Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2821023
fix: minor change due to `uuid` being a workspace crate
justpav05 Aug 27, 2026
726f46f
fix: minor fix for inherited fields in Cargo.toml
justpav05 Aug 27, 2026
5dc445d
fix: minor fix for inherited fields in Cargo.toml
justpav05 Aug 27, 2026
5fe56eb
fix: add LGPL-3.0-linking-exception for statis link
justpav05 Aug 27, 2026
da95b71
fix: while decoder abi not need anymore - just deleted it
justpav05 Aug 27, 2026
d1b8694
fix: delete unused abi
justpav05 Aug 27, 2026
6602bbc
fix: simplified the separate ABI request for hooks; it is now included
justpav05 Aug 27, 2026
ec6841e
fix: syncs docs
justpav05 Aug 27, 2026
9884653
fix: added new C fields to internal types
justpav05 Aug 27, 2026
37d6a51
fix: update THE TODO. Unstall HOOOKS, EA!!!
justpav05 Aug 27, 2026
6309896
fix: hook setup completed
justpav05 Aug 27, 2026
5c4a057
fix: fixed the macro for recdatabase: it now correctly handles generic
justpav05 Aug 28, 2026
c22eb97
fix: new recdata marco?
justpav05 Aug 28, 2026
c09aa76
fix: new table for hooks in database
justpav05 Aug 28, 2026
6b24565
fix: updated dependency versions
justpav05 Aug 28, 2026
3bc9e09
fix: fixed TOML file style
justpav05 Aug 28, 2026
34f7ab8
fix: update docs
justpav05 Aug 28, 2026
757171f
new: decoding work is progressing gradually
justpav05 Aug 28, 2026
1b06dd5
fix: removed the entire old Zig decoder for ALPM packages
justpav05 Aug 29, 2026
389a790
new: a new decoder for alpm packages is fully ready
justpav05 Aug 29, 2026
46c9716
new: added a type for decoder hooks
justpav05 Aug 29, 2026
0d9a7c9
new: added tests to xtask
justpav05 Aug 29, 2026
32e1af8
new: now we have tests
justpav05 Aug 29, 2026
0e6d9df
fix: updated TODO
justpav05 Aug 29, 2026
b6e5f76
fix: delete alpm decoder from pipeline
justpav05 Aug 29, 2026
3300a73
fix: added required license
justpav05 Aug 29, 2026
a717327
new: add static link for alpm decoder
justpav05 Aug 29, 2026
6b2c1d1
fix: decoder name now taken from the end
justpav05 Aug 29, 2026
60c07f5
fix: extracted common comparison function to ABI
justpav05 Aug 29, 2026
b459473
fix: delete old deb zig lib
justpav05 Aug 29, 2026
48f7a13
new: the decoder for .deb packages has been completely rewritten in Rust
justpav05 Aug 29, 2026
ccd5192
fix: add tests for deb decoder
justpav05 Aug 29, 2026
52128d3
fix: update README
justpav05 Aug 29, 2026
d8941c7
fix: added a stub for the RPM decoder
justpav05 Aug 29, 2026
46d2886
fix: added a stub for the xbps decoder
justpav05 Aug 29, 2026
2e4e439
fix: added descriptions for boot plugins
justpav05 Aug 29, 2026
dba46a6
fix: added descriptions for decoders
justpav05 Aug 29, 2026
c57df7f
fix: add descriptions
justpav05 Aug 29, 2026
b137aab
fix: delete Zig Ci, because it`s don`t need anymore
justpav05 Aug 29, 2026
b4f06bd
fix: fixed build.rs to read only its own section of the code, rather
justpav05 Aug 29, 2026
8520a08
fix: added a new workspace dependency
justpav05 Aug 29, 2026
2f16326
fix: completely rewrote the RPM format unpacker adnd with static linking
justpav05 Aug 29, 2026
8df3505
fix: add tests for deb decoder
justpav05 Aug 29, 2026
268b1ea
fix: delete unnnesassary zig decoder
justpav05 Aug 29, 2026
d688e87
fix: update README
justpav05 Aug 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
39 changes: 0 additions & 39 deletions .github/workflows/ci-zig.yml

This file was deleted.

2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Every new source file needs an SPDX header matching its directory's license, e.g
```rust
// SPDX-FileCopyrightText: 2026 <your name>
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception
```

For files where a comment header doesn't make sense (e.g. Markdown, TOML), add an annotation to
Expand Down
14 changes: 12 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[workspace]
resolver = "3"
members = ["user/upac-cli", "user/sign-cli", "user/setup-cli", "lib/macro", "lib/abi", "lib/lib" , "lib/pki", "lib/types", "lib/setup", "booters/uki", "booters/systemd-boot", "booters/grub", "booters/refind"]
members = ["user/upac-cli", "user/sign-cli", "user/setup-cli", "lib/macro", "lib/abi", "lib/lib" , "lib/pki", "lib/types", "lib/setup", "booters/uki", "booters/systemd-boot", "booters/grub", "booters/refind", "decoders/alpm", "decoders/deb", "decoders/rpm", "decoders/xbps"]

[workspace.package]
version = "0.2.0"
edition = "2024"
rust-version = "1.98"

license = "LGPL-3.0-or-later"
license = "LGPL-3.0-or-later WITH LGPL-3.0-linking-exception"
license-file = "LICENSES/LGPL-3.0-or-later"

readme = "README.md"
Expand Down Expand Up @@ -38,6 +38,10 @@ upac-uki = { path = "booters/uki", default-features = false }
upac-systemd-boot = { path = "booters/systemd-boot", default-features = false }
upac-grub = { path = "booters/grub", default-features = false }
upac-refind = { path = "booters/refind", default-features = false }
upac-decoders-alpm = { path = "decoders/alpm", package = "alpm", default-features = false }
upac-decoders-deb = { path = "decoders/deb", package = "deb", default-features = false }
upac-decoders-rpm = { path = "decoders/rpm", package = "rpm", default-features = false }
upac-decoders-xbps = { path = "decoders/xbps", package = "xbps", default-features = false }

composefs-oci = { version = "0.9.0", features = ["composefs-boot", "boot", "tar"] }
nix = { version = "0.31.3", features = ["mount", "sched", "fs", "net"] }
Expand All @@ -60,6 +64,12 @@ composefs-boot = "0.9.0"
indicatif = "0.18.4"
efivar = "2.0.0"
tempfile = "3"
ar = "0.9.0"
cpio = "0.4.1"
flate2 = "1.1.9"
tar = "0.4.46"
xz2 = "0.1.7"
zstd = "0.13.3"

[profile.dev]
opt-level = 0
Expand Down
16 changes: 16 additions & 0 deletions LICENSES/LGPL-3.0-linking-exception.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
As a special exception to the GNU Lesser General Public License version 3
("LGPL3"), the copyright holders of this Library give you permission to
convey to a third party a Combined Work that links statically or dynamically
to this Library without providing any Minimal Corresponding Source or
Minimal Application Code as set out in 4d or providing the installation
information set out in section 4e, provided that you comply with the other
provisions of LGPL3 and provided that you meet, for the Application the
terms and conditions of the license(s) which apply to the Application.

Except as stated in this special exception, the provisions of LGPL3 will
continue to comply in full to this Library. If you modify this Library, you
may apply this exception to your version of this Library, but you are not
obliged to do so. If you do not wish to do so, delete this exception
statement from your version. This exception does not (and cannot) modify any
license terms which apply to the Application, with which you must still
comply.
31 changes: 21 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,13 @@ The core library exposes a C-compatible ABI through `libupac.so`. All strings cr

### Decoders (`decoders/`)

Decoders are separate shared libraries, still written in [Zig](https://ziglang.org/), that handle format-specific package unpacking. Each decoder receives a package path, an output directory, and a SHA-256 checksum; it verifies the checksum, extracts the package, parses the metadata, and returns a `PackageMeta` struct.
Decoders are separate shared libraries that handle format-specific package unpacking. Each decoder receives a package path, an output directory, and a SHA-256 checksum; it verifies the checksum, extracts the package, parses the metadata, and returns a `PackageMeta` struct, its dependencies, and any declarative (package-format-native) trigger names it declares. `alpm`, `deb` and `rpm` are written in [Rust](https://www.rust-lang.org/) (and can also be statically linked into `upac-lib` via the `builtin-alpm`/`builtin-deb`/`builtin-rpm` Cargo features); `xbps` is still [Zig](https://ziglang.org/) and is planned for the same Rust rewrite.

| Decoder | Formats | Distributions |
|---|---|---|
| **`libupac-alpm.so`** | `.pkg.tar.zst`, `.pkg.tar.xz`, `.pkg.tar.gz` | Arch Linux, Manjaro, etc. |
| **`libupac-rpm.so`** | `.rpm` | Fedora, RHEL, openSUSE, etc. |
| **`libupac-deb.so`** | `.deb` | Debian, Ubuntu, etc. |
| **`libupac_decoder_alpm.so`** | `.pkg.tar.zst`, `.pkg.tar.xz`, `.pkg.tar.gz` | Arch Linux, Manjaro, etc. |
| **`libupac_decoder_deb.so`** | `.deb` | Debian, Ubuntu, etc. |
| **`libupac_decoder_rpm.so`** | `.rpm` | Fedora, RHEL, openSUSE, etc. |
| **`libupac-xbps.so`** | `.xbps` | Void Linux |

Adding support for a new package format means writing a new decoder `.so` — the core library does not need to change.
Expand All @@ -135,11 +135,14 @@ cargo build --workspace
### Static linking

By default `up` dlopens `libupac.so` at startup, and `upac-lib` in turn dlopens boot-plugin
`.so`s (`booters/{uki,systemd-boot,grub,refind}`) described by on-disk manifests — this is the
`dynamic-plugins` feature, on by default on both `upac-cli` and `upac-lib`.
`.so`s (`booters/{uki,systemd-boot,grub,refind}`) and decoder `.so`s (`decoders/{alpm,deb}`, the
two currently written in Rust) described by on-disk manifests — this is the `dynamic-plugins`
feature, on by default on both `upac-cli` and `upac-lib`.

Each crate also has a `static-link`/`builtin-*` axis for producing self-contained binaries with
no dlopen at all:
no dlopen at all — `builtin-uki`/`builtin-systemd-boot`/`builtin-grub`/`builtin-refind` (bundled
as `builtin-all`) for boot plugins, `builtin-alpm`/`builtin-deb`/`builtin-rpm` for decoders (no
bundle yet, only three decoders are Rust so far):

```sh
# libupac.so with uki+systemd-boot+grub compiled in, `up` still dlopens it
Expand All @@ -160,13 +163,21 @@ cargo hack build -p upac-cli -p upac-lib --feature-powerset \
--at-least-one-of dynamic-plugins,static-link
```

Decoder static linking (the Zig side) isn't implemented yet — `builtin-decoders` exists as a
placeholder feature on `upac-lib` only.
Decoder static linking for the remaining Zig decoder (`xbps`) isn't implemented — `builtin-decoders`
still works, just without an `xbps` counterpart until it's rewritten in Rust.

### Build a decoder

`alpm`/`deb`/`rpm` are normal Rust workspace members, built along with everything else:

```sh
cargo build -p alpm -p deb -p rpm
```

`xbps` is still Zig:

```sh
cd decoders/alpm
cd decoders/xbps
zig build
```

Expand Down
18 changes: 12 additions & 6 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Upac was originally OSTree-based. The project is migrated to composefs-backed at
the read-only surface (`unmutated/`) and the composefs/database layers are done and tested.

**Every mutating command's entire pipeline is real end-to-end** — install/update/uninstall/rollback/commit/files/gc all have genuine `transaction`/`merge`/`checkout`/`swap` bodies (no
`todo!()` anywhere in `lib/lib/src`), including the boot-plugin subsystem (pluggable UKI/systemd-boot/grub/rEFInd one-shot reboot selection), the real §5.1 3-way `/etc` merge with `.upac-new` conflict handling, and deploy retention/pinning. Package unpacking itself (`upac-lib`'s own decoder-plugin invocation, checksum, output-dir bookkeeping) is done (`PackageUnpacker` in `lib/lib/src/plugin/decoder/unpack.rs`), wired into both install's and update's `PreparationStage`.
`todo!()` anywhere in `lib/lib/src`), including the boot-plugin subsystem (pluggable UKI/systemd-boot/grub/rEFInd one-shot reboot selection), the real §5.1 3-way `/etc` merge with `.upac-new` conflict handling, and deploy retention/pinning. Package unpacking itself (`upac-lib`'s own decoder-plugin invocation, checksum, output-dir bookkeeping) is done (`PackageUnpacker` in `lib/lib/src/plugin/decoder/unpack.rs`), wired into both install's and update's `PreparationStage`. **Declarative (package-format-native) triggers are also fully wired**: `PackageUnpacker` carries each decoded package's `DeclarativeTrigger{format, triggers}` through `Context` as its own key (separate from `PackageTemp`, so `TransactionStage`'s `context.take::<Vec<PackageTemp>>()` doesn't remove it), install/update persist it into the new `packages_triggers` database table (`database::triggers`, keyed by the package's `Uuid`) alongside `PackageMeta`, uninstall reads it back from there (no re-`decode()`), and `HookStage` — via a new `Timing::Declarative` position on `PipelineTrigger`, firing right before each command's Post hooks — matches the stored trigger names against `build_trigger_table()`'s per-format table and runs whatever hooks matched.

What's still explicitly out of scope for this phase, tracked separately below: network-based
package fetching (§6) and the first-boot bootstrap installer (§5).
Expand All @@ -39,13 +39,19 @@ resolution, etc. all live in `upac-lib`).

`upac-lib`'s own paths are still baked in at build time via `lib.toml`. Separately, a genuine *runtime* config now exists: `upac_types::settings::RuntimeSettings` reads a shared `/etc/upac.d/upac.toml` (currently `[gc] retention_depth` and `[progress]` indicatif templates), parsed independently by both `upac-lib` and `upac-cli` (both link `upac_types` directly) — best-effort, missing/malformed file falls back to defaults.

## 4. Decoders (Zig, `decoders/`) — **in progress**.
## 4. Decoders (`decoders/`) — **in progress**.

Per-format decoder shared libraries (deb/rpm/alpm/xbps) exist with real backend logic; see `decoders/*/` and the README's Decoders section for the current contract (`package_path` + `output_dir` + SHA-256 checksum in, `PackageMeta` + dependencies out). Remaining work, not near-term:
Per-format decoder shared libraries (alpm/deb/rpm/xbps) exist with real backend logic; see `decoders/*/` and the README's Decoders section for the current contract (`package_path` + `output_dir` + SHA-256 checksum in, `PackageMeta` + dependencies + declarative triggers out).

- **Packaging pipeline.** Decoder manifest TOML files exist for all 4 decoders
(`decoders/{alpm,deb,rpm,xbps}/upac-*.toml`), but there's no PKGBUILD/spec/etc packaging, Mime types for alpm/xbps (`application/x-alpm-package`/`application/x-xbps-package`) are unofficial and vendor-prefixed (no shared-mime-info registration exists for either format, unlike deb/rpm). `up mime sync` is the mechanism meant to populate desktop integration once decoders are actually installed if any problems arise with automatic updating—not written yet either.
- **Full rewrite to Rust.** The 4 decoders are considered legacy: static linking was never started (separate mechanism from the Rust boot plugins' Cargo-feature approach — no Zig-side equivalent designed), and `parseVersion`/`CVersion` still populate the pre-`Ver`-brick 4-field shape, out of sync with the simplified Rust/C-ABI `{epoch, raw}`. Rather than reconciling that drift in Zig, the plan is a full rewrite of the decoders in Rust later — do not invest in fixing/extending the Zig side in the meantime.
**`alpm`, `deb` and `rpm` are done and rewritten in Rust** (`decoders/{alpm,deb,rpm}`, packages `alpm`/`deb`/`rpm`, `[lib] name = "upac_decoder_{alpm,deb,rpm}"` — decoder-before-format naming) — `xbps` is still the legacy Zig implementation and hasn't started its rewrite. `alpm`'s pipeline is `verify` (SHA-256) → `extract` (tar + gzip/xz/zstd, reads `.PKGINFO`/`.INSTALL` into memory) → `pkginfo::PkgInfo::parse` (`PackageMeta` + `Vec<Dependency>`) → `triggers::scan` (declarative trigger function names, matched against the shared `upac_types::DecoderTrigger` enum — `PreInstall`/`PostInstall`/`PreUpgrade`/`PostUpgrade`/`PreRemove`/`PostRemove`, the same 6-point set every Rust decoder maps its own native function/scriptlet names onto) — 12 tests (`decoders/alpm/tests/{pkginfo,triggers}.rs`; caught and fixed a real bug where a declarative-trigger name appearing as an indented call inside another function's body was misdetected as a top-level declaration). `deb`'s pipeline is `verify` (SHA-256) → `extract` (outer `ar` archive + nested `control.tar.*`/`data.tar.*`, gzip/xz/zstd) → `control::ControlFile::parse` (Debian control file `Key: value` fields + `Depends:` parsing — comma-separated AND groups, `|` OR-groups resolved by taking the first alternative) → `triggers::scan` (presence of the 4 maintainer-script files `preinst`/`postinst`/`prerm`/`postrm` — since dpkg has no separate install-vs-upgrade script, each file maps to two `DecoderTrigger` positions) — 11 tests (`decoders/deb/tests/{control,triggers}.rs`); license text is pulled from the payload's `usr/share/doc/*/copyright` DEP-5 file. `rpm`'s pipeline is `verify` (SHA-256) → `header::read` (own hand-rolled binary parser, generic over `Read + Seek`: skips the 96-byte lead, skips the signature section incl. its 8-byte alignment padding, reads the main header's tag index + data store) → `extract` (payload is `cpio` newc/crc format, not tar — dispatched by the header's own `PayloadFormat`/`PayloadCompressor` tags, gzip/xz/zstd, with a path-traversal guard hand-rolled since there's no `tar`-crate-style built-in protection for `cpio` entries) → `meta::build` (`PackageMeta` + `Vec<Dependency>` — `Requires*` array tags mapped via RPM's own `RPMSENSE_{LESS,GREATER,EQUAL}` bits to `CONSTRAINT_*`, `rpmlib()`-internal pseudo-dependencies filtered out) → `triggers::scan` (presence of the 4 scriptlet tags `%pre`/`%post`/`%preun`/`%postun` — same file-has-no-install-vs-upgrade-split reasoning as `deb`'s maintainer scripts) — 13 tests (`decoders/rpm/tests/{meta,triggers}.rs`, built against synthetic in-memory RPM header byte blobs, no real `.rpm` fixture file needed). Format-specific constants (archive entry names, `.PKGINFO`/control field keys, RPM header tag IDs, lifecycle script/function/scriptlet names) live in a shared `decoders/decoder.toml`, generated per-decoder-crate via `build.rs` — same pattern as `booters/booter.toml`, except each crate's `build.rs` now only reads its **own** section (`[alpm]`/`[deb]`/`[rpm]`/`[xbps]`) rather than generating a module for every section in the shared file. The dependency-version-constraint longest-prefix-match logic (`<=`/`>=`/etc. → `CONSTRAINT_*` bitflags) is shared as `upac_abi::decoder::parse_constraint_prefix`, with each decoder supplying its own operator table (syntax differs per format — alpm has bare `<`/`>`, deb only has `<<`/`>>`); `rpm` doesn't use this at all — its own `REQUIREFLAGS` tag is already a clean bitflag, no string parsing needed.

All three Rust decoders can also be **statically linked** into `upac-lib`, mirroring the boot-plugin `builtin-*` Cargo-feature mechanism but adapted for extension-based dispatch (a decoder is selected by the package file's extension, not a runtime `probe()` call): `builtin-alpm`/`builtin-deb`/`builtin-rpm` features (`dep:upac-decoders-{alpm,deb,rpm}` + shared `builtin-decoders` gate) compile the decoder in as an `rlib`, with `format`/`extensions` also compiled in as constants (generated from each crate's own `upac-{alpm,deb,rpm}.toml` manifest via `build.rs`) — a `builtin-decoders`-only build touches no `/etc/upac.d/decoders/*.toml` manifest on disk at all. See `lib/lib/src/plugin/decoder/mod.rs`'s `static_decoders()`.

Remaining work, not near-term:

- **Packaging pipeline.** Decoder manifest TOML files exist for all 4 decoders
(`decoders/{alpm,deb,rpm,xbps}/upac-*.toml`), but there's no PKGBUILD/spec/etc packaging, Mime types for alpm/xbps (`application/x-alpm-package`/`application/x-xbps-package`) are unofficial and vendor-prefixed (no shared-mime-info registration exists for either format, unlike deb/rpm). `up mime sync` (populates desktop/mime-type integration from installed decoder manifests) is already fully implemented — see §1 — this item is just "no decoder is actually packaged/installed yet for it to sync against."
- **Full rewrite to Rust, `xbps` remaining.** Still legacy Zig: static linking was never started for it (no Zig-side equivalent of the Cargo-feature `builtin-*` mechanism), and its `parseVersion`/`CVersion` still populate the pre-`Ver`-brick 4-field shape, out of sync with the simplified Rust/C-ABI `{epoch, raw}`. Rather than reconciling that drift in Zig, the plan (per `alpm`/`deb`/`rpm`'s own precedent) is a full rewrite in Rust — do not invest in fixing/extending the Zig side in the meantime. Once rewritten, its `.so` output will be underscore-named (`libupac_decoder_xbps.so`, standard Rust `cdylib` naming) rather than the current hyphenated `libupac-xbps.so` — a cosmetic-only mismatch within the decoder family until a packaging step renames the artifact, not a functional issue.

## 5. Bootstrap / installer concerns — **done**.

Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Near-term, concrete items. See `ROADMAP.md` for the bigger picture.
- `user/upac-cli/data/` (`.desktop`, `upac-mime.xml`, `.policy`) reference `Icon=upac`/`icon_name=upac`,
but there's no actual icon asset (SVG/PNG) yet, and no install step wiring it into
`/usr/share/icons/hicolor/...`. Needs real artwork before packaging.

2 changes: 1 addition & 1 deletion booters/booter.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2026 JustPav
# SPDX-FileCopyrightText: 2026 SmoothTeam
#
# SPDX-License-Identifier: LGPL-3.0-or-later
# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception

# Shared source of truth for external protocol constants used by more than one boot plugin —
# none of this is upac's own ABI, so it doesn't belong in any single plugin crate. Each plugin's
Expand Down
14 changes: 12 additions & 2 deletions booters/grub/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
# SPDX-FileCopyrightText: 2026 JustPav
# SPDX-FileCopyrightText: 2026 SmoothTeam
#
# SPDX-License-Identifier: LGPL-3.0-or-later
# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception

[package]
name = "upac-grub"
description = "GRUB (BLS via blscfg) boot plugin for upac: one-shot/persistent reboot selection via grub-reboot/grub-set-default"
version.workspace = true

edition.workspace = true
repository.workspace = true
rust-version.workspace = true

license.workspace = true

readme.workspace = true
homepage.workspace = true
repository.workspace = true

keywords.workspace = true
categories.workspace = true

[lints]
workspace = true

Expand Down
2 changes: 1 addition & 1 deletion booters/grub/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 JustPav
// SPDX-FileCopyrightText: 2026 SmoothTeam
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception

use std::env::var;
use std::error::Error;
Expand Down
2 changes: 1 addition & 1 deletion booters/grub/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2026 JustPav
// SPDX-FileCopyrightText: 2026 SmoothTeam
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception

use std::io::ErrorKind as IoErrorKind;
use std::path::Path;
Expand Down
Loading
Loading