mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
fix(publish): error if there are uncommitted changes (#22613)
Closes https://github.com/denoland/deno/issues/22330
This commit is contained in:
parent
96cfe82664
commit
c2c4e745a5
3 changed files with 91 additions and 1 deletions
|
@ -302,6 +302,7 @@ pub struct PublishFlags {
|
|||
pub token: Option<String>,
|
||||
pub dry_run: bool,
|
||||
pub allow_slow_types: bool,
|
||||
pub allow_dirty: bool,
|
||||
pub provenance: bool,
|
||||
}
|
||||
|
||||
|
@ -2397,9 +2398,14 @@ fn publish_subcommand() -> Command {
|
|||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("allow-dirty")
|
||||
.long("allow-dirty")
|
||||
.help("Allow publishing if the repository has uncommited changed")
|
||||
.action(ArgAction::SetTrue),
|
||||
).arg(
|
||||
Arg::new("provenance")
|
||||
.long("provenance")
|
||||
.help("From CI/CD system, publicly links the package to where it was built and published from.")
|
||||
.help("From CI/CD system, publicly links the package to where it was built and published from")
|
||||
.action(ArgAction::SetTrue)
|
||||
)
|
||||
.arg(check_arg(/* type checks by default */ true))
|
||||
|
@ -3842,6 +3848,7 @@ fn publish_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
|||
token: matches.remove_one("token"),
|
||||
dry_run: matches.get_flag("dry-run"),
|
||||
allow_slow_types: matches.get_flag("allow-slow-types"),
|
||||
allow_dirty: matches.get_flag("allow-dirty"),
|
||||
provenance: matches.get_flag("provenance"),
|
||||
});
|
||||
}
|
||||
|
@ -8564,6 +8571,7 @@ mod tests {
|
|||
"publish",
|
||||
"--dry-run",
|
||||
"--allow-slow-types",
|
||||
"--allow-dirty",
|
||||
"--token=asdf",
|
||||
]);
|
||||
assert_eq!(
|
||||
|
@ -8573,6 +8581,7 @@ mod tests {
|
|||
token: Some("asdf".to_string()),
|
||||
dry_run: true,
|
||||
allow_slow_types: true,
|
||||
allow_dirty: true,
|
||||
provenance: false,
|
||||
}),
|
||||
type_check_mode: TypeCheckMode::Local,
|
||||
|
@ -8591,6 +8600,7 @@ mod tests {
|
|||
subcommand: DenoSubcommand::Publish(PublishFlags {
|
||||
token: Some("asdf".to_string()),
|
||||
dry_run: false,
|
||||
allow_dirty: false,
|
||||
allow_slow_types: false,
|
||||
provenance: true,
|
||||
}),
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
use std::io::IsTerminal;
|
||||
use std::path::Path;
|
||||
use std::process::Stdio;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -24,6 +26,7 @@ use lsp_types::Url;
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use sha2::Digest;
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::args::jsr_api_url;
|
||||
use crate::args::jsr_url;
|
||||
|
@ -937,6 +940,12 @@ pub async fn publish(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
if !publish_flags.allow_dirty
|
||||
&& check_if_git_repo_dirty(cli_options.initial_cwd()).await
|
||||
{
|
||||
bail!("Aborting due to uncomitted changes",);
|
||||
}
|
||||
|
||||
perform_publish(
|
||||
cli_factory.http_client(),
|
||||
prepared_data.publish_order_graph,
|
||||
|
@ -1016,6 +1025,34 @@ fn verify_version_manifest(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn check_if_git_repo_dirty(cwd: &Path) -> bool {
|
||||
let bin_name = if cfg!(windows) { "git.exe" } else { "git" };
|
||||
|
||||
// Check if git exists
|
||||
let git_exists = Command::new(bin_name)
|
||||
.arg("--version")
|
||||
.stderr(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.status()
|
||||
.await
|
||||
.map_or(false, |status| status.success());
|
||||
|
||||
if !git_exists {
|
||||
return false; // Git is not installed
|
||||
}
|
||||
|
||||
// Check if there are uncommitted changes
|
||||
let output = Command::new(bin_name)
|
||||
.current_dir(cwd)
|
||||
.args(["status", "--porcelain"])
|
||||
.output()
|
||||
.await
|
||||
.expect("Failed to execute command");
|
||||
|
||||
let output_str = String::from_utf8_lossy(&output.stdout);
|
||||
!output_str.trim().is_empty()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::tar::PublishableTarball;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use deno_core::serde_json::json;
|
||||
use test_util::assert_contains;
|
||||
use test_util::assert_not_contains;
|
||||
|
@ -427,3 +429,44 @@ fn publish_context_builder() -> TestContextBuilder {
|
|||
.envs(env_vars_for_jsr_tests())
|
||||
.use_temp_cwd()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn allow_dirty() {
|
||||
let context = publish_context_builder().build();
|
||||
let temp_dir = context.temp_dir().path();
|
||||
temp_dir.join("deno.json").write_json(&json!({
|
||||
"name": "@foo/bar",
|
||||
"version": "1.0.0",
|
||||
"exports": "./main.ts",
|
||||
}));
|
||||
|
||||
temp_dir.join("main.ts").write("");
|
||||
|
||||
let cmd = Command::new("git")
|
||||
.arg("init")
|
||||
.arg(temp_dir.as_path())
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(cmd.status.success());
|
||||
|
||||
let output = context
|
||||
.new_command()
|
||||
.arg("publish")
|
||||
.arg("--token")
|
||||
.arg("sadfasdf")
|
||||
.run();
|
||||
output.assert_exit_code(1);
|
||||
let output = output.combined_output();
|
||||
assert_contains!(output, "Aborting due to uncomitted changes");
|
||||
|
||||
let output = context
|
||||
.new_command()
|
||||
.arg("publish")
|
||||
.arg("--allow-dirty")
|
||||
.arg("--token")
|
||||
.arg("sadfasdf")
|
||||
.run();
|
||||
output.assert_exit_code(0);
|
||||
let output = output.combined_output();
|
||||
assert_contains!(output, "Successfully published");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue