summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2024-08-08 17:54:39 +0100
committerGitHub <noreply@github.com>2024-08-08 16:54:39 +0000
commitffe1bfd54c2065fe718872f67e19e8a863c0bf22 (patch)
treecf315d0c24fd72afd7957622008e7c1893d68ab8 /cli
parent3f692bed0a62de79895ea3373b9004fd6a542035 (diff)
feat: `deno init --serve` (#24897)
This commit adds "--serve" flag to "deno init" subcommand, that provides a template for quick starting a project using "deno serve". --------- Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
Diffstat (limited to 'cli')
-rw-r--r--cli/args/flags.rs38
-rw-r--r--cli/tools/init/mod.rs96
2 files changed, 127 insertions, 7 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 1053e8f3f..e28ce549b 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -214,6 +214,7 @@ impl FmtFlags {
pub struct InitFlags {
pub dir: Option<String>,
pub lib: bool,
+ pub serve: bool,
}
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -2121,6 +2122,14 @@ fn init_subcommand() -> Command {
.required(false)
.action(ArgAction::SetTrue),
)
+ .arg(
+ Arg::new("serve")
+ .long("serve")
+ .long_help("Generate an example project for `deno serve`")
+ .conflicts_with("lib")
+ .required(false)
+ .action(ArgAction::SetTrue),
+ )
})
}
@@ -4174,6 +4183,7 @@ 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"),
+ serve: matches.get_flag("serve"),
});
}
@@ -10026,7 +10036,8 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: None,
- lib: false
+ lib: false,
+ serve: false,
}),
..Flags::default()
}
@@ -10038,7 +10049,8 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: Some(String::from("foo")),
- lib: false
+ lib: false,
+ serve: false,
}),
..Flags::default()
}
@@ -10050,7 +10062,8 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: None,
- lib: false
+ lib: false,
+ serve: false,
}),
log_level: Some(Level::Error),
..Flags::default()
@@ -10063,7 +10076,21 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: None,
- lib: true
+ lib: true,
+ serve: false,
+ }),
+ ..Flags::default()
+ }
+ );
+
+ let r = flags_from_vec(svec!["deno", "init", "--serve"]);
+ assert_eq!(
+ r.unwrap(),
+ Flags {
+ subcommand: DenoSubcommand::Init(InitFlags {
+ dir: None,
+ lib: false,
+ serve: true,
}),
..Flags::default()
}
@@ -10075,7 +10102,8 @@ mod tests {
Flags {
subcommand: DenoSubcommand::Init(InitFlags {
dir: Some(String::from("foo")),
- lib: true
+ lib: true,
+ serve: false,
}),
..Flags::default()
}
diff --git a/cli/tools/init/mod.rs b/cli/tools/init/mod.rs
index c62d93289..6d442198e 100644
--- a/cli/tools/init/mod.rs
+++ b/cli/tools/init/mod.rs
@@ -20,7 +20,87 @@ pub fn init_project(init_flags: InitFlags) -> Result<(), AnyError> {
cwd
};
- if init_flags.lib {
+ if init_flags.serve {
+ create_file(
+ &dir,
+ "main.ts",
+ r#"import { type Route, route, serveDir } from "@std/http";
+
+const routes: Route[] = [
+ {
+ pattern: new URLPattern({ pathname: "/" }),
+ handler: () => new Response("Home page"),
+ },
+ {
+ pattern: new URLPattern({ pathname: "/users/:id" }),
+ handler: (_req, _info, params) => new Response(params?.pathname.groups.id),
+ },
+ {
+ pattern: new URLPattern({ pathname: "/static/*" }),
+ handler: (req) => serveDir(req, { urlRoot: "./" }),
+ },
+];
+
+function defaultHandler(_req: Request) {
+ return new Response("Not found", { status: 404 });
+}
+
+const handler = route(routes, defaultHandler);
+
+export default {
+ fetch(req) {
+ return handler(req);
+ },
+} satisfies Deno.ServeDefaultExport;
+
+"#,
+ )?;
+ create_file(
+ &dir,
+ "main_test.ts",
+ r#"import { assertEquals } from "@std/assert";
+import server from "./main.ts";
+
+Deno.test(async function serverFetch() {
+ const req = new Request("https://deno.land");
+ const res = await server.fetch(req);
+ assertEquals(await res.text(), "Home page");
+});
+
+Deno.test(async function serverFetchNotFound() {
+ const req = new Request("https://deno.land/404");
+ const res = await server.fetch(req);
+ assertEquals(res.status, 404);
+});
+
+Deno.test(async function serverFetchUsers() {
+ const req = new Request("https://deno.land/users/123");
+ const res = await server.fetch(req);
+ assertEquals(await res.text(), "123");
+});
+
+Deno.test(async function serverFetchStatic() {
+ const req = new Request("https://deno.land/static/main.ts");
+ const res = await server.fetch(req);
+ assertEquals(res.headers.get("content-type"), "text/plain;charset=UTF-8");
+});
+"#,
+ )?;
+
+ create_json_file(
+ &dir,
+ "deno.json",
+ &json!({
+ "tasks": {
+ "dev": "deno serve --watch -R main.ts",
+ },
+ "imports": {
+ "@std/assert": "jsr:@std/assert@1",
+ "@std/http": "jsr:@std/http@1",
+ }
+ }),
+ )?;
+ } else if init_flags.lib {
// Extract the directory name to use as the project name
let project_name = dir
.file_name()
@@ -111,7 +191,19 @@ Deno.test(function addTest() {
info!(" cd {}", dir);
info!("");
}
- if init_flags.lib {
+ if init_flags.serve {
+ info!(" {}", colors::gray("# Run the server"));
+ info!(" deno serve -R main.ts");
+ info!("");
+ info!(
+ " {}",
+ colors::gray("# Run the server and watch for file changes")
+ );
+ info!(" deno task dev");
+ info!("");
+ info!(" {}", colors::gray("# Run the tests"));
+ info!(" deno -R test");
+ } else if init_flags.lib {
info!(" {}", colors::gray("# Run the tests"));
info!(" deno test");
info!("");