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: deno vendor #13670

Merged
merged 38 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
fadf48a
Committing for backup purposes.
dsherret Feb 3, 2022
8532d19
Add copyrights.
dsherret Feb 5, 2022
9699a5c
Merge branch 'main' into deno_vendor
dsherret Feb 5, 2022
e0db996
Starting to add text changes.
dsherret Feb 7, 2022
383a962
Somewhat working.
dsherret Feb 7, 2022
85ab7ed
Slight fix.
dsherret Feb 7, 2022
31c4996
Better import map and leave output files the same more
dsherret Feb 8, 2022
e5fd1f4
Merge remote-tracking branch 'upstream/main' into deno_vendor
dsherret Feb 8, 2022
591042d
Small fixes. Need to resolve the todos... might be a bit of work.
dsherret Feb 8, 2022
5e6022a
Lots of bugs, but slowly getting there. Will need deno_graph improvem…
dsherret Feb 10, 2022
52c7818
- Inspect the source code itself to get the specifier text
dsherret Feb 10, 2022
6a54b35
Basic testing infrastructure.
dsherret Feb 10, 2022
677f492
Fix more issues. It seems to be working decently now.
dsherret Feb 10, 2022
8317c87
Maintain casing of extensions when able
dsherret Feb 11, 2022
855dbe4
Merge branch 'main' into deno_vendor
dsherret Feb 11, 2022
cf746ae
More tests.
dsherret Feb 11, 2022
a981b53
- derived import map and functionality test
dsherret Feb 11, 2022
bd77405
Merge remote-tracking branch 'upstream/main' into deno_vendor
dsherret Feb 14, 2022
2974cd1
Support x-typescript-types headers
dsherret Feb 14, 2022
fe1413f
Fix and add tests for default export detection.
dsherret Feb 14, 2022
36bc916
Add flags test.
dsherret Feb 14, 2022
9762a40
More integration tests and fixes.
dsherret Feb 14, 2022
b77ddb5
Add sub command description
dsherret Feb 14, 2022
8c16515
Add test for an existing import map.
dsherret Feb 14, 2022
4286ffd
Tests for dynamic imports
dsherret Feb 14, 2022
8d10e4d
Add support for more flags.
dsherret Feb 14, 2022
72fb9b4
Updates based on self review.
dsherret Feb 15, 2022
c8a8aa5
Fix fs_util test
dsherret Feb 15, 2022
3d097a5
Maybe fix mac.
dsherret Feb 15, 2022
f04366c
Fix mac issue on a mac
dsherret Feb 15, 2022
4056996
Probably fix on all operating systems.......
dsherret Feb 15, 2022
d147900
Referencing a different origin should add entry to "imports"
dsherret Feb 16, 2022
8b10b6a
Add message on success.
dsherret Feb 16, 2022
b3b98cc
Merge branch 'main' into deno_vendor
dsherret Feb 16, 2022
326f399
Fix clippy issues on main.
dsherret Feb 16, 2022
dd8d561
Update for new deno_graph changes.
dsherret Feb 16, 2022
bfa2ee9
Add context to canonicalize.
dsherret Feb 16, 2022
90bce37
Use first non-remote entry point in output message.
dsherret Feb 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ encoding_rs = "=0.8.29"
env_logger = "=0.8.4"
fancy-regex = "=0.7.1"
http = "=0.2.4"
import_map = "=0.8.0"
import_map = "=0.9.0"
jsonc-parser = { version = "=0.19.0", features = ["serde"] }
libc = "=0.2.106"
log = { version = "=0.4.14", features = ["serde"] }
Expand Down
138 changes: 133 additions & 5 deletions cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ pub struct UpgradeFlags {
pub ca_file: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct VendorFlags {
pub specifiers: Vec<String>,
pub output_path: Option<PathBuf>,
pub force: bool,
}

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum DenoSubcommand {
Bundle(BundleFlags),
Expand All @@ -181,6 +188,7 @@ pub enum DenoSubcommand {
Test(TestFlags),
Types,
Upgrade(UpgradeFlags),
Vendor(VendorFlags),
}

impl Default for DenoSubcommand {
Expand Down Expand Up @@ -480,6 +488,7 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::Result<Flags> {
Some(("lint", m)) => lint_parse(&mut flags, m),
Some(("compile", m)) => compile_parse(&mut flags, m),
Some(("lsp", m)) => lsp_parse(&mut flags, m),
Some(("vendor", m)) => vendor_parse(&mut flags, m),
_ => handle_repl_flags(&mut flags, ReplFlags { eval: None }),
}

Expand Down Expand Up @@ -551,6 +560,7 @@ If the flag is set, restrict these messages to errors.",
.subcommand(test_subcommand())
.subcommand(types_subcommand())
.subcommand(upgrade_subcommand())
.subcommand(vendor_subcommand())
.long_about(DENO_HELP)
.after_help(ENV_VARIABLES_HELP)
}
Expand Down Expand Up @@ -1400,6 +1410,52 @@ update to a different location, use the --output flag
.arg(ca_file_arg())
}

fn vendor_subcommand<'a>() -> App<'a> {
App::new("vendor")
.about("Vendor remote modules into a local directory")
.long_about(
"Vendor remote modules into a local directory.

Analyzes the provided modules and their dependencies, downloads remote
modules to the output directory, and produces an import map that maps
remote specifiers to the downloaded files.

deno vendor main.ts
deno run --import-map vendor/import_map.json main.ts

Remote modules and multiple modules may also be specified:

deno vendor main.ts test.deps.ts https://deno.land/std/path/mod.ts",
)
.arg(
Arg::new("specifiers")
.takes_value(true)
.multiple_values(true)
.multiple_occurrences(true)
.required(true),
)
.arg(
Arg::new("output")
.long("output")
.help("The directory to output the vendored modules to")
.takes_value(true),
)
.arg(
Arg::new("force")
.long("force")
.short('f')
.help(
"Forcefully overwrite conflicting files in existing output directory",
)
.takes_value(false),
)
.arg(config_arg())
.arg(import_map_arg())
.arg(lock_arg())
.arg(reload_arg())
.arg(ca_file_arg())
}

fn compile_args(app: App) -> App {
app
.arg(import_map_arg())
Expand Down Expand Up @@ -2222,6 +2278,23 @@ fn upgrade_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
});
}

fn vendor_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
ca_file_arg_parse(flags, matches);
config_arg_parse(flags, matches);
import_map_arg_parse(flags, matches);
lock_arg_parse(flags, matches);
reload_arg_parse(flags, matches);

flags.subcommand = DenoSubcommand::Vendor(VendorFlags {
specifiers: matches
.values_of("specifiers")
.map(|p| p.map(ToString::to_string).collect())
.unwrap_or_default(),
output_path: matches.value_of("output").map(PathBuf::from),
force: matches.is_present("force"),
});
}

fn compile_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
import_map_arg_parse(flags, matches);
no_remote_arg_parse(flags, matches);
Expand Down Expand Up @@ -2428,13 +2501,17 @@ fn no_check_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
}

fn lock_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
lock_arg_parse(flags, matches);
if matches.is_present("lock-write") {
flags.lock_write = true;
}
}

fn lock_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
if matches.is_present("lock") {
let lockfile = matches.value_of("lock").unwrap();
flags.lock = Some(PathBuf::from(lockfile));
}
if matches.is_present("lock-write") {
flags.lock_write = true;
}
}

fn config_arg_parse(flags: &mut Flags, matches: &ArgMatches) {
Expand Down Expand Up @@ -2497,8 +2574,8 @@ mod tests {

/// Creates vector of strings, Vec<String>
macro_rules! svec {
($($x:expr),*) => (vec![$($x.to_string()),*]);
}
($($x:expr),* $(,)?) => (vec![$($x.to_string()),*]);
Copy link
Member Author

Choose a reason for hiding this comment

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

Trailing comma support.

}

#[test]
fn global_flags() {
Expand Down Expand Up @@ -4855,4 +4932,55 @@ mod tests {
.contains("error: The following required arguments were not provided:"));
assert!(&error_message.contains("--watch=<FILES>..."));
}

#[test]
fn vendor_minimal() {
let r = flags_from_vec(svec!["deno", "vendor", "mod.ts",]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Vendor(VendorFlags {
specifiers: svec!["mod.ts"],
force: false,
output_path: None,
}),
..Flags::default()
}
);
}

#[test]
fn vendor_all() {
let r = flags_from_vec(svec![
"deno",
"vendor",
"--config",
"deno.json",
"--import-map",
"import_map.json",
"--lock",
"lock.json",
"--force",
"--output",
"out_dir",
"--reload",
"mod.ts",
"deps.test.ts",
]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Vendor(VendorFlags {
specifiers: svec!["mod.ts", "deps.test.ts"],
force: true,
output_path: Some(PathBuf::from("out_dir")),
}),
config_path: Some("deno.json".to_string()),
import_map_path: Some("import_map.json".to_string()),
lock: Some(PathBuf::from("lock.json")),
reload: true,
..Flags::default()
}
);
}
}
66 changes: 66 additions & 0 deletions cli/fs_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,32 @@ pub fn path_has_trailing_slash(path: &Path) -> bool {
}
}

/// Gets a path with the specified file stem suffix.
pub fn path_with_stem_suffix(path: &Path, suffix: &str) -> PathBuf {
if let Some(file_name) = path.file_name().map(|f| f.to_string_lossy()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

to_string_lossy 🤷‍♂️

if let Some(file_stem) = path.file_stem().map(|f| f.to_string_lossy()) {
if let Some(ext) = path.extension().map(|f| f.to_string_lossy()) {
return if file_stem.to_lowercase().ends_with(".d") {
path.with_file_name(format!(
"{}_{}.{}.{}",
&file_stem[..file_stem.len() - ".d".len()],
suffix,
// maintain casing
&file_stem[file_stem.len() - "d".len()..],
ext
))
} else {
path.with_file_name(format!("{}{}.{}", file_stem, suffix, ext))
};
}
}

path.with_file_name(format!("{}{}", file_name, suffix))
} else {
path.with_file_name(suffix)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -730,4 +756,44 @@ mod tests {
assert_eq!(result, expected);
}
}

#[test]
fn test_path_with_stem_suffix() {
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/"), "_2"),
PathBuf::from("/_2")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test"), "_2"),
PathBuf::from("/test_2")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test.txt"), "_2"),
PathBuf::from("/test_2.txt")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test/subdir"), "_2"),
PathBuf::from("/test/subdir_2")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test/subdir.other.txt"), "_2"),
PathBuf::from("/test/subdir.other_2.txt")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test.d.ts"), "_2"),
PathBuf::from("/test_2.d.ts")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test.D.TS"), "_2"),
PathBuf::from("/test_2.D.TS")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test.d.mts"), "_2"),
PathBuf::from("/test_2.d.mts")
);
assert_eq!(
path_with_stem_suffix(&PathBuf::from("/test.d.cts"), "_2"),
PathBuf::from("/test_2.d.cts")
);
}
}
13 changes: 13 additions & 0 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use crate::flags::RunFlags;
use crate::flags::TestFlags;
use crate::flags::UninstallFlags;
use crate::flags::UpgradeFlags;
use crate::flags::VendorFlags;
use crate::fmt_errors::PrettyJsError;
use crate::graph_util::graph_lock_or_exit;
use crate::graph_util::graph_valid;
Expand Down Expand Up @@ -1298,6 +1299,15 @@ async fn upgrade_command(
Ok(0)
}

async fn vendor_command(
flags: Flags,
vendor_flags: VendorFlags,
) -> Result<i32, AnyError> {
let ps = ProcState::build(Arc::new(flags)).await?;
tools::vendor::vendor(ps, vendor_flags).await?;
Ok(0)
}

fn init_v8_flags(v8_flags: &[String]) {
let v8_flags_includes_help = v8_flags
.iter()
Expand Down Expand Up @@ -1376,6 +1386,9 @@ fn get_subcommand(
DenoSubcommand::Upgrade(upgrade_flags) => {
upgrade_command(flags, upgrade_flags).boxed_local()
}
DenoSubcommand::Vendor(vendor_flags) => {
vendor_command(flags, vendor_flags).boxed_local()
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions cli/tests/integration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ mod run;
mod test;
#[path = "upgrade_tests.rs"]
mod upgrade;
#[path = "vendor_tests.rs"]
mod vendor;
#[path = "watcher_tests.rs"]
mod watcher;
#[path = "worker_tests.rs"]
Expand Down
Loading