Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): deno init --lib #22499

Merged
merged 11 commits into from
Jul 10, 2024
54 changes: 47 additions & 7 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ impl FmtFlags {
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InitFlags {
pub dir: Option<String>,
pub lib: bool,
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -1740,11 +1741,18 @@ fn init_subcommand() -> Command {
Command::new("init")
.about("Initialize a new project")
.defer(|cmd| {
cmd.arg(
Arg::new("dir")
.required(false)
.value_hint(ValueHint::DirPath),
)
cmd
.arg(
Arg::new("dir")
.required(false)
.value_hint(ValueHint::DirPath),
)
.arg(
Arg::new("lib")
.long("lib")
.required(false)
.action(ArgAction::SetTrue),
)
})
}

Expand Down Expand Up @@ -3497,6 +3505,7 @@ fn fmt_parse(flags: &mut Flags, matches: &mut ArgMatches) {
fn init_parse(flags: &mut Flags, matches: &mut ArgMatches) {
flags.subcommand = DenoSubcommand::Init(InitFlags {
dir: matches.remove_one::<String>("dir"),
lib: matches.get_flag("lib"),
});
}

Expand Down Expand Up @@ -8455,7 +8464,10 @@ mod tests {
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Init(InitFlags { dir: None }),
subcommand: DenoSubcommand::Init(InitFlags {
dir: None,
lib: false
}),
..Flags::default()
}
);
Expand All @@ -8466,6 +8478,7 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: Some(String::from("foo")),
lib: false
}),
..Flags::default()
}
Expand All @@ -8475,11 +8488,38 @@ mod tests {
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Init(InitFlags { dir: None }),
subcommand: DenoSubcommand::Init(InitFlags {
dir: None,
lib: false
}),
log_level: Some(Level::Error),
..Flags::default()
}
);

let r = flags_from_vec(svec!["deno", "init", "--lib"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: None,
lib: true
}),
..Flags::default()
}
);

let r = flags_from_vec(svec!["deno", "init", "foo", "--lib"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: Some(String::from("foo")),
lib: true
}),
..Flags::default()
}
);
}

#[test]
Expand Down
16 changes: 15 additions & 1 deletion cli/tools/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,21 @@ pub async fn init_project(init_flags: InitFlags) -> Result<(), AnyError> {
let main_test_ts = include_str!("./templates/main_test.ts")
.replace("{CURRENT_STD_URL}", deno_std::CURRENT_STD_URL_STR);
create_file(&dir, "main_test.ts", &main_test_ts)?;
create_file(&dir, "deno.json", include_str!("./templates/deno.json"))?;

if init_flags.lib {
// Extract the directory name to use as the project name
let project_name = dir
.file_name()
.unwrap_or_else(|| dir.as_os_str())
Comment on lines +25 to +27
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be problematic - I don't think all directories are valid JSR specifiers, but maybe fine for the first pass and could be improved in the future.

.to_str()
.unwrap();

let template_content = include_str!("./templates/deno_lib.json");
let new_content = template_content.replace("{{name}}", project_name);
create_file(&dir, "deno.json", &new_content)?;
} else {
create_file(&dir, "deno.json", include_str!("./templates/deno.json"))?;
}

info!("✅ {}", colors::green("Project initialized"));
info!("");
Expand Down
8 changes: 8 additions & 0 deletions cli/tools/init/templates/deno_lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "{{name}}",
"version": "1.0.0",
"exports": {},
"tasks": {
"dev": "deno run --watch main.ts"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Why does a library default to having a main.ts? That sounds more like an application thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, probably better to do lib.ts instead

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe even better, mod.ts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this to mod.ts, which is the default entrypoint name for libraries in Deno. I also changed the subcommand to deno test, rather than deno run, as it's a for a library, rather than a script. Happy to change, if there are better suggestions.

}
}