mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat(cli): deno init --lib
(#22499)
Closes #22287 Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com> Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
parent
9776a13e33
commit
ff5163af05
9 changed files with 233 additions and 69 deletions
|
@ -205,6 +205,7 @@ impl FmtFlags {
|
|||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct InitFlags {
|
||||
pub dir: Option<String>,
|
||||
pub lib: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -2052,11 +2053,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),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -4033,6 +4041,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"),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -9753,7 +9762,10 @@ mod tests {
|
|||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Init(InitFlags { dir: None }),
|
||||
subcommand: DenoSubcommand::Init(InitFlags {
|
||||
dir: None,
|
||||
lib: false
|
||||
}),
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
|
@ -9764,6 +9776,7 @@ mod tests {
|
|||
Flags {
|
||||
subcommand: DenoSubcommand::Init(InitFlags {
|
||||
dir: Some(String::from("foo")),
|
||||
lib: false
|
||||
}),
|
||||
..Flags::default()
|
||||
}
|
||||
|
@ -9773,11 +9786,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]
|
||||
|
|
|
@ -4,10 +4,145 @@ use crate::args::InitFlags;
|
|||
use crate::colors;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json::json;
|
||||
use log::info;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn init_project(init_flags: InitFlags) -> Result<(), AnyError> {
|
||||
let cwd =
|
||||
std::env::current_dir().context("Can't read current working directory.")?;
|
||||
let dir = if let Some(dir) = &init_flags.dir {
|
||||
let dir = cwd.join(dir);
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
dir
|
||||
} else {
|
||||
cwd
|
||||
};
|
||||
|
||||
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())
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
create_file(
|
||||
&dir,
|
||||
"mod.ts",
|
||||
r#"export function add(a: number, b: number): number {
|
||||
return a + b;
|
||||
}
|
||||
"#,
|
||||
)?;
|
||||
create_file(
|
||||
&dir,
|
||||
"mod_test.ts",
|
||||
r#"import { assertEquals } from "jsr:@std/assert";
|
||||
import { add } from "./mod.ts";
|
||||
|
||||
Deno.test(function addTest() {
|
||||
assertEquals(add(2, 3), 5);
|
||||
});
|
||||
"#,
|
||||
)?;
|
||||
|
||||
create_json_file(
|
||||
&dir,
|
||||
"deno.json",
|
||||
&json!({
|
||||
"name": project_name,
|
||||
"version": "1.0.0",
|
||||
"exports": "./mod.ts",
|
||||
"tasks": {
|
||||
"dev": "deno test --watch mod.ts"
|
||||
}
|
||||
}),
|
||||
)?;
|
||||
} else {
|
||||
create_file(
|
||||
&dir,
|
||||
"main.ts",
|
||||
r#"export function add(a: number, b: number): number {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// Learn more at https://deno.land/manual/examples/module_metadata#concepts
|
||||
if (import.meta.main) {
|
||||
console.log("Add 2 + 3 =", add(2, 3));
|
||||
}
|
||||
"#,
|
||||
)?;
|
||||
create_file(
|
||||
&dir,
|
||||
"main_test.ts",
|
||||
r#"import { assertEquals } from "jsr:@std/assert";
|
||||
import { add } from "./main.ts";
|
||||
|
||||
Deno.test(function addTest() {
|
||||
assertEquals(add(2, 3), 5);
|
||||
});
|
||||
"#,
|
||||
)?;
|
||||
|
||||
create_json_file(
|
||||
&dir,
|
||||
"deno.json",
|
||||
&json!({
|
||||
"tasks": {
|
||||
"dev": "deno run --watch main.ts"
|
||||
}
|
||||
}),
|
||||
)?;
|
||||
}
|
||||
|
||||
info!("✅ {}", colors::green("Project initialized"));
|
||||
info!("");
|
||||
info!("{}", colors::gray("Run these commands to get started"));
|
||||
info!("");
|
||||
if let Some(dir) = init_flags.dir {
|
||||
info!(" cd {}", dir);
|
||||
info!("");
|
||||
}
|
||||
if init_flags.lib {
|
||||
info!(" {}", colors::gray("# Run the tests"));
|
||||
info!(" deno test");
|
||||
info!("");
|
||||
info!(
|
||||
" {}",
|
||||
colors::gray("# Run the tests and watch for file changes")
|
||||
);
|
||||
info!(" deno task dev");
|
||||
info!("");
|
||||
info!(" {}", colors::gray("# Publish to JSR (dry run)"));
|
||||
info!(" deno publish --dry-run");
|
||||
} else {
|
||||
info!(" {}", colors::gray("# Run the program"));
|
||||
info!(" deno run main.ts");
|
||||
info!("");
|
||||
info!(
|
||||
" {}",
|
||||
colors::gray("# Run the program and watch for file changes")
|
||||
);
|
||||
info!(" deno task dev");
|
||||
info!("");
|
||||
info!(" {}", colors::gray("# Run the tests"));
|
||||
info!(" deno test");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_json_file(
|
||||
dir: &Path,
|
||||
filename: &str,
|
||||
value: &deno_core::serde_json::Value,
|
||||
) -> Result<(), AnyError> {
|
||||
let mut text = deno_core::serde_json::to_string_pretty(value)?;
|
||||
text.push('\n');
|
||||
create_file(dir, filename, &text)
|
||||
}
|
||||
|
||||
fn create_file(
|
||||
dir: &Path,
|
||||
filename: &str,
|
||||
|
@ -30,46 +165,3 @@ fn create_file(
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_project(init_flags: InitFlags) -> Result<(), AnyError> {
|
||||
let cwd =
|
||||
std::env::current_dir().context("Can't read current working directory.")?;
|
||||
let dir = if let Some(dir) = &init_flags.dir {
|
||||
let dir = cwd.join(dir);
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
dir
|
||||
} else {
|
||||
cwd
|
||||
};
|
||||
|
||||
let main_ts = include_str!("./templates/main.ts");
|
||||
create_file(&dir, "main.ts", main_ts)?;
|
||||
|
||||
create_file(
|
||||
&dir,
|
||||
"main_test.ts",
|
||||
include_str!("./templates/main_test.ts"),
|
||||
)?;
|
||||
create_file(&dir, "deno.json", include_str!("./templates/deno.json"))?;
|
||||
|
||||
info!("✅ {}", colors::green("Project initialized"));
|
||||
info!("");
|
||||
info!("{}", colors::gray("Run these commands to get started"));
|
||||
info!("");
|
||||
if let Some(dir) = init_flags.dir {
|
||||
info!(" cd {}", dir);
|
||||
info!("");
|
||||
}
|
||||
info!(" {}", colors::gray("# Run the program"));
|
||||
info!(" deno run main.ts");
|
||||
info!("");
|
||||
info!(
|
||||
" {}",
|
||||
colors::gray("# Run the program and watch for file changes")
|
||||
);
|
||||
info!(" deno task dev");
|
||||
info!("");
|
||||
info!(" {}", colors::gray("# Run the tests"));
|
||||
info!(" deno test");
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"tasks": {
|
||||
"dev": "deno run --watch main.ts"
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
export function add(a: number, b: number): number {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// Learn more at https://deno.land/manual/examples/module_metadata#concepts
|
||||
if (import.meta.main) {
|
||||
console.log("Add 2 + 3 =", add(2, 3));
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import { assertEquals } from "jsr:@std/assert";
|
||||
import { add } from "./main.ts";
|
||||
|
||||
Deno.test(function addTest() {
|
||||
assertEquals(add(2, 3), 5);
|
||||
});
|
16
tests/specs/init/lib/__test__.jsonc
Normal file
16
tests/specs/init/lib/__test__.jsonc
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"steps": [{
|
||||
"args": "init --lib project",
|
||||
"output": "init.out"
|
||||
}, {
|
||||
"cwd": "project",
|
||||
"args": "test",
|
||||
"output": "test.out"
|
||||
}, {
|
||||
"cwd": "project",
|
||||
"args": "publish --dry-run",
|
||||
"output": "dry_publish.out",
|
||||
"exitCode": 1
|
||||
}]
|
||||
}
|
7
tests/specs/init/lib/dry_publish.out
Normal file
7
tests/specs/init/lib/dry_publish.out
Normal file
|
@ -0,0 +1,7 @@
|
|||
Check file:///[WILDLINE]/mod.ts
|
||||
Checking for slow types in the public API...
|
||||
Check file:///[WILDLINE]/mod.ts
|
||||
error: Failed preparing 'project'.
|
||||
|
||||
Caused by:
|
||||
Invalid package name, use '@<scope_name>/<package_name> format
|
14
tests/specs/init/lib/init.out
Normal file
14
tests/specs/init/lib/init.out
Normal file
|
@ -0,0 +1,14 @@
|
|||
✅ Project initialized
|
||||
|
||||
Run these commands to get started
|
||||
|
||||
cd project
|
||||
|
||||
# Run the tests
|
||||
deno test
|
||||
|
||||
# Run the tests and watch for file changes
|
||||
deno task dev
|
||||
|
||||
# Publish to JSR (dry run)
|
||||
deno publish --dry-run
|
14
tests/specs/init/lib/test.out
Normal file
14
tests/specs/init/lib/test.out
Normal file
|
@ -0,0 +1,14 @@
|
|||
Download http://127.0.0.1:4250/@std/assert/meta.json
|
||||
Download http://127.0.0.1:4250/@std/assert/0.220.1_meta.json
|
||||
[UNORDERED_START]
|
||||
Download http://127.0.0.1:4250/@std/assert/0.220.1/mod.ts
|
||||
Download http://127.0.0.1:4250/@std/assert/0.220.1/assert_equals.ts
|
||||
Download http://127.0.0.1:4250/@std/assert/0.220.1/assert.ts
|
||||
Download http://127.0.0.1:4250/@std/assert/0.220.1/fail.ts
|
||||
[UNORDERED_END]
|
||||
Check file:///[WILDLINE]/mod_test.ts
|
||||
running 1 test from ./mod_test.ts
|
||||
addTest ... ok ([WILDLINE])
|
||||
|
||||
ok | 1 passed | 0 failed ([WILDLINE])
|
||||
|
Loading…
Reference in a new issue