]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Always rerun build if Format=none and don't remove previous outputs
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 2 Jul 2024 20:56:25 +0000 (22:56 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 2 Jul 2024 21:41:33 +0000 (23:41 +0200)
Let's always rerun the build if Format=none. Also, since we know
Format=none won't touch any of the outputs we know about, let's keep
the existing outputs intact. This allows using Format=none to rerun
the build script without removing the existing output (e.g. directory
or disk image).

We'll be able to make use of this in mkosi-kernel to rebuild the kernel
modules without removing the disk image produced in a previous step.

We also simplify check_outputs() to only check the main output and not
the auxiliary outputs.

mkosi/__init__.py
mkosi/resources/mkosi.md

index 95997ea3e9045a5bc01a208c93a7fd6de560712f..34ac6f469ece8c51117f49800f9f05549011358c 100644 (file)
@@ -2823,14 +2823,13 @@ def check_inputs(config: Config) -> None:
 
 
 def check_outputs(config: Config) -> None:
-    for f in (
-        config.output_with_compression,
-        config.output_checksum if config.checksum else None,
-        config.output_signature if config.sign else None,
-        config.output_nspawn_settings if config.nspawn_settings else None,
-    ):
-        if f and (config.output_dir_or_cwd() / f).exists():
-            logging.info(f"Output path {f} exists already. (Use --force to rebuild.)")
+    if config.output_format == OutputFormat.none:
+        return
+
+    f = config.output_dir_or_cwd() / config.output_with_compression
+
+    if f.exists() and not f.is_symlink():
+        logging.info(f"Output path {f} exists already. (Use --force to rebuild.)")
 
 
 def check_tool(config: Config, *tools: PathString, reason: str, hint: Optional[str] = None) -> Path:
@@ -3835,8 +3834,6 @@ def build_image(context: Context) -> None:
         run_build_scripts(context)
 
         if context.config.output_format == OutputFormat.none:
-            # Touch an empty file to indicate the image was built.
-            (context.staging / context.config.output).touch()
             finalize_staging(context)
             return
 
@@ -4490,24 +4487,25 @@ def run_clean(args: Args, config: Config, *, resources: Path) -> None:
         remove_build_cache = args.force > 1
         remove_package_cache = args.force > 2
 
-    outputs = {
-        config.output_dir_or_cwd() / output
-        for output in config.outputs
-        if (config.output_dir_or_cwd() / output).exists()
-    }
+    if config.output_format != OutputFormat.none or args.force:
+        outputs = {
+            config.output_dir_or_cwd() / output
+            for output in config.outputs
+            if (config.output_dir_or_cwd() / output).exists()
+        }
 
-    # Make sure we resolve the symlink we create in the output directory and remove its target as well as it might not
-    # be in the list of outputs anymore if the compression or output format was changed.
-    outputs |= {o.resolve() for o in outputs}
+        # Make sure we resolve the symlink we create in the output directory and remove its target as well as it might
+        # not be in the list of outputs anymore if the compression or output format was changed.
+        outputs |= {o.resolve() for o in outputs}
 
-    if outputs:
-        with (
-            complete_step(f"Removing output files of {config.name()} image…"),
-            flock_or_die(config.output_dir_or_cwd() / config.output)
-            if (config.output_dir_or_cwd() / config.output).exists()
-            else contextlib.nullcontext()
-        ):
-            rmtree(*outputs)
+        if outputs:
+            with (
+                complete_step(f"Removing output files of {config.name()} image…"),
+                flock_or_die(config.output_dir_or_cwd() / config.output)
+                if (config.output_dir_or_cwd() / config.output).exists()
+                else contextlib.nullcontext()
+            ):
+                rmtree(*outputs)
 
     if remove_build_cache:
         if config.cache_dir:
@@ -4773,7 +4771,10 @@ def run_verb(args: Args, images: Sequence[Config], *, resources: Path) -> None:
         if args.verb != Verb.build and args.force == 0:
             continue
 
-        if (config.output_dir_or_cwd() / config.output_with_compression).exists():
+        if (
+            config.output_format != OutputFormat.none and
+            (config.output_dir_or_cwd() / config.output_with_compression).exists()
+        ):
             continue
 
         check_inputs(config)
index 4cadee648b4fb611fa70ccfb12bce19ed4b7f16d..33c2f3136b099a393775f99060554fba5caa429c 100644 (file)
@@ -516,6 +516,12 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
     include it in the kernel command line of every unified kernel image
     built by mkosi.
 
+    If the `none` output format is used, the outputs from a previous
+    build are not removed, but clean scripts (see `CleanScripts=`) are
+    still executed. This allows rerunning a build script
+    (see `BuildScripts=`) without removing the results of a previous
+    build.
+
 `ManifestFormat=`, `--manifest-format=`
 :   The manifest format type or types to generate. A comma-delimited
     list consisting of `json` (the standard JSON output format that