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

feat: deno vendor #13670

merged 38 commits into from Feb 16, 2022

Conversation

dsherret
Copy link
Member

@dsherret dsherret commented Feb 14, 2022

Not part of this first pass:

  • Warning when dynamic import is not statically analyzable (Ability to tell about any dynamic import specifiers deno_graph could not statically analyze deno_graph#138)
  • Special handling of file system layout to take into account Window's 260 character path limit. I had some code that handled this, but it wasn't very good and I thought of a better solution. I'll open an issue and do another PR at a later time.
  • Module specifiers with different text in the same module that resolve to the same module aren't handled (Support multiple ranges for an import in the graph deno_graph#132) -- Not a big deal because this is probably super rare
  • Directories with different casing resolve to the same folder on case insensistive file systems. I will have an upcomming PR with the 260 char limit that fixes this (just added this to dnt here)
  • The specified import map is not combined with the generated import map. It might be hard to do this correctly because the base of the import map changes when going into the vendor folder. Right now it's not a big deal for people to manually update the created import map after.

Differences with proposal:

  • Uses vendor folder instead of _vendor by default (seemed like in the meeting people wanted vendor instead?).
  • Output is not dependent on the existing state of the vendor folder.
    • Errors when the vendor folder exists and is non-empty. Allows using a --force flag to potentially overwrite the contents.
    • No --info flag
    • Specifying an import map via --import-map ... located within the output directory will error.
    • Why: Vendor is already a complex feature and I think basing the vendor output on the existing state of the vendor folder would be very difficult to do. It would also be hard to fix bugs because we'd need to know the previous state of the vendor folder. I think it also might be difficult for some users to understand.

Closes #13346

- Remove windows 260 limit code because it was terrible and I thought of a better solution that can come after the initial implementation.
- Remove other code that's no longer used
- fix directory paths in import map (bug in url crate)
- starting to add integration tests
@lucacasonato
Copy link
Member

Module specifiers with different text in the same module that resolve to the same module aren't handled (denoland/deno_graph#132) -- Not a big deal because this is probably super rare

I agree not that important for a first pass, but I don't agree it's super rare. Often you see in deps.ts files when people re-export both types and symbols:

export { foo } from "https://example.com/";
export type { foo } from "https://example.com/";

@@ -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.

@@ -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 🤷‍♂️

@@ -0,0 +1,331 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
Copy link
Member Author

Choose a reason for hiding this comment

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

Most of the tests aren't in this file. They'll be in cli/tools/vendor/build.rs. This is just the final integration tests.

.unwrap();
let output = deno.wait_with_output().unwrap();
assert_eq!(
String::from_utf8_lossy(&output.stderr).trim(),
Copy link
Member Author

Choose a reason for hiding this comment

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

Would be neat if we had a less verbose way of running the deno process and getting the output in the tests.

@dsherret
Copy link
Member Author

@lucacasonato it will just be an issue where the module specifiers differ and don't match the file name like:

export { foo } from "https://example.com/mod";
export type { foo } from "https://example.com/redirect_to_mod";

Removes displaying the output directory in the message because it's a pain to test obviously.
@lucacasonato lucacasonato added this to the 1.19.0 milestone Feb 15, 2022
@lucacasonato
Copy link
Member

It'd be nice to add a little message after deno vendor succeeds:

$ deno vendor main.ts
Vendored x modules into vendor/ directory.

To use vendored modules, specify the `--import-map` flag when invoking deno subcommands:
  deno run -A --import-map=./vendor/import_map.json main.ts

let mut text = from.make_relative(&to).unwrap();
if is_dir && !text.ends_with('/') && to.query().is_none() {
text.push('/');
}
Copy link
Member

Choose a reason for hiding this comment

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

Because of some of this nitty gritty heuristics, it would be good to have a little unit test for relative_path()

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a bit of a pain to test this struct because it involves creating a module graph. I thought about extracting some of the functionality in here out, but it adds a bit of indirection. The logic is temporary workarounds and the code in here is tested transitively—if I delete either of the if statements or start flipping conditions then the vendor tests will fail.

&self,
from: &ModuleSpecifier,
to: &ModuleSpecifier,
) -> String {
Copy link
Member

Choose a reason for hiding this comment

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

Might as well have a unit test for relative_specifier_text() too...

Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

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

Looks great. After fixing the issue that Luca discovered in the dotcom repo, I think this would be ready to land.

@dsherret
Copy link
Member Author

@lucacasonato I added the message and fixed the issue seen on the dotcom repo.

Copy link
Member

@lucacasonato lucacasonato left a comment

Choose a reason for hiding this comment

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

LGTM! All the code i tested now works as expected. 🎉

Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

LGTM, I have a few nitpicks, but they can be addressed after this PR lands

cli/tools/vendor/build.rs Show resolved Hide resolved
},
)) = &module.maybe_types_dependency
{
// hack to tell if it's a x-typescript-types header
Copy link
Member

Choose a reason for hiding this comment

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

I don't get what this hack does :(

Copy link
Member Author

Choose a reason for hiding this comment

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

See denoland/deno_graph#133

The hack is to check if the range start and end in the file is zero.

cli/tools/vendor/mod.rs Outdated Show resolved Hide resolved
cli/tools/vendor/mod.rs Outdated Show resolved Hide resolved
Copy link
Member

@littledivy littledivy left a comment

Choose a reason for hiding this comment

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

LGTM! Tested it on a bunch of projects, its perfect!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: deno vendor
5 participants