summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRabin Gaire <rabingaire20@gmail.com>2022-01-11 10:09:39 +0545
committerGitHub <noreply@github.com>2022-01-10 23:24:39 -0500
commit605b8db8f61fc4c0c71d11cde873af18d87c49bf (patch)
tree63ecb48a02e2549aa8db941ecdd95147843a7b36
parentb66afa2518042cda239ef07f221722781ca660f6 (diff)
cli(compile): fix output flag behaviour on compile command (#13299)
-rw-r--r--cli/fs_util.rs39
-rw-r--r--cli/main.rs9
-rw-r--r--cli/tests/integration/compile_tests.rs68
-rw-r--r--cli/tools/standalone.rs11
4 files changed, 124 insertions, 3 deletions
diff --git a/cli/fs_util.rs b/cli/fs_util.rs
index 06bdb689a..7290d3696 100644
--- a/cli/fs_util.rs
+++ b/cli/fs_util.rs
@@ -376,6 +376,20 @@ pub fn specifier_parent(specifier: &ModuleSpecifier) -> ModuleSpecifier {
specifier
}
+/// This function checks if input path has trailing slash or not. If input path
+/// has trailing slash it will return true else it will return false.
+pub fn path_has_trailing_slash(path: &Path) -> bool {
+ if let Some(path_str) = path.to_str() {
+ if cfg!(windows) {
+ path_str.ends_with('\\')
+ } else {
+ path_str.ends_with('/')
+ }
+ } else {
+ false
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -754,4 +768,29 @@ mod tests {
assert_eq!(result.to_string(), expected);
}
}
+
+ #[test]
+ fn test_path_has_trailing_slash() {
+ #[cfg(not(windows))]
+ {
+ run_test("/Users/johndoe/Desktop/deno-project/target/", true);
+ run_test(r"/Users/johndoe/deno-project/target//", true);
+ run_test("/Users/johndoe/Desktop/deno-project", false);
+ run_test(r"/Users/johndoe/deno-project\", false);
+ }
+
+ #[cfg(windows)]
+ {
+ run_test(r"C:\test\deno-project\", true);
+ run_test(r"C:\test\deno-project\\", true);
+ run_test(r"C:\test\file.txt", false);
+ run_test(r"C:\test\file.txt/", false);
+ }
+
+ fn run_test(path_str: &str, expected: bool) {
+ let path = Path::new(path_str);
+ let result = path_has_trailing_slash(path);
+ assert_eq!(result, expected);
+ }
+ }
}
diff --git a/cli/main.rs b/cli/main.rs
index f4800b72a..d8e4c4a70 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -378,7 +378,14 @@ async fn compile_command(
let ps = ProcState::build(flags.clone()).await?;
let deno_dir = &ps.dir;
- let output = compile_flags.output.or_else(|| {
+ let output = compile_flags.output.and_then(|output| {
+ if fs_util::path_has_trailing_slash(&output) {
+ let infer_file_name = infer_name_from_url(&module_specifier).map(PathBuf::from)?;
+ Some(output.join(infer_file_name))
+ } else {
+ Some(output)
+ }
+ }).or_else(|| {
infer_name_from_url(&module_specifier).map(PathBuf::from)
}).ok_or_else(|| generic_error(
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
diff --git a/cli/tests/integration/compile_tests.rs b/cli/tests/integration/compile_tests.rs
index d2abd04d5..bff03013f 100644
--- a/cli/tests/integration/compile_tests.rs
+++ b/cli/tests/integration/compile_tests.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+use std::fs::File;
use std::process::Command;
use tempfile::TempDir;
use test_util as util;
@@ -234,6 +235,73 @@ fn standalone_compiler_ops() {
}
#[test]
+fn compile_with_directory_output_flag() {
+ let dir = TempDir::new().expect("tempdir fail");
+ let output_path = if cfg!(windows) {
+ dir.path().join(r"args\random\")
+ } else {
+ dir.path().join("args/random/")
+ };
+ let output = util::deno_cmd()
+ .current_dir(util::testdata_path())
+ .arg("compile")
+ .arg("--unstable")
+ .arg("--output")
+ .arg(&output_path)
+ .arg("./standalone_compiler_ops.ts")
+ .stdout(std::process::Stdio::piped())
+ .spawn()
+ .unwrap()
+ .wait_with_output()
+ .unwrap();
+ assert!(output.status.success());
+ let exe = if cfg!(windows) {
+ output_path.join("standalone_compiler_ops.exe")
+ } else {
+ output_path.join("standalone_compiler_ops")
+ };
+ assert!(&exe.exists());
+ let output = Command::new(exe)
+ .stdout(std::process::Stdio::piped())
+ .stderr(std::process::Stdio::piped())
+ .spawn()
+ .unwrap()
+ .wait_with_output()
+ .unwrap();
+ assert!(output.status.success());
+ assert_eq!(output.stdout, b"Hello, Compiler API!\n");
+}
+
+#[test]
+fn compile_with_file_exists_error() {
+ let dir = TempDir::new().expect("tempdir fail");
+ let output_path = if cfg!(windows) {
+ dir.path().join(r"args\")
+ } else {
+ dir.path().join("args/")
+ };
+ let file_path = dir.path().join("args");
+ File::create(&file_path).expect("cannot create file");
+ let output = util::deno_cmd()
+ .current_dir(util::testdata_path())
+ .arg("compile")
+ .arg("--unstable")
+ .arg("--output")
+ .arg(&output_path)
+ .arg("./028_args.ts")
+ .stderr(std::process::Stdio::piped())
+ .spawn()
+ .unwrap()
+ .wait_with_output()
+ .unwrap();
+ assert!(!output.status.success());
+ let expected_stderr =
+ format!("Could not compile: {:?} is a file.\n", &file_path);
+ let stderr = String::from_utf8(output.stderr).unwrap();
+ assert!(stderr.contains(&expected_stderr));
+}
+
+#[test]
fn compile_with_directory_exists_error() {
let dir = TempDir::new().expect("tempdir fail");
let exe = if cfg!(windows) {
diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs
index a29b405ba..a0960d051 100644
--- a/cli/tools/standalone.rs
+++ b/cli/tools/standalone.rs
@@ -136,14 +136,14 @@ pub async fn write_standalone_binary(
let output = match target {
Some(target) => {
if target.contains("windows") {
- PathBuf::from(output.display().to_string() + ".exe")
+ output.with_extension("exe")
} else {
output
}
}
None => {
if cfg!(windows) && output.extension().unwrap_or_default() != "exe" {
- PathBuf::from(output.display().to_string() + ".exe")
+ output.with_extension("exe")
} else {
output
}
@@ -175,7 +175,14 @@ pub async fn write_standalone_binary(
// Remove file if it was indeed a deno compiled binary, to avoid corruption
// (see https://github.com/denoland/deno/issues/10310)
std::fs::remove_file(&output)?;
+ } else {
+ let output_base = &output.parent().unwrap();
+ if output_base.exists() && output_base.is_file() {
+ bail!("Could not compile: {:?} is a file.", &output_base);
+ }
+ tokio::fs::create_dir_all(output_base).await?;
}
+
tokio::fs::write(&output, final_bin).await?;
#[cfg(unix)]
{