Skip to content

Commit 9956731

Browse files
authored
feat(publish): add --set-version <version> flag (#26141)
1 parent 8be2bbf commit 9956731

File tree

16 files changed

+127
-27
lines changed

16 files changed

+127
-27
lines changed

cli/args/flags.rs

+36-18
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ pub struct PublishFlags {
428428
pub allow_slow_types: bool,
429429
pub allow_dirty: bool,
430430
pub no_provenance: bool,
431+
pub set_version: Option<String>,
431432
}
432433

433434
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -1391,7 +1392,7 @@ pub fn flags_from_vec(args: Vec<OsString>) -> clap::error::Result<Flags> {
13911392
"uninstall" => uninstall_parse(&mut flags, &mut m),
13921393
"upgrade" => upgrade_parse(&mut flags, &mut m),
13931394
"vendor" => vendor_parse(&mut flags, &mut m),
1394-
"publish" => publish_parse(&mut flags, &mut m),
1395+
"publish" => publish_parse(&mut flags, &mut m)?,
13951396
_ => unreachable!(),
13961397
}
13971398
} else {
@@ -3225,42 +3226,51 @@ fn publish_subcommand() -> Command {
32253226
command("publish", "Publish the current working directory's package or workspace to JSR", UnstableArgsConfig::ResolutionOnly)
32263227
.defer(|cmd| {
32273228
cmd
3228-
.arg(
3229-
Arg::new("token")
3230-
.long("token")
3231-
.help("The API token to use when publishing. If unset, interactive authentication is be used")
3232-
.help_heading(PUBLISH_HEADING)
3233-
)
3229+
.arg(
3230+
Arg::new("token")
3231+
.long("token")
3232+
.help("The API token to use when publishing. If unset, interactive authentication is be used")
3233+
.help_heading(PUBLISH_HEADING)
3234+
)
32343235
.arg(config_arg())
32353236
.arg(no_config_arg())
32363237
.arg(
32373238
Arg::new("dry-run")
32383239
.long("dry-run")
32393240
.help("Prepare the package for publishing performing all checks and validations without uploading")
32403241
.action(ArgAction::SetTrue)
3241-
.help_heading(PUBLISH_HEADING),
3242+
.help_heading(PUBLISH_HEADING),
32423243
)
32433244
.arg(
32443245
Arg::new("allow-slow-types")
32453246
.long("allow-slow-types")
32463247
.help("Allow publishing with slow types")
32473248
.action(ArgAction::SetTrue)
3248-
.help_heading(PUBLISH_HEADING),
3249+
.help_heading(PUBLISH_HEADING),
32493250
)
32503251
.arg(
32513252
Arg::new("allow-dirty")
32523253
.long("allow-dirty")
32533254
.help("Allow publishing if the repository has uncommitted changed")
32543255
.action(ArgAction::SetTrue)
3255-
.help_heading(PUBLISH_HEADING),
3256-
).arg(
3257-
Arg::new("no-provenance")
3258-
.long("no-provenance")
3259-
.help(cstr!("Disable provenance attestation.
3256+
.help_heading(PUBLISH_HEADING),
3257+
)
3258+
.arg(
3259+
Arg::new("no-provenance")
3260+
.long("no-provenance")
3261+
.help(cstr!("Disable provenance attestation.
32603262
<p(245)>Enabled by default on Github actions, publicly links the package to where it was built and published from.</>"))
3261-
.action(ArgAction::SetTrue)
3262-
.help_heading(PUBLISH_HEADING)
3263-
)
3263+
.action(ArgAction::SetTrue)
3264+
.help_heading(PUBLISH_HEADING)
3265+
)
3266+
.arg(
3267+
Arg::new("set-version")
3268+
.long("set-version")
3269+
.help("Set version for a package to be published.
3270+
<p(245)>This flag can be used while publishing individual packages and cannot be used in a workspace.</>")
3271+
.value_name("VERSION")
3272+
.help_heading(PUBLISH_HEADING)
3273+
)
32643274
.arg(check_arg(/* type checks by default */ true))
32653275
.arg(no_check_arg())
32663276
})
@@ -5229,7 +5239,10 @@ fn vendor_parse(flags: &mut Flags, _matches: &mut ArgMatches) {
52295239
flags.subcommand = DenoSubcommand::Vendor
52305240
}
52315241

5232-
fn publish_parse(flags: &mut Flags, matches: &mut ArgMatches) {
5242+
fn publish_parse(
5243+
flags: &mut Flags,
5244+
matches: &mut ArgMatches,
5245+
) -> clap::error::Result<()> {
52335246
flags.type_check_mode = TypeCheckMode::Local; // local by default
52345247
unstable_args_parse(flags, matches, UnstableArgsConfig::ResolutionOnly);
52355248
no_check_arg_parse(flags, matches);
@@ -5242,7 +5255,10 @@ fn publish_parse(flags: &mut Flags, matches: &mut ArgMatches) {
52425255
allow_slow_types: matches.get_flag("allow-slow-types"),
52435256
allow_dirty: matches.get_flag("allow-dirty"),
52445257
no_provenance: matches.get_flag("no-provenance"),
5258+
set_version: matches.remove_one::<String>("set-version"),
52455259
});
5260+
5261+
Ok(())
52465262
}
52475263

52485264
fn compile_args_parse(
@@ -10769,6 +10785,7 @@ mod tests {
1076910785
"--allow-slow-types",
1077010786
"--allow-dirty",
1077110787
"--token=asdf",
10788+
"--set-version=1.0.1",
1077210789
]);
1077310790
assert_eq!(
1077410791
r.unwrap(),
@@ -10779,6 +10796,7 @@ mod tests {
1077910796
allow_slow_types: true,
1078010797
allow_dirty: true,
1078110798
no_provenance: true,
10799+
set_version: Some("1.0.1".to_string()),
1078210800
}),
1078310801
type_check_mode: TypeCheckMode::Local,
1078410802
..Flags::default()

cli/tools/registry/mod.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub async fn publish(
9090

9191
let cli_options = cli_factory.cli_options()?;
9292
let directory_path = cli_options.initial_cwd();
93-
let publish_configs = cli_options.start_dir.jsr_packages_for_publish();
93+
let mut publish_configs = cli_options.start_dir.jsr_packages_for_publish();
9494
if publish_configs.is_empty() {
9595
match cli_options.start_dir.maybe_deno_json() {
9696
Some(deno_json) => {
@@ -108,6 +108,18 @@ pub async fn publish(
108108
}
109109
}
110110
}
111+
112+
if let Some(version) = &publish_flags.set_version {
113+
if publish_configs.len() > 1 {
114+
bail!("Cannot use --set-version when publishing a workspace. Change your cwd to an individual package instead.");
115+
}
116+
if let Some(publish_config) = publish_configs.get_mut(0) {
117+
let mut config_file = publish_config.config_file.as_ref().clone();
118+
config_file.json.version = Some(version.clone());
119+
publish_config.config_file = Arc::new(config_file);
120+
}
121+
}
122+
111123
let specifier_unfurler = Arc::new(SpecifierUnfurler::new(
112124
if cli_options.unstable_sloppy_imports() {
113125
Some(CliSloppyImportsResolver::new(SloppyImportsCachedFs::new(
@@ -410,9 +422,12 @@ impl PublishPreparer {
410422
let deno_json = &package.config_file;
411423
let config_path = deno_json.specifier.to_file_path().unwrap();
412424
let root_dir = config_path.parent().unwrap().to_path_buf();
413-
let Some(version) = deno_json.json.version.clone() else {
414-
bail!("{} is missing 'version' field", deno_json.specifier);
415-
};
425+
let version = deno_json.json.version.clone().ok_or_else(|| {
426+
deno_core::anyhow::anyhow!(
427+
"{} is missing 'version' field",
428+
deno_json.specifier
429+
)
430+
})?;
416431
if deno_json.json.exports.is_none() {
417432
let mut suggested_entrypoint = None;
418433

@@ -435,11 +450,11 @@ impl PublishPreparer {
435450
);
436451

437452
bail!(
438-
"You did not specify an entrypoint to \"{}\" package in {}. Add `exports` mapping in the configuration file, eg:\n{}",
439-
package.name,
440-
deno_json.specifier,
441-
exports_content
442-
);
453+
"You did not specify an entrypoint to \"{}\" package in {}. Add `exports` mapping in the configuration file, eg:\n{}",
454+
package.name,
455+
deno_json.specifier,
456+
exports_content
457+
);
443458
}
444459
let Some(name_no_at) = package.name.strip_prefix('@') else {
445460
bail!("Invalid package name, use '@<scope_name>/<package_name> format");

tests/specs/publish/set_version/multiple_packages/LICENSE

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"args": "publish --set-version 1.1.0 --token 'sadfasdf'",
3+
"output": "error_set_version.out",
4+
"exitCode": 1
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"workspace": {
3+
"members": [
4+
"packages/package1",
5+
"packages/package2"
6+
]
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
error: Cannot use --set-version when publishing a workspace. Change your cwd to an individual package instead.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "@foo/package1",
3+
"version": "1.0.0",
4+
"exports": {
5+
".": "./mod.ts"
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function package1() {
2+
return "package1";
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "@foo/package2",
3+
"version": "1.0.0",
4+
"exports": {
5+
".": "./mod.ts"
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function package2() {
2+
return "package2";
3+
}

tests/specs/publish/set_version/success/LICENSE

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"args": "publish --set-version 1.1.0 --token 'sadfasdf'",
3+
"output": "successful_set_version.out"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "@foo/bar",
3+
"version": "1.0.0",
4+
"exports": {
5+
".": "./mod.ts"
6+
},
7+
"imports": {
8+
"@std/http": "./std_http.ts"
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import http from "@std/http";
2+
3+
export function foobar(): { fileServer(): void } {
4+
return {
5+
fileServer: http.fileServer,
6+
};
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// temp until we get jsr:@std/http in the test server
2+
export default {
3+
fileServer() {
4+
console.log("Hi");
5+
},
6+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Check file:///[WILDCARD]/success/mod.ts
2+
Checking for slow types in the public API...
3+
Check file:///[WILDCARD]/success/mod.ts
4+
Publishing @foo/[email protected] ...
5+
Successfully published @foo/[email protected]
6+
Visit http://127.0.0.1:4250/@foo/[email protected] for details

0 commit comments

Comments
 (0)