Skip to content

Commit 83c4083

Browse files
committed
Local file paths in meta are recorded using relative paths.
1 parent 62b2d22 commit 83c4083

File tree

4 files changed

+147
-17
lines changed

4 files changed

+147
-17
lines changed

devtools/text-optimizer/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#[derive(Debug)]
22
pub enum MyError {
3+
CommitId,
34
Io(std::io::Error),
45
Serde(serde_yaml::Error),
6+
PathError,
57
}
68

79
impl From<std::io::Error> for MyError {

devtools/text-optimizer/src/extractors/mod.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub mod std_output_extractor;
44
pub mod thiserror_extractor;
55

66
use crate::{
7-
types::TextInfo, yaml_processor::save_yaml, CLAP_TEXT_FILE, LOG_TEXT_FILE,
7+
error::MyError, types::TextInfo, yaml_processor::save_yaml, CLAP_TEXT_FILE, LOG_TEXT_FILE,
88
STD_OUTPUT_TEXT_FILE, THISERROR_TEXT_FILE,
99
};
1010

@@ -27,14 +27,11 @@ pub trait Extractor {
2727
fn text_list(&self) -> Vec<TextInfo>;
2828
fn scanning_file_path(&self) -> &PathBuf;
2929
fn save_file_path(&self) -> &PathBuf;
30-
fn save_as_file(&self) {
31-
save_yaml(self.save_file_path(), &self.text_list()).expect("save yaml");
32-
}
3330
fn visit_file(&mut self, node: &File);
3431
}
3532

36-
pub fn extract(project_root: PathBuf, output_dir: &PathBuf) {
37-
// extractors
33+
pub fn extract(root_cargo_config_path: PathBuf, commit_id: &str, output_dir: &PathBuf) {
34+
// init all extractors
3835
let mut clap_extractor = ClapExtractor::new(output_dir.join(CLAP_TEXT_FILE));
3936
let mut log_extractor = LogExtractor::new(output_dir.join(LOG_TEXT_FILE));
4037
let mut std_output_extractor = StdOutputExtractor::new(output_dir.join(STD_OUTPUT_TEXT_FILE));
@@ -48,21 +45,24 @@ pub fn extract(project_root: PathBuf, output_dir: &PathBuf) {
4845
];
4946

5047
let project_metadata = MetadataCommand::new()
51-
.manifest_path(project_root)
48+
.manifest_path(&root_cargo_config_path)
5249
.exec()
5350
.expect("Failed to get current directory");
5451

5552
for package in project_metadata.workspace_packages() {
5653
log::info!("Scanning Crate: {}", package.name);
5754

58-
let crate_src_path = Path::new(&package.manifest_path)
55+
let crate_src_path = PathBuf::from(&package.manifest_path)
5956
.parent()
6057
.expect("workspace member crate path")
6158
.join("src");
59+
let crate_src_path =
60+
to_relative_path(&crate_src_path, &root_cargo_config_path).expect("to_relative_path");
61+
6262
process_rs_files_in_src(&crate_src_path, &mut extractors);
6363
}
6464

65-
save_extractors(output_dir, &extractors);
65+
save_text_info_files(output_dir, &extractors, commit_id);
6666
}
6767

6868
pub fn process_rs_files_in_src(dir_path: &Path, extractors: &mut [&mut dyn Extractor]) {
@@ -103,14 +103,34 @@ pub fn extract_contents_in_brackets(lit: String) -> Option<String> {
103103
None
104104
}
105105

106-
fn save_extractors(output_dir: &PathBuf, extractors: &[&mut dyn Extractor]) {
106+
fn save_text_info_files(output_dir: &PathBuf, extractors: &[&mut dyn Extractor], commit_id: &str) {
107107
fs::create_dir_all(output_dir).expect("create dir all");
108108
println!();
109109

110110
for extractor in extractors {
111-
extractor.save_as_file();
111+
save_yaml(
112+
extractor.save_file_path(),
113+
&extractor.text_list(),
114+
commit_id,
115+
)
116+
.expect("save yaml");
117+
112118
let file_name = extractor.save_file_path().file_name().unwrap();
113119
let text_len = extractor.text_list().len();
114120
println!("{:?}: {:?}", file_name, text_len);
115121
}
116122
}
123+
124+
fn to_relative_path(
125+
absolut_path: &Path,
126+
root_cargo_config_path: &Path,
127+
) -> Result<PathBuf, MyError> {
128+
let cargo_config_path_abs = root_cargo_config_path.canonicalize()?;
129+
let project_root_path = cargo_config_path_abs.parent().ok_or(MyError::PathError)?;
130+
let relative_path = absolut_path
131+
.strip_prefix(project_root_path)
132+
.map_err(|_| MyError::PathError)?
133+
.to_str()
134+
.ok_or(MyError::PathError)?;
135+
Ok(Path::new("../..").join(relative_path))
136+
}

devtools/text-optimizer/src/main.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ mod yaml_processor;
66

77
use backfill::backfill;
88
use clap::{Parser, Subcommand};
9+
use error::MyError;
910
use extractors::extract;
1011
use std::path::PathBuf;
12+
use std::process::Command;
13+
use std::result::Result;
1114

12-
pub const PROJECT_ROOT: &str = "../../Cargo.toml";
15+
pub const GITHUB_REPO: &str = "https://github.com/nervosnetwork/ckb/tree";
16+
pub const PROJECT_ROOT_CARGO_CONFIG_PATH: &str = "../../Cargo.toml";
1317
pub const LOG_TEXT_FILE: &str = "log_text_list.yml";
1418
pub const CLAP_TEXT_FILE: &str = "clap_text_list.yml";
1519
pub const STD_OUTPUT_TEXT_FILE: &str = "std_output_text_list.yml";
@@ -26,6 +30,10 @@ struct Cli {
2630
enum Commands {
2731
/// extracting text
2832
Extract {
33+
/// specify a github commit id as the rev for generating the source link
34+
#[arg(short, long)]
35+
commit_id: String,
36+
2937
/// specifies a directory path for .yml text files output
3038
#[arg(short, long, default_value = PathBuf::from("./").into_os_string())]
3139
output_dir: PathBuf,
@@ -46,12 +54,51 @@ fn main() {
4654
);
4755

4856
match &cli.command {
49-
Some(Commands::Extract { output_dir }) => {
50-
extract(PathBuf::from(PROJECT_ROOT), output_dir);
57+
Some(Commands::Extract {
58+
commit_id,
59+
output_dir,
60+
}) => {
61+
check_commit_id(commit_id).expect("check commit id");
62+
extract(
63+
PathBuf::from(PROJECT_ROOT_CARGO_CONFIG_PATH),
64+
commit_id,
65+
output_dir,
66+
);
5167
}
5268
Some(Commands::Backfill { input_dir }) => {
5369
backfill(input_dir);
5470
}
5571
None => {}
5672
}
5773
}
74+
75+
fn check_commit_id(commit_id: &str) -> Result<(), MyError> {
76+
let output = Command::new("git")
77+
.arg("rev-parse")
78+
.arg("HEAD")
79+
.output()
80+
.expect("Failed to execute git command");
81+
82+
if output.status.success() {
83+
let current_commit_id = String::from_utf8_lossy(&output.stdout);
84+
let current_commit_id: String = current_commit_id.trim().chars().take(7).collect();
85+
let commit_id: String = commit_id.trim().chars().take(7).collect();
86+
if current_commit_id == commit_id {
87+
log::info!(
88+
"Current commit ID matches the expected commit ID: {}",
89+
current_commit_id
90+
);
91+
Ok(())
92+
} else {
93+
log::warn!(
94+
"Current commit ID {} does not match the expected commit ID {}.",
95+
current_commit_id,
96+
commit_id
97+
);
98+
Err(MyError::CommitId)
99+
}
100+
} else {
101+
log::error!("Failed to retrieve the current commit ID");
102+
Err(MyError::CommitId)
103+
}
104+
}

devtools/text-optimizer/src/yaml_processor.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,76 @@
1-
use super::{error::MyError, types::TextInfo};
1+
use super::{
2+
error::MyError,
3+
types::{Category, Meta, TextInfo},
4+
GITHUB_REPO,
5+
};
6+
use serde::{Deserialize, Serialize};
27
use std::io::Read;
38
use std::io::Write;
49
use std::{fs::File, path::PathBuf};
510

6-
pub fn save_yaml(file: &PathBuf, data: &[TextInfo]) -> Result<(), MyError> {
11+
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Clone)]
12+
pub struct TextInfoSave {
13+
original: String,
14+
editable: String,
15+
metadata: Metadata,
16+
}
17+
18+
impl TextInfoSave {
19+
pub fn from_text_info(text_info: TextInfo, git_repo: &str, commit_id: &str) -> Self {
20+
// 使用 Metadata 的 from_meta 方法进行 Meta 到 Metadata 的转换
21+
let metadata = Metadata::from_meta(text_info.metadata(), git_repo, commit_id);
22+
23+
// 创建 TextInfoSave 结构体并返回
24+
TextInfoSave {
25+
original: text_info.original().to_owned(),
26+
editable: text_info.editable().to_owned(),
27+
metadata,
28+
}
29+
}
30+
}
31+
32+
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Clone)]
33+
pub struct Metadata {
34+
category: Category,
35+
file: PathBuf,
36+
code_line_link: Vec<String>,
37+
}
38+
39+
impl Metadata {
40+
// 定义从 Meta 到 Metadata 的转换方法
41+
pub fn from_meta(meta: &Meta, github_repo: &str, commit_id: &str) -> Self {
42+
// 创建 GitHub 代码行链接的前缀
43+
let github_link_prefix = format!("{}/{}/", github_repo, commit_id);
44+
45+
// 为每个代码行生成 GitHub 链接
46+
let code_line_link: Vec<String> = meta
47+
.start_lines()
48+
.iter()
49+
.map(|line| format!("{}#L{}", github_link_prefix, line))
50+
.collect();
51+
52+
Metadata {
53+
category: meta.category().to_owned(),
54+
file: meta.file().to_owned(),
55+
code_line_link,
56+
}
57+
}
58+
}
59+
60+
pub fn save_yaml(file: &PathBuf, data: &[TextInfo], commit_id: &str) -> Result<(), MyError> {
761
let mut file = File::create(file)?;
62+
63+
// Convert TextInfo to TextInfoSave
64+
let data_save: Vec<TextInfoSave> = data
65+
.iter()
66+
.map(|text_info| TextInfoSave::from_text_info(text_info.clone(), GITHUB_REPO, commit_id))
67+
.collect();
68+
869
file.write_fmt(format_args!(
970
"# Number of TextInfo items: {}\n\n",
1071
data.len()
1172
))?;
12-
serde_yaml::to_writer(file, data)?;
73+
serde_yaml::to_writer(file, &data_save)?;
1374
Ok(())
1475
}
1576

0 commit comments

Comments
 (0)