1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

fix(workspaces/publish): include the license file from the workspace root if not in pkg (#24714)

This commit is contained in:
David Sherret 2024-07-24 21:43:30 -04:00 committed by GitHub
parent 5f5f662a68
commit 84b7504d0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 108 additions and 32 deletions

View file

@ -4,6 +4,7 @@ use std::collections::HashMap;
use std::collections::HashSet;
use std::io::IsTerminal;
use std::path::Path;
use std::path::PathBuf;
use std::process::Stdio;
use std::rc::Rc;
use std::sync::Arc;
@ -13,6 +14,7 @@ use base64::Engine;
use deno_ast::ModuleSpecifier;
use deno_config::workspace::JsrPackageConfig;
use deno_config::workspace::PackageJsonDepResolution;
use deno_config::workspace::Workspace;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
@ -448,7 +450,7 @@ impl PublishPreparer {
move || {
let root_specifier =
ModuleSpecifier::from_directory_path(&root_dir).unwrap();
let publish_paths =
let mut publish_paths =
paths::collect_publish_paths(paths::CollectPublishPathsOptions {
root_dir: &root_dir,
cli_options: &cli_options,
@ -464,13 +466,28 @@ impl PublishPreparer {
);
if !has_license_file(publish_paths.iter().map(|p| &p.specifier)) {
diagnostics_collector.push(PublishDiagnostic::MissingLicense {
expected_path: root_dir.join("LICENSE"),
});
if let Some(license_path) =
resolve_license_file(&root_dir, cli_options.workspace())
{
// force including the license file from the package or workspace root
publish_paths.push(CollectedPublishPath {
specifier: ModuleSpecifier::from_file_path(&license_path)
.unwrap(),
relative_path: "LICENSE".to_string(),
maybe_content: Some(std::fs::read(&license_path).with_context(
|| format!("failed reading '{}'.", license_path.display()),
)?),
path: license_path,
});
} else {
diagnostics_collector.push(PublishDiagnostic::MissingLicense {
expected_path: root_dir.join("LICENSE"),
});
}
}
tar::create_gzipped_tarball(
&publish_paths,
publish_paths,
LazyGraphSourceParser::new(&source_cache, &graph),
&diagnostics_collector,
&unfurler,
@ -1194,31 +1211,49 @@ async fn check_if_git_repo_dirty(cwd: &Path) -> Option<String> {
}
}
static SUPPORTED_LICENSE_FILE_NAMES: [&str; 6] = [
"LICENSE",
"LICENSE.md",
"LICENSE.txt",
"LICENCE",
"LICENCE.md",
"LICENCE.txt",
];
fn resolve_license_file(
pkg_root_dir: &Path,
workspace: &Workspace,
) -> Option<PathBuf> {
let workspace_root_dir = workspace.root_dir_path();
let mut dirs = Vec::with_capacity(2);
dirs.push(pkg_root_dir);
if workspace_root_dir != pkg_root_dir {
dirs.push(&workspace_root_dir);
}
for dir in dirs {
for file_name in &SUPPORTED_LICENSE_FILE_NAMES {
let file_path = dir.join(file_name);
if file_path.exists() {
return Some(file_path);
}
}
}
None
}
fn has_license_file<'a>(
mut specifiers: impl Iterator<Item = &'a ModuleSpecifier>,
) -> bool {
let allowed_license_files = {
let files = HashSet::from([
"license",
"license.md",
"license.txt",
"licence",
"licence.md",
"licence.txt",
]);
if cfg!(debug_assertions) {
for file in &files {
assert_eq!(*file, file.to_lowercase());
}
}
files
};
let supported_license_files = SUPPORTED_LICENSE_FILE_NAMES
.iter()
.map(|s| s.to_lowercase())
.collect::<HashSet<_>>();
specifiers.any(|specifier| {
specifier
.path()
.rsplit_once('/')
.map(|(_, file)| {
allowed_license_files.contains(file.to_lowercase().as_str())
supported_license_files.contains(file.to_lowercase().as_str())
})
.unwrap_or(false)
})

View file

@ -214,7 +214,10 @@ pub enum PackagePathValidationError {
pub struct CollectedPublishPath {
pub specifier: ModuleSpecifier,
pub path: PathBuf,
/// Relative path to use in the tarball.
pub relative_path: String,
/// Specify the contents for any injected paths.
pub maybe_content: Option<Vec<u8>>,
}
pub struct CollectPublishPathsOptions<'a> {
@ -307,6 +310,7 @@ pub fn collect_publish_paths(
specifier,
path,
relative_path,
maybe_content: None,
});
}

View file

@ -34,7 +34,7 @@ pub struct PublishableTarball {
}
pub fn create_gzipped_tarball(
publish_paths: &[CollectedPublishPath],
publish_paths: Vec<CollectedPublishPath>,
source_parser: LazyGraphSourceParser,
diagnostics_collector: &PublishDiagnosticsCollector,
unfurler: &SpecifierUnfurler,
@ -45,15 +45,17 @@ pub fn create_gzipped_tarball(
for path in publish_paths {
let path_str = &path.relative_path;
let specifier = &path.specifier;
let path = &path.path;
let content = resolve_content_maybe_unfurling(
path,
specifier,
unfurler,
source_parser,
diagnostics_collector,
)?;
let content = match path.maybe_content {
Some(content) => content.clone(),
None => resolve_content_maybe_unfurling(
&path.path,
specifier,
unfurler,
source_parser,
diagnostics_collector,
)?,
};
files.push(PublishableTarballFile {
path_str: path_str.clone(),
@ -65,7 +67,7 @@ pub fn create_gzipped_tarball(
tar
.add_file(format!(".{}", path_str), &content)
.with_context(|| {
format!("Unable to add file to tarball '{}'", path.display())
format!("Unable to add file to tarball '{}'", path.path.display())
})?;
}

View file

@ -4,6 +4,15 @@
"args": "publish --token 'sadfasdf'",
"output": "workspace.out"
},
"workspace_dry_run": {
"args": "publish --token 'sadfasdf' --dry-run",
"output": "workspace_dry_run.out"
},
"individual_dry_run": {
"cwd": "./foo",
"args": "publish --token 'sadfasdf' --dry-run",
"output": "foo_dry_run.out"
},
"individual": {
"cwd": "./bar",
"args": "publish --token 'sadfasdf'",

View file

@ -0,0 +1,9 @@
Check file:///[WILDLINE]/foo/mod.ts
Checking for slow types in the public API...
Check file:///[WILDLINE]/foo/mod.ts
Simulating publish of @foo/foo@1.0.0 with files:
[# notice how this line is including the LICENSE from the root directory]
file:///[WILDLINE]/workspace/LICENSE (0B)
file:///[WILDLINE]/workspace/foo/deno.json (135B)
file:///[WILDLINE]/workspace/foo/mod.ts (118B)
Warning Aborting due to --dry-run

View file

@ -0,0 +1,17 @@
Publishing a workspace...
Check file:///[WILDLINE]/workspace/bar/mod.ts
Check file:///[WILDLINE]/workspace/foo/mod.ts
Checking for slow types in the public API...
Check file:///[WILDLINE]/workspace/bar/mod.ts
Check file:///[WILDLINE]/workspace/foo/mod.ts
[UNORDERED_START]
Simulating publish of @foo/foo@1.0.0 with files:
file:///[WILDLINE]/workspace/LICENSE (0B)
file:///[WILDLINE]/workspace/foo/deno.json (135B)
file:///[WILDLINE]/workspace/foo/mod.ts (118B)
Simulating publish of @foo/bar@1.0.0 with files:
file:///[WILDLINE]/workspace/bar/LICENSE (0B)
file:///[WILDLINE]/workspace/bar/deno.json (87B)
file:///[WILDLINE]/workspace/bar/mod.ts (70B)
[UNORDERED_END]
Warning Aborting due to --dry-run