Repository: denoland/deno (language: rust)

Issue:
Deno compile should never include the specified output executable in itself
Run this twice:

```
> deno compile --include . main.js
// ...ok...
> deno compile --include . main.js
Compile file:///V:/scratch/main.js to scratch.exe
error: Writing deno compile executable to temporary file 'scratch.exe.tmp-619f5e5217cfea84'

Caused by:
    0: Including V:\scratch\scratch.exe
    1: Reading V:\scratch\scratch.exe
    2: The system cannot find the file specified. (os error 2)
```

Version: Deno 2.1.6



Discussion / hints:
I'll try to solve this...


Fix patch:
diff --git a/cli/tools/compile.rs b/cli/tools/compile.rs
index 5df399336afe3a..6183ceb9126e38 100644
--- a/cli/tools/compile.rs
+++ b/cli/tools/compile.rs
@@ -37,18 +37,18 @@ pub async fn compile(
   let binary_writer = factory.create_compile_binary_writer().await?;
   let http_client = factory.http_client_provider();
   let entrypoint = cli_options.resolve_main_module()?;
-  let (module_roots, include_files) = get_module_roots_and_include_files(
-    entrypoint,
-    &compile_flags,
-    cli_options.initial_cwd(),
-  )?;
-
   let output_path = resolve_compile_executable_output_path(
     http_client,
     &compile_flags,
     cli_options.initial_cwd(),
   )
   .await?;
+  let (module_roots, include_files) = get_module_roots_and_include_files(
+    entrypoint,
+    &url_from_file_path(&cli_options.initial_cwd().join(&output_path))?,
+    &compile_flags,
+    cli_options.initial_cwd(),
+  )?;
 
   let graph = Arc::try_unwrap(
     module_graph_creator
@@ -198,6 +198,7 @@ fn validate_output_path(output_path: &Path) -> Result<(), AnyError> {
 
 fn get_module_roots_and_include_files(
   entrypoint: &ModuleSpecifier,
+  output_url: &ModuleSpecifier,
   compile_flags: &CompileFlags,
   initial_cwd: &Path,
 ) -> Result<(Vec<ModuleSpecifier>, Vec<ModuleSpecifier>), AnyError> {
@@ -226,9 +227,8 @@ fn get_module_roots_and_include_files(
 
   fn analyze_path(
     url: &ModuleSpecifier,
-    module_roots: &mut Vec<ModuleSpecifier>,
-    include_files: &mut Vec<ModuleSpecifier>,
     searched_paths: &mut HashSet<PathBuf>,
+    mut add_url: impl FnMut(ModuleSpecifier),
   ) -> Result<(), AnyError> {
     let Ok(path) = url_to_file_path(url) else {
       return Ok(());
@@ -240,10 +240,7 @@ fn get_module_roots_and_include_files(
       }
       if !path.is_dir() {
         let url = url_from_file_path(&path)?;
-        include_files.push(url.clone());
-        if is_module_graph_module(&url) {
-          module_roots.push(url);
-        }
+        add_url(url);
         continue;
       }
       for entry in std::fs::read_dir(&path).with_context(|| {
@@ -270,12 +267,14 @@ fn get_module_roots_and_include_files(
         include_files.push(url);
       }
     } else {
-      analyze_path(
-        &url,
-        &mut module_roots,
-        &mut include_files,
-        &mut searched_paths,
-      )?;
+      analyze_path(&url, &mut searched_paths, |file_url| {
+        if file_url != *output_url {
+          include_files.push(file_url.clone());
+          if is_module_graph_module(&file_url) {
+            module_roots.push(file_url);
+          }
+        }
+      })?;
     }
   }
   Ok((module_roots, include_files))


Test patch:
diff --git a/tests/specs/compile/two_times_compile_include_all/__test__.jsonc b/tests/specs/compile/two_times_compile_include_all/__test__.jsonc
new file mode 100644
index 00000000000000..c9098ed00f4dba
--- /dev/null
+++ b/tests/specs/compile/two_times_compile_include_all/__test__.jsonc
@@ -0,0 +1,13 @@
+{
+  "tempDir": true,
+  "steps": [
+    {
+      "args": "compile --include . main.ts",
+      "output": "compile1.out"
+    },
+    {
+      "args": "compile --include . main.ts",
+      "output": "compile2.out"
+    }
+  ]
+}
diff --git a/tests/specs/compile/two_times_compile_include_all/compile1.out b/tests/specs/compile/two_times_compile_include_all/compile1.out
new file mode 100644
index 00000000000000..7db3d2b50b1760
--- /dev/null
+++ b/tests/specs/compile/two_times_compile_include_all/compile1.out
@@ -0,0 +1,14 @@
+Check file:[WILDLINE]main.ts
+Check file:[WILDLINE]deno.json
+Compile file:[WILDLINE]main.ts to [WILDLINE]
+
+Embedded Files
+
+[WILDLINE]
+├── deno.json ([WILDLINE])
+└── main.ts ([WILDLINE])
+
+Files: [WILDCARD]
+Metadata: [WILDCARD]
+Remote modules: [WILDCARD]
+
diff --git a/tests/specs/compile/two_times_compile_include_all/compile2.out b/tests/specs/compile/two_times_compile_include_all/compile2.out
new file mode 100644
index 00000000000000..01871fa9745958
--- /dev/null
+++ b/tests/specs/compile/two_times_compile_include_all/compile2.out
@@ -0,0 +1,12 @@
+Compile file:[WILDLINE]main.ts to [WILDLINE]
+
+Embedded Files
+
+[WILDLINE]
+├── deno.json ([WILDLINE])
+└── main.ts ([WILDLINE])
+
+Files: [WILDCARD]
+Metadata: [WILDCARD]
+Remote modules: [WILDCARD]
+
diff --git a/tests/specs/compile/two_times_compile_include_all/deno.json b/tests/specs/compile/two_times_compile_include_all/deno.json
new file mode 100644
index 00000000000000..c0401f75f5c287
--- /dev/null
+++ b/tests/specs/compile/two_times_compile_include_all/deno.json
@@ -0,0 +1,3 @@
+{
+  "unstable": ["kv"]
+}
diff --git a/tests/specs/compile/two_times_compile_include_all/main.ts b/tests/specs/compile/two_times_compile_include_all/main.ts
new file mode 100644
index 00000000000000..5f64f9c196585d
--- /dev/null
+++ b/tests/specs/compile/two_times_compile_include_all/main.ts
@@ -0,0 +1,1 @@
+console.log("WHATEVER");