Skip to content

Commit cfe472f

Browse files
feat: support --config in sg new
BREAKING CHANGE: --base-dir is removed and superseded by --config
1 parent c6cc145 commit cfe472f

File tree

2 files changed

+43
-37
lines changed

2 files changed

+43
-37
lines changed

crates/cli/src/config.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,8 @@ impl ProjectConfig {
6666
pub fn by_config_path(config_path: Option<PathBuf>) -> Result<Option<Self>> {
6767
Self::discover_project(config_path, None)
6868
}
69-
pub fn by_project_dir(project_dir: &Path) -> Result<Option<Self>> {
70-
Self::discover_project(None, Some(project_dir))
71-
}
7269
// return None if config file does not exist
73-
pub fn discover_project(
74-
config_path: Option<PathBuf>,
75-
base: Option<&Path>,
76-
) -> Result<Option<Self>> {
70+
fn discover_project(config_path: Option<PathBuf>, base: Option<&Path>) -> Result<Option<Self>> {
7771
let config_path =
7872
find_config_path_with_default(config_path, base).context(EC::ReadConfiguration)?;
7973
// NOTE: if config file does not exist, return None

crates/cli/src/new.rs

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use inquire::validator::ValueRequiredValidator;
88

99
use std::fmt::Display;
1010
use std::fs::{self, File};
11-
use std::path::PathBuf;
11+
use std::path::{Path, PathBuf};
1212

1313
#[derive(Parser)]
1414
pub struct NewArg {
@@ -29,25 +29,33 @@ pub struct NewArg {
2929
/// Please see the command description for the what arguments are required.
3030
#[arg(short, long, global = true)]
3131
yes: bool,
32-
/// Create new project/items in the folder specified by this argument.
33-
#[arg(short, long, global = true, default_value = ".")]
34-
base_dir: PathBuf,
32+
33+
/// Path to ast-grep root config, default is sgconfig.yml.
34+
#[clap(short, long, value_name = "CONFIG_FILE")]
35+
config: Option<PathBuf>,
36+
}
37+
38+
fn create_dir(project_dir: &Path, dir: &str) -> Result<PathBuf> {
39+
let path = project_dir.join(dir);
40+
fs::create_dir_all(&path)?;
41+
// create a .gitkeep file to keep the folder in git
42+
// https://github.com/ast-grep/ast-grep/issues/1273
43+
let gitkeep = path.join(".gitkeep");
44+
File::create(gitkeep)?;
45+
Ok(path)
3546
}
3647

3748
impl NewArg {
38-
fn ask_dir_and_create(&self, prompt: &str, default: &str) -> Result<PathBuf> {
49+
fn find_project_config(&self) -> Result<Option<ProjectConfig>> {
50+
ProjectConfig::by_config_path(self.config.clone())
51+
}
52+
fn ask_dir(&self, prompt: &str, default: &str) -> Result<String> {
3953
let dir = if self.yes {
4054
default.to_owned()
4155
} else {
4256
inquire::Text::new(prompt).with_default(default).prompt()?
4357
};
44-
let path = self.base_dir.join(dir);
45-
fs::create_dir_all(&path)?;
46-
// create a .gitkeep file to keep the folder in git
47-
// https://github.com/ast-grep/ast-grep/issues/1273
48-
let gitkeep = path.join(".gitkeep");
49-
File::create(gitkeep)?;
50-
Ok(path)
58+
Ok(dir)
5159
}
5260

5361
fn confirm(&self, prompt: &str) -> Result<bool> {
@@ -144,8 +152,8 @@ impl Display for Entity {
144152
}
145153

146154
pub fn run_create_new(mut arg: NewArg) -> Result<()> {
147-
let config_path = ProjectConfig::by_project_dir(&arg.base_dir)?;
148-
register_custom_language(config_path)?;
155+
let project_config = arg.find_project_config()?;
156+
register_custom_language(project_config)?;
149157
if let Some(entity) = arg.entity.take() {
150158
run_create_entity(entity, arg)
151159
} else {
@@ -155,12 +163,12 @@ pub fn run_create_new(mut arg: NewArg) -> Result<()> {
155163

156164
fn run_create_entity(entity: Entity, arg: NewArg) -> Result<()> {
157165
// check if we are under a project dir
158-
if let Some(found) = ProjectConfig::by_project_dir(&arg.base_dir)? {
166+
if let Some(found) = arg.find_project_config()? {
159167
return do_create_entity(entity, found, arg);
160168
}
161169
// check if we creating a project
162170
if entity == Entity::Project {
163-
create_new_project(arg)
171+
create_new_project(arg, std::env::current_dir()?.as_path())
164172
} else {
165173
// if not, return error
166174
Err(anyhow::anyhow!(EC::ProjectNotExist))
@@ -179,29 +187,33 @@ fn do_create_entity(entity: Entity, found: ProjectConfig, arg: NewArg) -> Result
179187

180188
fn ask_entity_type(arg: NewArg) -> Result<()> {
181189
// 1. check if we are under a sgconfig.yml
182-
if let Some(found) = ProjectConfig::by_project_dir(&arg.base_dir)? {
190+
if let Some(found) = arg.find_project_config()? {
183191
// 2. ask users what to create if yes
184192
let entity = arg.ask_entity_type()?;
185193
do_create_entity(entity, found, arg)
186194
} else {
187195
// 3. ask users to provide project info if no sgconfig found
188196
print!("No sgconfig.yml found. ");
189-
create_new_project(arg)
197+
let current_dir = std::env::current_dir()?;
198+
create_new_project(arg, &current_dir)
190199
}
191200
}
192201

193-
fn create_new_project(arg: NewArg) -> Result<()> {
202+
fn create_new_project(arg: NewArg, project_dir: &Path) -> Result<()> {
194203
println!("Creating a new ast-grep project...");
195-
let rule_dirs = arg.ask_dir_and_create("Where do you want to have your rules?", "rules")?;
204+
let ask_dir_and_create = |prompt: &str, default: &str| -> Result<PathBuf> {
205+
let dir = arg.ask_dir(prompt, default)?;
206+
create_dir(project_dir, &dir)
207+
};
208+
let rule_dirs = ask_dir_and_create("Where do you want to have your rules?", "rules")?;
196209
let test_dirs = if arg.confirm("Do you want to create rule tests?")? {
197-
let test_dirs =
198-
arg.ask_dir_and_create("Where do you want to have your tests?", "rule-tests")?;
210+
let test_dirs = ask_dir_and_create("Where do you want to have your tests?", "rule-tests")?;
199211
Some(TestConfig::from(test_dirs))
200212
} else {
201213
None
202214
};
203215
let utils = if arg.confirm("Do you want to create folder for utility rules?")? {
204-
let util_dirs = arg.ask_dir_and_create("Where do you want to have your utilities?", "utils")?;
216+
let util_dirs = ask_dir_and_create("Where do you want to have your utilities?", "utils")?;
205217
Some(util_dirs)
206218
} else {
207219
None
@@ -214,7 +226,7 @@ fn create_new_project(arg: NewArg) -> Result<()> {
214226
language_globs: None, // advanced feature, skip now
215227
language_injections: vec![], // advanced feature
216228
};
217-
let config_path = arg.base_dir.join("sgconfig.yml");
229+
let config_path = project_dir.join("sgconfig.yml");
218230
let f = File::create(config_path)?;
219231
serde_yaml::to_writer(f, &root_config)?;
220232
println!("Your new ast-grep project has been created!");
@@ -358,9 +370,9 @@ mod test {
358370
name: None,
359371
lang: None,
360372
yes: true,
361-
base_dir: tempdir.to_path_buf(),
373+
config: None,
362374
};
363-
run_create_new(arg)?;
375+
create_new_project(arg, tempdir)?;
364376
assert!(tempdir.join("sgconfig.yml").exists());
365377
Ok(())
366378
}
@@ -371,9 +383,9 @@ mod test {
371383
name: Some("test-rule".into()),
372384
lang: Some(SupportLang::Rust.into()),
373385
yes: true,
374-
base_dir: temp.to_path_buf(),
386+
config: Some(temp.join("sgconfig.yml")),
375387
};
376-
run_create_new(arg).unwrap();
388+
run_create_new(arg)?;
377389
assert!(temp.join("rules/test-rule.yml").exists());
378390
Ok(())
379391
}
@@ -384,9 +396,9 @@ mod test {
384396
name: Some("test-utils".into()),
385397
lang: Some(SupportLang::Rust.into()),
386398
yes: true,
387-
base_dir: temp.to_path_buf(),
399+
config: Some(temp.join("sgconfig.yml")),
388400
};
389-
run_create_new(arg).unwrap();
401+
run_create_new(arg)?;
390402
assert!(temp.join("utils/test-utils.yml").exists());
391403
Ok(())
392404
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy