chore: stage remaining scaffolding
This commit is contained in:
parent
5a8823fddb
commit
231af23d1c
14 changed files with 895 additions and 1 deletions
36
Makefile.toml
Normal file
36
Makefile.toml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
[tasks.format]
|
||||||
|
description = "Format Rust code using rustfmt"
|
||||||
|
install_crate = "rustfmt"
|
||||||
|
command = "cargo"
|
||||||
|
args = ["fmt", "--", "--emit=files"]
|
||||||
|
|
||||||
|
[tasks.clean]
|
||||||
|
description = "Clean build artifacts"
|
||||||
|
command = "cargo"
|
||||||
|
args = ["clean"]
|
||||||
|
|
||||||
|
[tasks.build]
|
||||||
|
description = "Build the project"
|
||||||
|
command = "cargo"
|
||||||
|
args = ["build"]
|
||||||
|
dependencies = ["clean"]
|
||||||
|
|
||||||
|
[tasks.test]
|
||||||
|
description = "Run tests"
|
||||||
|
command = "cargo"
|
||||||
|
args = ["test"]
|
||||||
|
dependencies = ["clean"]
|
||||||
|
|
||||||
|
[tasks.my-flow]
|
||||||
|
description = "Run full workflow: format, build, test"
|
||||||
|
dependencies = ["format", "build", "test"]
|
||||||
|
|
||||||
|
[tasks.dev-flow]
|
||||||
|
description = "Full developer workflow: format, lint, build, test"
|
||||||
|
dependencies = ["format", "clippy", "build", "test"]
|
||||||
|
|
||||||
|
[tasks.release-build]
|
||||||
|
description = "Build the project in release mode"
|
||||||
|
command = "cargo"
|
||||||
|
args = ["build", "--release", "--all-features"]
|
||||||
|
dependencies = ["clean"]
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"generated_at": "2025-10-01T07:30:15.338392+00:00",
|
"generated_at": "2025-10-01T12:09:20.934066+00:00",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"book": "mlfs",
|
"book": "mlfs",
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
"path": "packages/mlfs/linux-headers.json",
|
"path": "packages/mlfs/linux-headers.json",
|
||||||
"stage": "cross-toolchain",
|
"stage": "cross-toolchain",
|
||||||
"status": "draft",
|
"status": "draft",
|
||||||
|
"tags": [],
|
||||||
"variant": null,
|
"variant": null,
|
||||||
"version": "6.16.9 API Headers"
|
"version": "6.16.9 API Headers"
|
||||||
},
|
},
|
||||||
|
|
@ -18,6 +19,7 @@
|
||||||
"path": "packages/mlfs/glibc.json",
|
"path": "packages/mlfs/glibc.json",
|
||||||
"stage": "cross-toolchain",
|
"stage": "cross-toolchain",
|
||||||
"status": "draft",
|
"status": "draft",
|
||||||
|
"tags": [],
|
||||||
"variant": null,
|
"variant": null,
|
||||||
"version": "2.42"
|
"version": "2.42"
|
||||||
},
|
},
|
||||||
|
|
@ -28,6 +30,7 @@
|
||||||
"path": "packages/mlfs/binutils-pass-1.json",
|
"path": "packages/mlfs/binutils-pass-1.json",
|
||||||
"stage": "cross-toolchain",
|
"stage": "cross-toolchain",
|
||||||
"status": "draft",
|
"status": "draft",
|
||||||
|
"tags": [],
|
||||||
"variant": "Pass 1",
|
"variant": "Pass 1",
|
||||||
"version": "2.45"
|
"version": "2.45"
|
||||||
},
|
},
|
||||||
|
|
@ -38,6 +41,7 @@
|
||||||
"path": "packages/mlfs/gcc-pass-1.json",
|
"path": "packages/mlfs/gcc-pass-1.json",
|
||||||
"stage": "cross-toolchain",
|
"stage": "cross-toolchain",
|
||||||
"status": "draft",
|
"status": "draft",
|
||||||
|
"tags": [],
|
||||||
"variant": "Pass 1",
|
"variant": "Pass 1",
|
||||||
"version": "15.2.0"
|
"version": "15.2.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
build.rs
Normal file
1
build.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
fn main() {}
|
||||||
91
concepts/nixette/README.md
Normal file
91
concepts/nixette/README.md
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
# Nixette – Declarative, Sourceful, and Unapologetically Herself
|
||||||
|
|
||||||
|
A playful concept distro imagined as the transfemme child of **NixOS** and **Gentoo**. Nixette blends the reproducible confidence of flakes with the fine-grained self-expression of USE flags, wrapped in a trans flag palette and a big, affirming hug.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Identity Snapshot
|
||||||
|
|
||||||
|
- **Tagline:** _Declarative, sourceful, and unapologetically herself._
|
||||||
|
- **Mascot:** Chibi penguin “Nixie” with pastel pigtails, Nix snowflake + Gentoo swirl hoodie.
|
||||||
|
- **Palette:** `#55CDFC` (sky blue), `#F7A8B8` (pink), `#FFFFFF`, plus a deep accent `#7C3AED`.
|
||||||
|
- **Pronoun Prompt:** The installer asks for name/pronouns and personalises MOTD, systemd messages, and shell prompt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Feature Mix
|
||||||
|
|
||||||
|
| Pillar | How Nixette expresses it |
|
||||||
|
|----------------------|-----------------------------------------------------------------------------------------------------------|
|
||||||
|
| Reproducibility | Flake-native system definitions with versioned profiles (`comfort-zone`, `diy-princess`, `studio-mode`). |
|
||||||
|
| Custom compilation | `nix emerge` bridge turns Gentoo ebuild overlays into reproducible derivations with cached binaries. |
|
||||||
|
| Playful polish | Catppuccin-trans themes, `nixette-style` CLI to sync GTK/Qt/terminal styling, dynamic welcome affirmations.|
|
||||||
|
| Inclusive defaults | Flatpak + Steam pre-set for accessibility tools, Fcitx5, Orca, speech-dispatcher, pronoun-friendly docs. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Toolchain Concepts
|
||||||
|
|
||||||
|
- **`trans-init` installer** – Guided TUI that outputs `flake.nix`, including overlays for the `nix emerge` bridge. Provides story-mode narration for first boot.
|
||||||
|
- **`nixette-style`** – Syncs wallpapers, SDDM theme, terminal palette, Qt/KDE settings, all sourced from a YAML theme pack.
|
||||||
|
- **`emerge-optional`** – Spins up Gentoo chroots inside Nix build sandboxes for packages happiest as ebuilds. Output is cached as a Nix store derivation.
|
||||||
|
- **`affirm-d`** – Small daemon rotating `/etc/motd`, desktop notifications, and TTY colour accents with inclusive affirmations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Profile Catalogue
|
||||||
|
|
||||||
|
| Profile | Intent |
|
||||||
|
|-----------------|---------------------------------------------------------------------------------------------|
|
||||||
|
| Comfort Zone | KDE Plasma, PipeWire, Wayland, cozy defaults, automatic Catgirl cursor + emoji fonts. |
|
||||||
|
| DIY Princess | Minimal sway-based stack, just the flake scaffolding and overlay hooks for custom builds. |
|
||||||
|
| Studio Mode | Focuses on creative tooling (Krita, Blender, Ardour) and low-latency kernels, GPU tuning. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap Sketch
|
||||||
|
|
||||||
|
1. **Moodboard → Brand Pack** (logo, icon, wallpapers, VT boot splash).
|
||||||
|
2. **Prototype flakes** – `nix flake init --template nixette#comfort-zone` etc.
|
||||||
|
3. **Gentoo overlay bridge** – Validate `nix emerge` on a handful of ebuilds (mesa, wine, gamescope).
|
||||||
|
4. **Installer draft** – BubbleTea/ratatui-driven TUI, prompts for pronouns + accessibility preferences.
|
||||||
|
5. **Community docs** – Write inclusive user guide, contributor covenant, pronoun style guide.
|
||||||
|
6. **Launch zine** – Release notes styled like a mini-comic introducing Nixie’s origin story.
|
||||||
|
7. **Accessibility audit** – Keyboard navigation, screen-reader pass, dyslexia-friendly typography options.
|
||||||
|
8. **Beta cosy jam** – Invite testers via queer sysadmin spaces; collect feedback through anonymous forms.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Affirmations YAML (snippet)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- id: bright-morning
|
||||||
|
message: "Good morning, {name}! Your system is as valid and custom as you are."
|
||||||
|
colour: "#F7A8B8"
|
||||||
|
- id: compile-hugs
|
||||||
|
message: "Kernel rebuilds take time. You deserve rest breaks and gentle music."
|
||||||
|
colour: "#55CDFC"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Logo & Wallpaper
|
||||||
|
|
||||||
|
See `assets/nixette-logo.svg` for the primary wordmark, `assets/nixette-mascot.svg` for Nixie’s badge, and `assets/nixette-wallpaper.svg` for a 4K wallpaper concept.
|
||||||
|
|
||||||
|
### Reference Configs
|
||||||
|
|
||||||
|
- `concepts/nixette/sample_flake.nix` demonstrates the comfort-zone profile with `nix emerge`, `affirmd`, and theming hooks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contributing Idea Seeds
|
||||||
|
|
||||||
|
- Write sample flakes showcasing the hybrid build pipeline.
|
||||||
|
- Mock up the mascot in SVG for use in documentation.
|
||||||
|
- Design additional wallpapers (night mode, pride variants, low-light).
|
||||||
|
- Draft inclusive documentation templates (issue/PR forms, community guidelines).
|
||||||
|
- Publish a community pledge emphasising safety, pronoun respect, and boundaries.
|
||||||
|
- Host monthly "compile & chill" streams to showcase contributions.
|
||||||
|
|
||||||
|
Let Nixette be the distro that compiles joy, not just binaries. 💜
|
||||||
62
concepts/nixette/sample_flake.nix
Normal file
62
concepts/nixette/sample_flake.nix
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
description = "Nixette comfort-zone profile";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
nixette-overlays.url = "github:nixette/overlays";
|
||||||
|
nixette-style.url = "github:nixette/style-pack";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, nixette-overlays, nixette-style, ... }@inputs:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
overlays = [ nixette-overlays.overlays.nix-emerge ];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixosConfigurations.nixette-comfort-zone = nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
modules = [
|
||||||
|
./profiles/comfort-zone.nix
|
||||||
|
({ config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
nixette-style
|
||||||
|
steam
|
||||||
|
lutris
|
||||||
|
krita
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nixette.nix-emerge = {
|
||||||
|
enable = true;
|
||||||
|
ebuilds = [
|
||||||
|
"games-emulation/gamescope"
|
||||||
|
"media-sound/pipewire"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nixette.affirmd.enable = true;
|
||||||
|
services.nixette.affirmd.pronouns = "she/her";
|
||||||
|
services.nixette.affirmd.motdPath = ./affirmations.yml;
|
||||||
|
|
||||||
|
programs.plasma.enable = true;
|
||||||
|
services.displayManager.sddm.enable = true;
|
||||||
|
services.displayManager.sddm.theme = nixette-style.themes.catgirl-sunrise;
|
||||||
|
|
||||||
|
users.users.nixie = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [ "wheel" "audio" "input" "video" ];
|
||||||
|
shell = pkgs.zsh;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zsh.promptInit = ''
|
||||||
|
eval "$(nixette-style prompt --name nixie --pronouns she/her)"
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
97
md5sums
Normal file
97
md5sums
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
590765dee95907dbc3c856f7255bd669 acl-2.3.2.tar.xz
|
||||||
|
227043ec2f6ca03c0948df5517f9c927 attr-2.5.2.tar.gz
|
||||||
|
1be79f7106ab6767f18391c5e22be701 autoconf-2.72.tar.xz
|
||||||
|
cea31dbf1120f890cbf2a3032cfb9a68 automake-1.18.1.tar.xz
|
||||||
|
977c8c0c5ae6309191e7768e28ebc951 bash-5.3.tar.gz
|
||||||
|
ad4db5a0eb4fdbb3f6813be4b6b3da74 bc-7.0.3.tar.xz
|
||||||
|
dee5b4267e0305a99a3c9d6131f45759 binutils-2.45.tar.xz
|
||||||
|
c28f119f405a2304ff0a7ccdcc629713 bison-3.8.2.tar.xz
|
||||||
|
67e051268d0c475ea773822f7500d0e5 bzip2-1.0.8.tar.gz
|
||||||
|
b2e687b6e664b9dd76581836c5c3e782 coreutils-9.8.tar.xz
|
||||||
|
68c5208c58236eba447d7d6d1326b821 dejagnu-1.6.3.tar.gz
|
||||||
|
d1b18b20868fb561f77861cd90b05de4 diffutils-3.12.tar.xz
|
||||||
|
113d7a7ee0710d2a670a44692a35fd2e e2fsprogs-1.47.3.tar.gz
|
||||||
|
ceefa052ded950a4c523688799193a44 elfutils-0.193.tar.bz2
|
||||||
|
423975a2a775ff32f12c53635b463a91 expat-2.7.3.tar.xz
|
||||||
|
00fce8de158422f5ccd2666512329bd2 expect5.45.4.tar.gz
|
||||||
|
459da2d4b534801e2e2861611d823864 file-5.46.tar.gz
|
||||||
|
870cfd71c07d37ebe56f9f4aaf4ad872 findutils-4.10.0.tar.xz
|
||||||
|
2882e3179748cc9f9c23ec593d6adc8d flex-2.6.4.tar.gz
|
||||||
|
c538415c1f27bd69cbbbf3cdd5135d39 flit_core-3.12.0.tar.gz
|
||||||
|
b7014650c5f45e5d4837c31209dc0037 gawk-5.3.2.tar.xz
|
||||||
|
b861b092bf1af683c46a8aa2e689a6fd gcc-15.2.0.tar.xz
|
||||||
|
aaa600665bc89e2febb3c7bd90679115 gdbm-1.26.tar.gz
|
||||||
|
8e14e926f088e292f5f2bce95b81d10e gettext-0.26.tar.xz
|
||||||
|
23c6f5a27932b435cae94e087cb8b1f5 glibc-2.42.tar.xz
|
||||||
|
956dc04e864001a9c22429f761f2c283 gmp-6.3.0.tar.xz
|
||||||
|
31753b021ea78a21f154bf9eecb8b079 gperf-3.3.tar.gz
|
||||||
|
5d9301ed9d209c4a88c8d3a6fd08b9ac grep-3.12.tar.xz
|
||||||
|
5e4f40315a22bb8a158748e7d5094c7d groff-1.23.0.tar.gz
|
||||||
|
60c564b1bdc39d8e43b3aab4bc0fb140 grub-2.12.tar.xz
|
||||||
|
4bf5a10f287501ee8e8ebe00ef62b2c2 gzip-1.14.tar.xz
|
||||||
|
437a3e9f4a420244c90db4ab20e713b6 iana-etc-20250926.tar.gz
|
||||||
|
401d7d07682a193960bcdecafd03de94 inetutils-2.6.tar.xz
|
||||||
|
12e517cac2b57a0121cda351570f1e63 intltool-0.51.0.tar.gz
|
||||||
|
80e1f91bf59d572acc15d5c6eb4f3e7c iproute2-6.16.0.tar.xz
|
||||||
|
11ee9d335b227ea2e8579c4ba6e56138 isl-0.27.tar.xz
|
||||||
|
66d4c25ff43d1deaf9637ccda523dec8 jinja2-3.1.6.tar.gz
|
||||||
|
7be7c6f658f5fb9512e2c490349a8eeb kbd-2.9.0.tar.xz
|
||||||
|
36f2cc483745e81ede3406fa55e1065a kmod-34.2.tar.xz
|
||||||
|
0386dc14f6a081a94dfb4c2413864eed less-679.tar.gz
|
||||||
|
2be34eced7c861fea8894e7195dac636 lfs-bootscripts-20250827.tar.xz
|
||||||
|
449ade7d620b5c4eeb15a632fbaa4f74 libcap-2.76.tar.xz
|
||||||
|
92af9efad4ba398995abf44835c5d9e9 libffi-3.5.2.tar.gz
|
||||||
|
17ac6969b2015386bcb5d278a08a40b5 libpipeline-1.5.8.tar.gz
|
||||||
|
22e0a29df8af5fdde276ea3a7d351d30 libtool-2.5.4.tar.xz
|
||||||
|
1796a5d20098e9dd9e3f576803c83000 libxcrypt-4.4.38.tar.xz
|
||||||
|
feb0a3d5ecf5a4628aed7d9f8f7ab3f6 linux-6.16.9.tar.xz
|
||||||
|
dead9f5f1966d9ae56e1e32761e4e675 lz4-1.10.0.tar.gz
|
||||||
|
6eb2ebed5b24e74b6e890919331d2132 m4-1.4.20.tar.xz
|
||||||
|
c8469a3713cbbe04d955d4ae4be23eeb make-4.4.1.tar.gz
|
||||||
|
b6335533cbeac3b24cd7be31fdee8c83 man-db-2.13.1.tar.xz
|
||||||
|
16f68d70139dd2bbcae4102be4705753 man-pages-6.15.tar.xz
|
||||||
|
13a73126d25afa72a1ff0daed072f5fe markupsafe-3.0.3.tar.gz
|
||||||
|
19e0a1091cec23d369dd77d852844195 meson-1.9.1.tar.gz
|
||||||
|
5c9bc658c9fd0f940e8e3e0f09530c62 mpc-1.3.1.tar.gz
|
||||||
|
7c32c39b8b6e3ae85f25156228156061 mpfr-4.2.2.tar.xz
|
||||||
|
679987405412f970561cc85e1e6428a2 ncurses-6.5-20250809.tgz
|
||||||
|
c35f8f55f4cf60f1a916068d8f45a0f8 ninja-1.13.1.tar.gz
|
||||||
|
0ec20faeb96bbb203c8684cc7fe4432e openssl-3.5.3.tar.gz
|
||||||
|
ab0ef21ddebe09d1803575120d3f99f8 packaging-25.0.tar.gz
|
||||||
|
149327a021d41c8f88d034eab41c039f patch-2.8.tar.xz
|
||||||
|
641f99b635ebb9332a9b6a8ce8e2f3cf pcre2-10.46.tar.bz2
|
||||||
|
7a6950a9f12d01eb96a9d2ed2f4e0072 perl-5.42.0.tar.xz
|
||||||
|
3291128c917fdb8fccd8c9e7784b643b pkgconf-2.5.1.tar.xz
|
||||||
|
90803e64f51f192f3325d25c3335d057 procps-ng-4.0.5.tar.xz
|
||||||
|
53eae841735189a896d614cba440eb10 psmisc-23.7.tar.xz
|
||||||
|
256cdb3bbf45cdce7499e52ba6c36ea3 Python-3.13.7.tar.xz
|
||||||
|
b84c0d81b2758398bb7f5b7411d3d908 python-3.13.7-docs-html.tar.bz2
|
||||||
|
25a73bfb2a3ad7146c5e9d4408d9f6cd readline-8.3.tar.gz
|
||||||
|
6aac9b2dbafcd5b7a67a8a9bcb8036c3 sed-4.9.tar.xz
|
||||||
|
82e1d67883b713f9493659b50d13b436 setuptools-80.9.0.tar.gz
|
||||||
|
30ef46f54363db1d624587be68794ef2 shadow-4.18.0.tar.xz
|
||||||
|
d74bbdca4ab1b2bd46d3b3f8dbb0f3db sqlite-autoconf-3500400.tar.gz
|
||||||
|
63a62af5b35913459954e6e66876f2b8 sqlite-doc-3500400.tar.xz
|
||||||
|
af60786956a2dc84054fbf46652e515e sysklogd-2.7.2.tar.gz
|
||||||
|
25fe5d328e22641254761f1baa74cee0 systemd-257.8.tar.gz
|
||||||
|
a44063e2ec0cf4adfd2ed5c9e9e095c5 systemd-man-pages-257.8.tar.xz
|
||||||
|
bc6890b975d19dc9db42d0c7364dd092 sysvinit-3.14.tar.xz
|
||||||
|
a2d8042658cfd8ea939e6d911eaf4152 tar-1.35.tar.xz
|
||||||
|
1ec3444533f54d0f86cd120058e15e48 tcl8.6.17-src.tar.gz
|
||||||
|
60c71044e723b0db5f21be82929f3534 tcl8.6.17-html.tar.gz
|
||||||
|
11939a7624572814912a18e76c8d8972 texinfo-7.2.tar.xz
|
||||||
|
ad65154c48c74a9b311fe84778c5434f tzdata2025b.tar.gz
|
||||||
|
acd4360d8a5c3ef320b9db88d275dae6 udev-lfs-20230818.tar.xz
|
||||||
|
a2a3281ce76821c4bc28794fdf9d3994 util-linux-2.41.2.tar.xz
|
||||||
|
e72f31be182f1ccf4b66bef46ac1e60e vim-9.1.1806.tar.gz
|
||||||
|
65e09ee84af36821e3b1e9564aa91bd5 wheel-0.46.1.tar.gz
|
||||||
|
89a8e82cfd2ad948b349c0a69c494463 XML-Parser-2.47.tar.gz
|
||||||
|
cf5e1feb023d22c6bdaa30e84ef3abe3 xz-5.8.1.tar.xz
|
||||||
|
9855b6d802d7fe5b7bd5b196a2271655 zlib-1.3.1.tar.gz
|
||||||
|
780fc1896922b1bc52a4e90980cdda48 zstd-1.5.7.tar.gz
|
||||||
|
6a5ac7e89b791aae556de0f745916f7f bzip2-1.0.8-install_docs-1.patch
|
||||||
|
c800540039fb0707954197486b1bde70 coreutils-9.8-i18n-2.patch
|
||||||
|
0ca4d6bb8d572fbcdb13cb36cd34833e expect-5.45.4-gcc15-1.patch
|
||||||
|
9a5997c3452909b1769918c759eff8a2 glibc-2.42-fhs-1.patch
|
||||||
|
f75cca16a38da6caa7d52151f7136895 kbd-2.9.0-backspace-1.patch
|
||||||
|
3af8fd8e13cad481eeeaa48be4247445 sysvinit-3.14-consolidated-1.patch
|
||||||
80
src/bin/graphql_server.rs
Normal file
80
src/bin/graphql_server.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#![cfg(feature = "graphql")]
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use actix_web::{App, HttpRequest, HttpResponse, HttpServer, middleware::Compress, web};
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use juniper_actix::{graphiql_handler, graphql_handler};
|
||||||
|
|
||||||
|
use package_management::db;
|
||||||
|
use package_management::graphql::{self, GraphQLContext, Schema};
|
||||||
|
|
||||||
|
const DEFAULT_BIND_ADDR: &str = "127.0.0.1:8080";
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
if let Err(err) = run().await {
|
||||||
|
eprintln!("GraphQL server failed: {err:#}");
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
err.to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run() -> Result<()> {
|
||||||
|
let pool = db::establish_pool().context("initialising SQLite pool")?;
|
||||||
|
let schema = Arc::new(graphql::create_schema());
|
||||||
|
let jokes = Arc::new(graphql::context::JokeCatalog::default());
|
||||||
|
let bind_addr = env::var("LPKG_GRAPHQL_ADDR").unwrap_or_else(|_| DEFAULT_BIND_ADDR.to_string());
|
||||||
|
let workers = worker_count();
|
||||||
|
|
||||||
|
println!("GraphQL server listening on {bind_addr} with {workers} worker(s)");
|
||||||
|
|
||||||
|
HttpServer::new(move || {
|
||||||
|
let app_schema = Arc::clone(&schema);
|
||||||
|
let pool = pool.clone();
|
||||||
|
let jokes = Arc::clone(&jokes);
|
||||||
|
|
||||||
|
App::new()
|
||||||
|
.app_data(web::Data::from(app_schema))
|
||||||
|
.app_data(web::Data::new(pool))
|
||||||
|
.app_data(web::Data::from(jokes))
|
||||||
|
.wrap(Compress::default())
|
||||||
|
.service(
|
||||||
|
web::resource("/graphql")
|
||||||
|
.route(web::post().to(graphql_endpoint))
|
||||||
|
.route(web::get().to(graphql_endpoint)),
|
||||||
|
)
|
||||||
|
.service(web::resource("/playground").route(web::get().to(graphiql_endpoint)))
|
||||||
|
})
|
||||||
|
.workers(workers)
|
||||||
|
.bind(&bind_addr)
|
||||||
|
.with_context(|| format!("binding GraphQL server to {bind_addr}"))?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
.context("running GraphQL server")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn graphql_endpoint(
|
||||||
|
schema: web::Data<Arc<Schema>>,
|
||||||
|
pool: web::Data<db::Pool>,
|
||||||
|
jokes: web::Data<Arc<graphql::context::JokeCatalog>>,
|
||||||
|
req: HttpRequest,
|
||||||
|
payload: web::Payload,
|
||||||
|
) -> Result<HttpResponse, actix_web::Error> {
|
||||||
|
let context = GraphQLContext::with_catalog(pool.get_ref().clone(), Arc::clone(jokes.get_ref()));
|
||||||
|
graphql_handler(schema.get_ref().as_ref(), &context, req, payload).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn graphiql_endpoint() -> Result<HttpResponse, actix_web::Error> {
|
||||||
|
graphiql_handler("/graphql", None).await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn worker_count() -> usize {
|
||||||
|
let suggested = num_cpus::get();
|
||||||
|
suggested.clamp(1, 8)
|
||||||
|
}
|
||||||
138
src/graphql/context.rs
Normal file
138
src/graphql/context.rs
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use rand::rng;
|
||||||
|
use rand::seq::IteratorRandom;
|
||||||
|
|
||||||
|
use crate::db;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct GraphQLContext {
|
||||||
|
pub db_pool: db::Pool,
|
||||||
|
jokes: Arc<JokeCatalog>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GraphQLContext {
|
||||||
|
pub fn new(db_pool: db::Pool) -> Self {
|
||||||
|
Self {
|
||||||
|
db_pool,
|
||||||
|
jokes: Arc::new(JokeCatalog::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_jokes(db_pool: db::Pool, jokes: Vec<Joke>) -> Self {
|
||||||
|
Self {
|
||||||
|
db_pool,
|
||||||
|
jokes: Arc::new(JokeCatalog::new(jokes)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_catalog(db_pool: db::Pool, catalog: Arc<JokeCatalog>) -> Self {
|
||||||
|
Self {
|
||||||
|
db_pool,
|
||||||
|
jokes: catalog,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn joke_catalog(&self) -> Arc<JokeCatalog> {
|
||||||
|
Arc::clone(&self.jokes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl juniper::Context for GraphQLContext {}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Joke {
|
||||||
|
pub id: String,
|
||||||
|
pub package: Option<String>,
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Joke {
|
||||||
|
pub fn new(id: impl Into<String>, package: Option<&str>, text: impl Into<String>) -> Self {
|
||||||
|
Self {
|
||||||
|
id: id.into(),
|
||||||
|
package: package.map(|pkg| pkg.to_string()),
|
||||||
|
text: text.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct JokeCatalog {
|
||||||
|
entries: Arc<Vec<Joke>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JokeCatalog {
|
||||||
|
fn new(entries: Vec<Joke>) -> Self {
|
||||||
|
Self {
|
||||||
|
entries: Arc::new(entries),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random(&self, package: Option<&str>) -> Option<Joke> {
|
||||||
|
let mut rng = rng();
|
||||||
|
|
||||||
|
if let Some(package) = package {
|
||||||
|
if let Some(chosen) = self
|
||||||
|
.entries
|
||||||
|
.iter()
|
||||||
|
.filter(|joke| matches_package(joke, package))
|
||||||
|
.choose(&mut rng)
|
||||||
|
{
|
||||||
|
return Some(chosen.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.entries.iter().choose(&mut rng).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all(&self, package: Option<&str>) -> Vec<Joke> {
|
||||||
|
match package {
|
||||||
|
Some(package) => self
|
||||||
|
.entries
|
||||||
|
.iter()
|
||||||
|
.filter(|joke| matches_package(joke, package))
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
None => self.entries.as_ref().clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for JokeCatalog {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new(default_jokes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn matches_package(joke: &Joke, package: &str) -> bool {
|
||||||
|
joke.package
|
||||||
|
.as_deref()
|
||||||
|
.map(|pkg| pkg.eq_ignore_ascii_case(package))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_jokes() -> Vec<Joke> {
|
||||||
|
vec![
|
||||||
|
Joke::new(
|
||||||
|
"optimizer-overdrive",
|
||||||
|
Some("gcc"),
|
||||||
|
"The GCC optimizer walked into a bar, reordered everyone’s drinks, and they still tasted the same—just faster.",
|
||||||
|
),
|
||||||
|
Joke::new(
|
||||||
|
"linker-chuckle",
|
||||||
|
Some("binutils"),
|
||||||
|
"Our linker refuses to go on vacation; it can’t handle unresolved references to the beach.",
|
||||||
|
),
|
||||||
|
Joke::new(
|
||||||
|
"glibc-giggle",
|
||||||
|
Some("glibc"),
|
||||||
|
"The C library tried stand-up comedy but segfaulted halfway through the punchline.",
|
||||||
|
),
|
||||||
|
Joke::new(
|
||||||
|
"pkg-general",
|
||||||
|
None,
|
||||||
|
"LPKG packages never get lost—they always follow the dependency graph back home.",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
14
src/graphql/mod.rs
Normal file
14
src/graphql/mod.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
pub mod context;
|
||||||
|
pub mod schema;
|
||||||
|
|
||||||
|
pub use context::{GraphQLContext, Joke};
|
||||||
|
pub use schema::QueryRoot;
|
||||||
|
|
||||||
|
use juniper::{EmptyMutation, EmptySubscription, RootNode};
|
||||||
|
|
||||||
|
pub type Schema =
|
||||||
|
RootNode<QueryRoot, EmptyMutation<GraphQLContext>, EmptySubscription<GraphQLContext>>;
|
||||||
|
|
||||||
|
pub fn create_schema() -> Schema {
|
||||||
|
Schema::new(QueryRoot {}, EmptyMutation::new(), EmptySubscription::new())
|
||||||
|
}
|
||||||
133
src/graphql/schema.rs
Normal file
133
src/graphql/schema.rs
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
use anyhow::{Error as AnyhowError, Result as AnyhowResult};
|
||||||
|
use juniper::{FieldResult, GraphQLObject, Value, graphql_object};
|
||||||
|
|
||||||
|
use crate::{db, pkgs::package::PackageDefinition};
|
||||||
|
|
||||||
|
use super::context::{GraphQLContext, Joke};
|
||||||
|
|
||||||
|
#[derive(Clone, GraphQLObject)]
|
||||||
|
#[graphql(description = "Package metadata exposed via the GraphQL API")]
|
||||||
|
pub struct PackageType {
|
||||||
|
pub name: String,
|
||||||
|
pub version: String,
|
||||||
|
pub source: Option<String>,
|
||||||
|
pub md5: Option<String>,
|
||||||
|
pub configure_args: Vec<String>,
|
||||||
|
pub build_commands: Vec<String>,
|
||||||
|
pub install_commands: Vec<String>,
|
||||||
|
pub dependencies: Vec<String>,
|
||||||
|
pub enable_lto: bool,
|
||||||
|
pub enable_pgo: bool,
|
||||||
|
pub cflags: Vec<String>,
|
||||||
|
pub ldflags: Vec<String>,
|
||||||
|
pub profdata: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PackageDefinition> for PackageType {
|
||||||
|
fn from(pkg: PackageDefinition) -> Self {
|
||||||
|
let optimizations = pkg.optimizations;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
name: pkg.name,
|
||||||
|
version: pkg.version,
|
||||||
|
source: pkg.source,
|
||||||
|
md5: pkg.md5,
|
||||||
|
configure_args: pkg.configure_args,
|
||||||
|
build_commands: pkg.build_commands,
|
||||||
|
install_commands: pkg.install_commands,
|
||||||
|
dependencies: pkg.dependencies,
|
||||||
|
enable_lto: optimizations.enable_lto,
|
||||||
|
enable_pgo: optimizations.enable_pgo,
|
||||||
|
cflags: optimizations.cflags,
|
||||||
|
ldflags: optimizations.ldflags,
|
||||||
|
profdata: optimizations.profdata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, GraphQLObject)]
|
||||||
|
#[graphql(description = "A light-hearted package-related joke")]
|
||||||
|
pub struct JokeType {
|
||||||
|
pub id: String,
|
||||||
|
pub package: Option<String>,
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Joke> for JokeType {
|
||||||
|
fn from(joke: Joke) -> Self {
|
||||||
|
Self {
|
||||||
|
id: joke.id,
|
||||||
|
package: joke.package,
|
||||||
|
text: joke.text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct QueryRoot;
|
||||||
|
|
||||||
|
#[graphql_object(context = GraphQLContext)]
|
||||||
|
impl QueryRoot {
|
||||||
|
fn packages(context: &GraphQLContext, limit: Option<i32>) -> FieldResult<Vec<PackageType>> {
|
||||||
|
let limit = limit.unwrap_or(50).clamp(1, 200) as usize;
|
||||||
|
let definitions =
|
||||||
|
db::load_package_definitions_via_pool(&context.db_pool).map_err(field_error)?;
|
||||||
|
|
||||||
|
Ok(definitions
|
||||||
|
.into_iter()
|
||||||
|
.take(limit)
|
||||||
|
.map(PackageType::from)
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn package(
|
||||||
|
context: &GraphQLContext,
|
||||||
|
name: String,
|
||||||
|
version: Option<String>,
|
||||||
|
) -> FieldResult<Option<PackageType>> {
|
||||||
|
let definition =
|
||||||
|
db::find_package_definition_via_pool(&context.db_pool, &name, version.as_deref())
|
||||||
|
.map_err(field_error)?;
|
||||||
|
|
||||||
|
Ok(definition.map(PackageType::from))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search(
|
||||||
|
context: &GraphQLContext,
|
||||||
|
query: String,
|
||||||
|
limit: Option<i32>,
|
||||||
|
) -> FieldResult<Vec<PackageType>> {
|
||||||
|
let limit = limit.map(|value| i64::from(value.clamp(1, 200)));
|
||||||
|
let results =
|
||||||
|
db::search_packages_via_pool(&context.db_pool, &query, limit).map_err(field_error)?;
|
||||||
|
|
||||||
|
let packages = results
|
||||||
|
.into_iter()
|
||||||
|
.map(|pkg| pkg.into_definition().map(PackageType::from))
|
||||||
|
.collect::<AnyhowResult<Vec<_>>>()
|
||||||
|
.map_err(field_error)?;
|
||||||
|
|
||||||
|
Ok(packages)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn jokes(context: &GraphQLContext, package: Option<String>) -> FieldResult<Vec<JokeType>> {
|
||||||
|
let catalog = context.joke_catalog();
|
||||||
|
Ok(catalog
|
||||||
|
.all(package.as_deref())
|
||||||
|
.into_iter()
|
||||||
|
.map(JokeType::from)
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_joke(
|
||||||
|
context: &GraphQLContext,
|
||||||
|
package: Option<String>,
|
||||||
|
) -> FieldResult<Option<JokeType>> {
|
||||||
|
let catalog = context.joke_catalog();
|
||||||
|
Ok(catalog.random(package.as_deref()).map(JokeType::from))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn field_error(err: AnyhowError) -> juniper::FieldError {
|
||||||
|
juniper::FieldError::new(err.to_string(), Value::null())
|
||||||
|
}
|
||||||
80
src/tui/animations/donut.rs
Normal file
80
src/tui/animations/donut.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
use rsille::canvas::Canvas;
|
||||||
|
use super::Animation;
|
||||||
|
|
||||||
|
const THETA_SPACING: f64 = 0.07;
|
||||||
|
const PHI_SPACING: f64 = 0.02;
|
||||||
|
|
||||||
|
pub struct DonutAnimation {
|
||||||
|
a: f64, // rotation around X
|
||||||
|
b: f64, // rotation around Z
|
||||||
|
size: (u16, u16),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DonutAnimation {
|
||||||
|
pub fn new(width: u16, height: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
a: 0.0,
|
||||||
|
b: 0.0,
|
||||||
|
size: (width, height),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for DonutAnimation {
|
||||||
|
fn update(&mut self, delta: Duration) {
|
||||||
|
let delta_secs = delta.as_secs_f64();
|
||||||
|
self.a += delta_secs;
|
||||||
|
self.b += delta_secs * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, canvas: &mut Canvas) {
|
||||||
|
let (width, height) = self.size;
|
||||||
|
let (width_f, height_f) = (width as f64, height as f64);
|
||||||
|
let k2 = 5.0;
|
||||||
|
let k1 = width_f * k2 * 3.0 / (8.0 * (height_f + width_f));
|
||||||
|
|
||||||
|
for theta in 0..((2.0 * std::f64::consts::PI / THETA_SPACING) as i32) {
|
||||||
|
let theta_f = theta as f64 * THETA_SPACING;
|
||||||
|
let cos_theta = theta_f.cos();
|
||||||
|
let sin_theta = theta_f.sin();
|
||||||
|
|
||||||
|
for phi in 0..((2.0 * std::f64::consts::PI / PHI_SPACING) as i32) {
|
||||||
|
let phi_f = phi as f64 * PHI_SPACING;
|
||||||
|
let cos_phi = phi_f.cos();
|
||||||
|
let sin_phi = phi_f.sin();
|
||||||
|
|
||||||
|
let cos_a = self.a.cos();
|
||||||
|
let sin_a = self.a.sin();
|
||||||
|
let cos_b = self.b.cos();
|
||||||
|
let sin_b = self.b.sin();
|
||||||
|
|
||||||
|
let h = cos_theta + 2.0;
|
||||||
|
let d = 1.0 / (sin_phi * h * sin_a + sin_theta * cos_a + 5.0);
|
||||||
|
let t = sin_phi * h * cos_a - sin_theta * sin_a;
|
||||||
|
|
||||||
|
let x = (width_f / 2.0 + 30.0 * d * (cos_phi * h * cos_b - t * sin_b)) as i32;
|
||||||
|
let y = (height_f / 2.0 + 15.0 * d * (cos_phi * h * sin_b + t * cos_b)) as i32;
|
||||||
|
let z = (1.0 / d) as u8;
|
||||||
|
|
||||||
|
if x >= 0 && x < width as i32 && y >= 0 && y < height as i32 {
|
||||||
|
let luminance = if z > 0 { z } else { 1 };
|
||||||
|
let c = match luminance {
|
||||||
|
0..=31 => '.',
|
||||||
|
32..=63 => '*',
|
||||||
|
64..=95 => 'o',
|
||||||
|
96..=127 => '&',
|
||||||
|
128..=159 => '8',
|
||||||
|
160..=191 => '#',
|
||||||
|
_ => '@',
|
||||||
|
};
|
||||||
|
canvas.put_char(x as u16, y as u16, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_finished(&self) -> bool {
|
||||||
|
false // continuous animation
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/tui/animations/mod.rs
Normal file
13
src/tui/animations/mod.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
use rsille::canvas::Canvas;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
pub trait Animation {
|
||||||
|
fn update(&mut self, delta: Duration);
|
||||||
|
fn render(&self, canvas: &mut Canvas);
|
||||||
|
fn is_finished(&self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ProgressAnimation: Animation {
|
||||||
|
fn set_progress(&mut self, progress: f64);
|
||||||
|
fn get_progress(&self) -> f64;
|
||||||
|
}
|
||||||
48
src/tui/animations/progress.rs
Normal file
48
src/tui/animations/progress.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
use std::time::Duration;
|
||||||
|
use rsille::canvas::Canvas;
|
||||||
|
use super::{Animation, ProgressAnimation};
|
||||||
|
|
||||||
|
pub struct ProgressBarAnimation {
|
||||||
|
progress: f64,
|
||||||
|
width: u16,
|
||||||
|
height: u16,
|
||||||
|
animation_offset: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgressBarAnimation {
|
||||||
|
pub fn new(width: u16, height: u16) -> Self {
|
||||||
|
Self {
|
||||||
|
progress: 0.0,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
animation_offset: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animation for ProgressBarAnimation {
|
||||||
|
fn update(&mut self, delta: Duration) {
|
||||||
|
self.animation_offset += delta.as_secs_f64() * 2.0;
|
||||||
|
if self.animation_offset >= 1.0 {
|
||||||
|
self.animation_offset -= 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, canvas: &mut Canvas) {
|
||||||
|
// Animated progress bar rendering will be implemented here
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_finished(&self) -> bool {
|
||||||
|
self.progress >= 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProgressAnimation for ProgressBarAnimation {
|
||||||
|
fn set_progress(&mut self, progress: f64) {
|
||||||
|
self.progress = progress.clamp(0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_progress(&self) -> f64 {
|
||||||
|
self.progress
|
||||||
|
}
|
||||||
|
}
|
||||||
97
wget-list
Normal file
97
wget-list
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
https://download.savannah.gnu.org/releases/acl/acl-2.3.2.tar.xz
|
||||||
|
https://download.savannah.gnu.org/releases/attr/attr-2.5.2.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/autoconf/autoconf-2.72.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/automake/automake-1.18.1.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz
|
||||||
|
https://github.com/gavinhoward/bc/releases/download/7.0.3/bc-7.0.3.tar.xz
|
||||||
|
https://sourceware.org/pub/binutils/releases/binutils-2.45.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz
|
||||||
|
https://www.sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/coreutils/coreutils-9.8.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/dejagnu/dejagnu-1.6.3.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/diffutils/diffutils-3.12.tar.xz
|
||||||
|
https://downloads.sourceforge.net/project/e2fsprogs/e2fsprogs/v1.47.3/e2fsprogs-1.47.3.tar.gz
|
||||||
|
https://sourceware.org/ftp/elfutils/0.193/elfutils-0.193.tar.bz2
|
||||||
|
https://github.com/libexpat/libexpat/releases/download/R_2_7_3/expat-2.7.3.tar.xz
|
||||||
|
https://prdownloads.sourceforge.net/expect/expect5.45.4.tar.gz
|
||||||
|
https://astron.com/pub/file/file-5.46.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/findutils/findutils-4.10.0.tar.xz
|
||||||
|
https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz
|
||||||
|
https://pypi.org/packages/source/f/flit-core/flit_core-3.12.0.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/gawk/gawk-5.3.2.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/gcc/gcc-15.2.0/gcc-15.2.0.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/gdbm/gdbm-1.26.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/gettext/gettext-0.26.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/glibc/glibc-2.42.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/gmp/gmp-6.3.0.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/gperf/gperf-3.3.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/grep/grep-3.12.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/groff/groff-1.23.0.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/grub/grub-2.12.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/gzip/gzip-1.14.tar.xz
|
||||||
|
https://github.com/Mic92/iana-etc/releases/download/20250926/iana-etc-20250926.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/inetutils/inetutils-2.6.tar.xz
|
||||||
|
https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz
|
||||||
|
https://www.kernel.org/pub/linux/utils/net/iproute2/iproute2-6.16.0.tar.xz
|
||||||
|
https://libisl.sourceforge.io/isl-0.27.tar.xz
|
||||||
|
https://pypi.org/packages/source/J/Jinja2/jinja2-3.1.6.tar.gz
|
||||||
|
https://www.kernel.org/pub/linux/utils/kbd/kbd-2.9.0.tar.xz
|
||||||
|
https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-34.2.tar.xz
|
||||||
|
https://www.greenwoodsoftware.com/less/less-679.tar.gz
|
||||||
|
https://www.linuxfromscratch.org/lfs/downloads/development/lfs-bootscripts-20250827.tar.xz
|
||||||
|
https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.76.tar.xz
|
||||||
|
https://github.com/libffi/libffi/releases/download/v3.5.2/libffi-3.5.2.tar.gz
|
||||||
|
https://download.savannah.gnu.org/releases/libpipeline/libpipeline-1.5.8.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/libtool/libtool-2.5.4.tar.xz
|
||||||
|
https://github.com/besser82/libxcrypt/releases/download/v4.4.38/libxcrypt-4.4.38.tar.xz
|
||||||
|
https://www.kernel.org/pub/linux/kernel/v6.x/linux-6.16.9.tar.xz
|
||||||
|
https://github.com/lz4/lz4/releases/download/v1.10.0/lz4-1.10.0.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/m4/m4-1.4.20.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz
|
||||||
|
https://download.savannah.gnu.org/releases/man-db/man-db-2.13.1.tar.xz
|
||||||
|
https://www.kernel.org/pub/linux/docs/man-pages/man-pages-6.15.tar.xz
|
||||||
|
https://pypi.org/packages/source/M/MarkupSafe/markupsafe-3.0.3.tar.gz
|
||||||
|
https://github.com/mesonbuild/meson/releases/download/1.9.1/meson-1.9.1.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/mpfr/mpfr-4.2.2.tar.xz
|
||||||
|
https://invisible-mirror.net/archives/ncurses/current/ncurses-6.5-20250809.tgz
|
||||||
|
https://github.com/ninja-build/ninja/archive/v1.13.1/ninja-1.13.1.tar.gz
|
||||||
|
https://github.com/openssl/openssl/releases/download/openssl-3.5.3/openssl-3.5.3.tar.gz
|
||||||
|
https://files.pythonhosted.org/packages/source/p/packaging/packaging-25.0.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/patch/patch-2.8.tar.xz
|
||||||
|
https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.46/pcre2-10.46.tar.bz2
|
||||||
|
https://www.cpan.org/src/5.0/perl-5.42.0.tar.xz
|
||||||
|
https://distfiles.ariadne.space/pkgconf/pkgconf-2.5.1.tar.xz
|
||||||
|
https://sourceforge.net/projects/procps-ng/files/Production/procps-ng-4.0.5.tar.xz
|
||||||
|
https://sourceforge.net/projects/psmisc/files/psmisc/psmisc-23.7.tar.xz
|
||||||
|
https://www.python.org/ftp/python/3.13.7/Python-3.13.7.tar.xz
|
||||||
|
https://www.python.org/ftp/python/doc/3.13.7/python-3.13.7-docs-html.tar.bz2
|
||||||
|
https://ftp.gnu.org/gnu/readline/readline-8.3.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/sed/sed-4.9.tar.xz
|
||||||
|
https://pypi.org/packages/source/s/setuptools/setuptools-80.9.0.tar.gz
|
||||||
|
https://github.com/shadow-maint/shadow/releases/download/4.18.0/shadow-4.18.0.tar.xz
|
||||||
|
https://sqlite.org/2025/sqlite-autoconf-3500400.tar.gz
|
||||||
|
https://anduin.linuxfromscratch.org/LFS/sqlite-doc-3500400.tar.xz
|
||||||
|
https://github.com/troglobit/sysklogd/releases/download/v2.7.2/sysklogd-2.7.2.tar.gz
|
||||||
|
https://github.com/systemd/systemd/archive/v257.8/systemd-257.8.tar.gz
|
||||||
|
https://anduin.linuxfromscratch.org/LFS/systemd-man-pages-257.8.tar.xz
|
||||||
|
https://github.com/slicer69/sysvinit/releases/download/3.14/sysvinit-3.14.tar.xz
|
||||||
|
https://ftp.gnu.org/gnu/tar/tar-1.35.tar.xz
|
||||||
|
https://downloads.sourceforge.net/tcl/tcl8.6.17-src.tar.gz
|
||||||
|
https://downloads.sourceforge.net/tcl/tcl8.6.17-html.tar.gz
|
||||||
|
https://ftp.gnu.org/gnu/texinfo/texinfo-7.2.tar.xz
|
||||||
|
https://www.iana.org/time-zones/repository/releases/tzdata2025b.tar.gz
|
||||||
|
https://anduin.linuxfromscratch.org/LFS/udev-lfs-20230818.tar.xz
|
||||||
|
https://www.kernel.org/pub/linux/utils/util-linux/v2.41/util-linux-2.41.2.tar.xz
|
||||||
|
https://github.com/vim/vim/archive/v9.1.1806/vim-9.1.1806.tar.gz
|
||||||
|
https://pypi.org/packages/source/w/wheel/wheel-0.46.1.tar.gz
|
||||||
|
https://cpan.metacpan.org/authors/id/T/TO/TODDR/XML-Parser-2.47.tar.gz
|
||||||
|
https://github.com//tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1.tar.xz
|
||||||
|
https://zlib.net/fossils/zlib-1.3.1.tar.gz
|
||||||
|
https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz
|
||||||
|
https://www.linuxfromscratch.org/patches/lfs/development/bzip2-1.0.8-install_docs-1.patch
|
||||||
|
https://www.linuxfromscratch.org/patches/lfs/development/coreutils-9.8-i18n-2.patch
|
||||||
|
https://www.linuxfromscratch.org/patches/lfs/development/expect-5.45.4-gcc15-1.patch
|
||||||
|
https://www.linuxfromscratch.org/patches/lfs/development/glibc-2.42-fhs-1.patch
|
||||||
|
https://www.linuxfromscratch.org/patches/lfs/development/kbd-2.9.0-backspace-1.patch
|
||||||
|
https://www.linuxfromscratch.org/patches/lfs/development/sysvinit-3.14-consolidated-1.patch
|
||||||
Loading…
Add table
Add a link
Reference in a new issue