diff --git a/.cz.toml b/.cz.toml deleted file mode 100644 index 973c69f..0000000 --- a/.cz.toml +++ /dev/null @@ -1,7 +0,0 @@ -[tool.commitizen] -name = "cz_conventional_commits" -tag_format = "$version" -version_scheme = "semver" -version = "0.2.0" -update_changelog_on_bump = true -major_version_zero = true diff --git a/.envrc b/.envrc index 57c0efe..67eeb98 100644 --- a/.envrc +++ b/.envrc @@ -5,7 +5,7 @@ fi watch_file flake.nix watch_file flake.lock -if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD") +if ! use flake .#dev --accept-flake-config then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 + echo "devshell could not be built. Make sure dev.nix is a valid devshell and try again." >&2 fi diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..46f629e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,45 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +## Describe the bug +A clear and concise description of what the bug is. + +## Steps To Reproduce +Steps to reproduce the behavior: +1. ... +2. ... +3. ... + +## Expected behavior +A clear and concise description of what you expected to happen. + +## Screenshots +If applicable, add screenshots to help explain your problem. + +## Additional context +Add any other context about the problem here. + +## Notify maintainers + + + +## Metadata +Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result. + +```console +[user@system:~]$ nix-shell -p nix-info --run "nix-info -m" +output here +``` + +--- + +Add a :+1: [reaction] to [issues you find important]. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3b32cee --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: feature-request +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. + +--- + +Add a :+1: [reaction] to [issues you find important]. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b85deb4..4dd4a55 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,3 @@ -# TODO: Place a short descriptive PR name here - ## Overview -## Dependencies (flake inputs) +## Dependencies ## Screenshots -- \[ \] I have tested the relevant changes locally. -- \[ \] I have checked that - `nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD")` - passes. -- \[ \] I have ensured my commits follow the project's conventional commits guidelines. -- \[ \] I have checked that the changes follow a linear history. -- \[ \] (If applicable) I have commented any relevant parts of my code. -- \[ \] (If applicable) I have added appropriate unit/feature tests. -- \[ \] (If applicable) I have updated the documentation accordingly (in English). +- [ ] I have tested the relevant changes locally. +- [ ] I have checked that `nix flake check` passes. +- [ ] I have ensured my commits follow the project's commits guidelines. +- [ ] I have checked that the changes follow a linear history. +- [ ] (If applicable) I have commented any relevant parts of my code. +- [ ] (If applicable) I have added appropriate unit/feature tests. +- [ ] (If applicable) I have updated the documentation accordingly (in English). ## Additional Notes diff --git a/.github/workflows/cachix-push.yml b/.github/workflows/cachix-push.yml new file mode 100644 index 0000000..ee1c993 --- /dev/null +++ b/.github/workflows/cachix-push.yml @@ -0,0 +1,33 @@ +name: "Push packages and devshells to the cachix binary cache service" + +on: + push: + branches: + - main + +jobs: + flake-check: + if: false + runs-on: "ubuntu-latest" + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Settings up cachix binary cache..." + uses: cachix/cachix-action@main + with: + name: tsandrini + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + + - name: "Building project packages..." + run: nix build + + - name: "Building project devshells..." + run: nix develop --command echo OK + diff --git a/.github/workflows/check-on-merge.yml b/.github/workflows/check-on-merge.yml deleted file mode 100644 index abfe3a8..0000000 --- a/.github/workflows/check-on-merge.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: "flake check" -on: - pull_request: - types: [opened, reopened, synchronize] -jobs: - check: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - - name: Check Nix flake Nixpkgs inputs - uses: DeterminateSystems/flake-checker-action@main diff --git a/.github/workflows/flake-check.yml b/.github/workflows/flake-check.yml new file mode 100644 index 0000000..25c6355 --- /dev/null +++ b/.github/workflows/flake-check.yml @@ -0,0 +1,30 @@ +name: "Run `nix flake-check`" + +on: + push: + branches: + - main + pull_request: + types: [opened, reopened, synchronize] + repository_dispatch: + types: [create-pull-request] + +jobs: + flake-check: + if: false + runs-on: "ubuntu-latest" + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Running `nix flake check`..." + run: nix flake check --show-trace --accept-flake-config + + - name: "Checking flake inputs for stale & insecure nixpkgs versions..." + uses: DeterminateSystems/flake-checker-action@main diff --git a/.github/workflows/flakehub-publish.yml b/.github/workflows/flakehub-publish.yml new file mode 100644 index 0000000..a328a01 --- /dev/null +++ b/.github/workflows/flakehub-publish.yml @@ -0,0 +1,29 @@ +name: "Publish flake to FlakeHub" + +on: + push: + branches: + - main + +jobs: + flakehub-publish: + runs-on: "ubuntu-latest" + permissions: + id-token: "write" + contents: "read" + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Publishing flake to FlakeHub..." + uses: DeterminateSystems/flakehub-push@main + with: + name: "tsandrini/flake-parts-builder" + rolling: true + visibility: "public" diff --git a/.github/workflows/flakehub.yml b/.github/workflows/flakehub.yml deleted file mode 100644 index 58fd235..0000000 --- a/.github/workflows/flakehub.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: "FlakeHub" -on: - push: - branches: - - "main" -jobs: - flakehub-publish: - runs-on: "ubuntu-latest" - permissions: - id-token: "write" - contents: "read" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/flakehub-push@main - with: - name: "tsandrini/practical-flakes-template" - rolling: true - visibility: "public" diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml index dee3401..f9f9955 100644 --- a/.github/workflows/update-flake-lock.yml +++ b/.github/workflows/update-flake-lock.yml @@ -1,24 +1,32 @@ -name: update-flake-lock +name: "Periodically update flake inputs in flake.lock" + on: workflow_dispatch: # allows manual triggering schedule: - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 jobs: - lockfile: - # if: false # NOTE: Uncomment this line to disable the workflow + update-flake-lock: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main - - name: Update flake.lock + - name: "Updating flake.lock..." uses: DeterminateSystems/update-flake-lock@main with: - pr-assignees: tsandrini - pr-title: "Automated action - Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR + pr-title: "Automated action - Update flake.lock" + pr-labels: | dependencies automated + # NOTE You can use a personal access token to identify + # as a concrete user, this may be useful when you want to + # trigger additional CI actions. + # token: ${{ secrets.GH_TOKEN_FOR_UPDATES }} diff --git a/.gitignore b/.gitignore index 2d8df24..a35912e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,257 @@ -# OS generated files # -###################### -.DS_Store -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db - -# IDEA Ignores # -################ -*.iml -*.ipr +# ---- +# Rust +# ---- +## Generated by Cargo +## will have compiled files and executables +debug/ +target/ + +## These are backup files generated by rustfmt +**/*.rs.bk + +## MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# --------- +# Nix/NixOS +# --------- + +## Builds +build/ +result +result-* + +## devshells/devenv/direnv +.direnv +.devenv + +# ----------- +# Editors/IDE +# ----------- + +## VIM + +### Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +### Session +Session.vim +Sessionx.vim + +### Temporary +.netrwhist +*~ +### Auto-generated tag files +tags +### Persistent undo +[._]*.un~ + +## VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +### Local History for Visual Studio Code +.history/ + +### Built Visual Studio Code Extensions +*.vsix + +## Emacs +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +### Org-mode +.org-id-locations +*_archive + +### flymake-mode +*_flymake.* + +### eshell files +/eshell/history +/eshell/lastdir + +### elpa packages +/elpa/ + +### reftex files +*.rel + +### AUCTeX auto folder +/auto/ + +### cask packages +.cask/ +dist/ + +### Flycheck +flycheck_*.el + +### server auth directory +/server/ + +### projectiles files +.projectile + +### directory configuration +.dir-locals.el + +### network security +/network-security.data + +## JetBrains IDE +### Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +### Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +### User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +### AWS User-specific +.idea/**/aws.xml + +### Generated files +.idea/**/contentModel.xml + +### Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +### Gradle +.idea/**/gradle.xml +.idea/**/libraries + +### CMake +cmake-build-*/ + +### Mongo Explorer plugin +.idea/**/mongoSettings.xml + +### File-based project format *.iws -.idea/ + +### IntelliJ out/ -local.properties -# Project related # -################ -result/ -build/ +### mpeltonen/sbt-idea plugin +.idea_modules/ -result -.direnv/ -.devenv/ +### JIRA plugin +atlassian-ide-plugin.xml + +### Cursive Clojure plugin +.idea/replstate.xml + +### SonarLint plugin +.idea/sonarlint/ + +### Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### Editor-based Rest Client +.idea/httpRequests + +### Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + + +# ----------- +# OS specific +# ----------- + +## Linux +*~ +### temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* +### KDE directory preferences +.directory +### Linux trash folder which might appear on any partition or disk +.Trash-* +### .nfs files are created when an open file is removed but is still being accessed +.nfs* + + +## macOS + +### General +.DS_Store +.AppleDouble +.LSOverride + +### Icon must end with two \r +Icon + +### Thumbnails +._* + +### Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +### Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# ----- +# Misc +# ----- + +## Backups +*.bak +*.gho +*.ori +*.orig +*.tmp + +## Tags -.devcontainer.json -.pre-commit-config.yaml +### Ignore tags created by etags, ctags, gtags (GNU global) and cscope +TAGS +.TAGS +!TAGS/ +tags +.tags +!tags/ +gtags.files +GTAGS +GRTAGS +GPATH +GSYMS +cscope.files +cscope.out +cscope.in.out +cscope.po.out diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c24dc02 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,677 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "cc" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "flake-parts-builder" +version = "1.0.0" +dependencies = [ + "clap", + "color-eyre", + "diff", + "fs_extra", + "minijinja", + "regex", + "serde", + "serde_json", + "tempfile", + "termcolor", + "thiserror", + "walkdir", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minijinja" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e136ef580d7955019ab0a407b68d77c292a9976907e217900f3f76bc8f6dc1a4" +dependencies = [ + "serde", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "proc-macro2" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "sharded-slab", + "thread_local", + "tracing-core", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3339f4f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "flake-parts-builder" +version = "1.0.0" +edition = "2021" +authors = ["TomΓ‘Ε‘ Sandrini"] +repository = "https://github.com/tsandrini/flake-parts-builder" +license = "MIT" + +[dependencies] +clap = { version = "4.5.7", features = ["cargo", "derive"] } +color-eyre = "0.6.3" +diff = "0.1.13" +fs_extra = "1.3.0" +minijinja = "2.0.2" +regex = "1.10.5" +serde = { version = "1.0.203", features = ["derive"] } +serde_json = "1.0.117" +tempfile = "3.10.1" +termcolor = "1.4.1" +thiserror = "1.0.61" +walkdir = "2.5.0" diff --git a/README.md b/README.md index 47d9515..3a1b17c 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,231 @@ -# practical-flakes-template +# flake-parts-builder -[![flake check](https://github.com/tsandrini/practical-flakes-template/actions/workflows/check-on-merge.yml/badge.svg)](https://github.com/tsandrini/practical-flakes-template/actions/workflows/check-on-merge.yml) -[![FlakeHub](https://github.com/tsandrini/practical-flakes-template/actions/workflows/flakehub.yml/badge.svg)](https://github.com/tsandrini/practical-flakes-template/actions/workflows/flakehub.yml) +[![flake check](https://github.com/tsandrini/flake-parts-builder/actions/workflows/check-on-merge.yml/badge.svg)](https://github.com/tsandrini/flake-parts-builder/actions/workflows/check-on-merge.yml) +[![FlakeHub](https://github.com/tsandrini/flake-parts-builder/actions/workflows/flakehub.yml/badge.svg)](https://github.com/tsandrini/flake-parts-builder/actions/workflows/flakehub.yml) -## !WARNING! +## About πŸ“ -Currently rewriting into an interactive template builder! For more info see branch `v1`. This will evetually be archived into a separate branch. +Building a new [flake-parts](https://github.com/hercules-ci/flake-parts) project? +Need a template with all the necessary boilerplate, but none perfectly fits your +needs? Just choose the parts that you need and **build your own**! -## Description +```bash +nix run github:tsandrini/flake-parts-builder -- init -p +github,+nixos,treefmt myProject +``` + +----- + +Templates defined to be used with `nix flake init -t` typically suffer from +the case of being **static** and too simple. They usually address only one +specific thing or problem domain (eg. devenv, rust, flake-parts, dotfiles, ...) +which makes the end user quickly start running into issues when trying to +combine said domains since real life flake projects rarely require only one +such domain. + +And this is what `flake-parts-builder` solves! It serves as a +**dynamic extension** to `nix flake init -t`, nothing more, nothing less! + +Okay, but what exactly does it do then? + +- `flake-parts-builder init` - **initialize** a new project with all your + required parts +- `flake-parts-builder add` - **add** new parts to an already existing + flake-parts project +- `flake-parts-builder list` - **list** all currently available flake-parts to + be used with the `list` and `add` subcommands -_PracticalFlakes_ are a set of highly opinionated templates to quickly bootstrap -your next [nix](https://github.com/NixOS/nix) project in -[flakes](https://nixos.wiki/wiki/Flakes) 😎 +## Installation πŸ€– -To quickly initialize a new project run +**Disclaimer**: `flake-parts-builder` is built on top of nix +[flakes](https://wiki.nixos.org/wiki/Flakes) and +[flake-parts](https://github.com/hercules-ci/flake-parts) hence why familiarity +with flakes is a necessity. The builder also currently runs in flakes mode only +and uses flakes to parse flake-parts stores. The following "experimental" +features are then a forced requirement +`--experimental-features 'nix-command flakes'`. + +*NOTE*: if enough people will be using this project I don't have any issues +with pushing it into upstream [nixpkgs](https://github.com/NixOS/nixpkgs). + +### Nix CLI ```bash -nix flake init -t github:tsandrini/practical-flakes-template +nix profile install github:tsandrini/flake-parts-builder ``` -And you're good to go! πŸ‘ - -## Features - -1. Drop-in modularity using - [flake-parts](https://github.com/hercules-ci/flake-parts) βš™οΈ - - the main idea is that if you have a bunch of projects using this template you - can simply just copy the individual `parts/` directories to share functionality - - this way, no matter if you're developing language features, packages, - [NixOS modules](https://nixos.wiki/wiki/NixOS_Modules), - [home-manager](https://github.com/nix-community/home-manager) userspace, - you can always use the same underlying structure -1. [devenv.sh](https://github.com/cachix/devenv) is awesome! πŸ”₯ - - includes a devenv shell already preconfigured to format and lint nix -1. [treefmt](https://github.com/numtide/treefmt) is the one and only formatter - to rule them all πŸ™ -1. Already preconfigured [github actions](https://docs.github.com/en/actions) - and [gitlab CI](https://docs.gitlab.com/ee/ci/) πŸ’ͺ - - automatic `nix flake check` on pull/merge requests - - automatic nixpkgs flake inputs checker (github only) - - automatic cron based flake inputs updates (github only) - - (optional) push to [FlakeHub](https://flakehub.com/) -1. Prepared for custom `lib` overrides πŸ€“ - - depending on what you're currently aiming to write, you might need some - custom helpers or library functions, this template - already set ups all the necessary boilerplate to get it all going -1. And finally, examples included πŸ–ŒοΈ - -## Usage - -After a proper installation process you can enter the development environment -with `direnv allow` (or alternatively -`nix develop .#dev --override-input devenv-root "file+file://"<(printf %s "$PWD")`) - -While not many, the code has some required references to the `practicalFlakes` -identifier. This can be renamed in the whole project using the script -`rename-project` (which is available in the dev environment) +### NixOS + +```nix +{ + inputs.flake-parts-builder.url = "github:tsandrini/flake-parts-builder"; + + outputs = { self, nixpkgs, flake-parts-builder }: { + # change `yourhostname` to your actual hostname + nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem { + # change to your system: + system = "x86_64-linux"; + modules = [ + ./configuration.nix + ({ system, ... }: { + environment.systemPackages = [ flake-parts-builder.packages.${system}.default ]; + }) + ]; + }; + }; +} +``` -```bash -rename-project . myAwesomeApp +## Binary cache πŸ’Ύ + +`flake-parts-builder` is written in Rust with minimal dependencies to ensure +safety and consistency, however, there is also a binary cache available if you'd +like to skip the build process. (TODO, push the damn thing xd) + +```nix + nixConfig = { + extra-substituters = [ + "https://tsandrini.cachix.org" + ]; + extra-trusted-public-keys = [ + "tsandrini.cachix.org-1:t0AzIUglIqwiY+vz/WRWXrOkDZN8TwY3gk+n+UDt4gw=" + ]; + }; ``` -You're also encouraged to update your flakes with +## Available parts πŸ“‚ + +You can list all of the available parts with the `flake-parts-builder list` +subcommand, which goes through all of the flake-parts stores passed via the `-I` +or `--include` flag. Here is the current output the list subcommand running on +only the base parts provided by this flake (note that you can disable the base +parts using `--disable-base` if you wish so) ```bash -nix flake update +flake-parts-builder list +``` +```md + # github:tsandrini/flake-parts-builder#flake-parts + - +github: (Collection) GitHub related parts + - +home-manager: (Collection) Home-manager related parts. + - +nixos: (Collection) NixOS related parts. + - agenix: Bindings for the agenix secrets manager with prepared NixOS/HM modules ready to be used in your configurations. + - devenv: Flake bindings for the `github:cachix/devenv` development environment. + - flake-root: Provides `config.flake-root` variable pointing to the root of the flake project. + - gh-actions-check: Adds a simple `nix flake check` GitHub action workflow. + - gh-actions-flake-update: Adds the periodic `DeterminateSystems/update-flake-lock` GitHub action workflow. + - gh-actions-flakehub: Adds the push to FlakeHub GitHub action workflow. + - gh-actions-pages: Adds a GitHub action that runs `nix build .#pages` and deploys the result to GitHub pages. + - gh-templates-PR: Adds a basic GitHub pull request template. + - gh-templates-issues: Adds basic bug/feature GitHub issue templates. + - gitlab-ci-check: Adds a simple `nix flake check` to your GitLab CI/CD pipeline. + - hm-homes: Template for your HM homes and a handy generator for you `homeManagerConfiguration` calls. + - hm-modules: Basic template for custom home-manager modules. + - lib: Basic template for custom nix library functions. + - nix-topology: Adds bindings for the `github:oddlama/nix-topology` project to generate graphs of your networks. + - nixos-hosts: Template for your NixOS hosts and a handy generator for `lib.nixosSystem` calls. + - nixos-modules: Basic template for custom NixOS modules. + - overlays: Basic template for custom nixpkgs overlays. + - pkgs: Basic template for custom nix packages (ie derivations). + - pre-commit-hooks: Bindings for pre-commit-hooks.nix and a simple pre-commit-hook template. + - process-compose-flake: Bindings for process-compose-flake and a simple process-compose template. + - shells: Basic template for custom nix devshells (ie. `mkShell` calls) with potential bindings to other parts. + - systems: Sets up the default `systems` of flake-parts using `github:nix-systems/default`. + - treefmt: Bindings for the treefmt formatter and a basic treefmt configuration. + + # github:tsandrini/flake-parts-builder#flake-parts-bootstrap + - _bootstrap: (Required) Minimal set of functions used to bootstrap your flake-parts project. ``` -## Variants +## Using your own parts πŸ‘¨β€πŸ’»πŸ‘©β€πŸ’» -There are also a few other different variants of the base template that may -be better suited for your needs +`flake-parts-builder` was designed from the ground up with extensibility in mind. +To be able to use local parts, remote parts and cache parts in an easy manner +the CLI accepts additional flake-parts stores via the `-I` or `--include` flag +as flake derivation outputs. Meaning that you can run -- **main**: The main, default template. -- **home**: Conceptually and structurally the same as the default template, but - also includes prepared and preconfigured - [home-manager](https://github.com/nix-community/home-manager) as well as - examples of how to use it -- **minimal**: Structurally the same as the default template, but stripped of all - of the included examples and additional prepared files -- **isolated**: Centralizes all of the nix related stuff into a `nix/` folder. - This can be useful when you'd like to not pollute your root with stuff not - directly tied to the code. -- **isolated-minimal**: Isolated combined with minimal, that is, structurally the - same as minimal, however, stripped out of all the examples and unnecessary code +```bash +flake-parts-builder init -I ./myDir#flake-parts -p shells,pkgs,my-custom-part myNewProject +``` -You can install your desired template variant using +or even remote parts stores ```bash -nix flake init -t github:tsandrini/practical-flakes-template#myVariant +flake-parts-builder init -I github:org/my-flake-project#flake-parts -p shells,my-custom-remote-part myNewProject +``` + +Thanks to the wonders of nix, the flake-parts stores will be resolved & fetched +only once and on successive calls, they will be copied directly from you local +`/nix/store` cache. + +### Custom flake-parts-stores + +A **flake-part store** is any derivation that has **flake-parts** located at +`$out/flake-parts`, so for example the following snippet + +```nix +stdenv.mkDerivation { + name = "my-custom-flake-parts"; + version = "1.0.0"; + src = ./flake-parts; + + dontConfigure = true; + dontBuild = true; + dontCheck = true; + + installPhase = '' + mkdir -p $out/flake-parts + cp -rv $src/* $out/flake-parts + ''; +} +``` + +### Custom flake-parts + +A **flake-part** is any folder with a **meta.nix** file at its root containing +an attrset with the following structure. + +```nix +{ + description = "Flake bindings for the cachix/devenv development environment."; + + inputs = { + devenv.url = "github:cachix/devenv" + # .... + }; + dependencies = [ ]; + conflicts = [ "shells" ]; + extraTrustedPublicKeys = [ "https://devenv.cachix.org" ]; + extraSubstituters = [ "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" ]; +} ``` -For example, -`nix flake init -t github:tsandrini/practical-flakes-template#isolated-minimal`. +- `description`: a simple description of the provided parts printed when running + `flake-parts-builder list` +- `inputs`: flake inputs that will be recursively merged from all required parts + and pasted into the final `flake.nix` file +- `dependencies`: with this you can add any additional required parts for the + initialization/addition, this can be either a full flake uri (eg. + `github:org/my-flake-project#flake-parts/my-custom-flake-part`) or a local + reference to some other part **included in the same flake-parts store** + (eg. `my-custom-part`) +- `conflicts`: a specification of other potentially conflicting parts + (for example when handling the same functionality, like `devenv` and `shells`) + that should abort the process in case of found conflict, note that you can + force the initialization/addition even in case of conflict with the + `--ignore-conflicts` +- `extraTrustedPublicKeys`: merged with all of the required parts and pasted into + the final `flake.nix`, for security purposes they are all commented out +- `extraSubstituters`: merged with all of the required parts and pasted into the + final `flake.nix`, for security purposes they are all commented out + +## FAQ πŸ—£οΈ + +### 1. Why not use `flake.templates` instead? + +### 2. Can't we just stuff this functionality into flakeModules? + +I totally agree there is a fine line between a reusable piece of functionality +and boilerplate template code and I personally can't think of a general enough +definition that would discern them and also be somehow useful. However, I do +believe there is a practical clearly visible difference between them that most +programmers can just simply look and see, let's for example take .... diff --git a/flake-parts-bootstrap/_bootstrap/.envrc b/flake-parts-bootstrap/_bootstrap/.envrc new file mode 100644 index 0000000..8f2fbe0 --- /dev/null +++ b/flake-parts-bootstrap/_bootstrap/.envrc @@ -0,0 +1,25 @@ +if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" +fi + +watch_file flake.nix +watch_file flake.lock + +# Conditionally watch dev files only if they exist +[ -f flake-parts/devenv/dev.nix ] && watch_file flake-parts/devenv/dev.nix +[ -f flake-parts/shells/dev.nix ] && watch_file flake-parts/shells/dev.nix +[ -f flake-parts/process-compose-flake/dev.nix ] && watch_file flake-parts/process-compose-flake/dev.nix +[ -f flake-parts/treefmt.nix ] && watch_file flake-parts/treefmt.nix +[ -f flake-parts/pre-commit-hooks.nix ] && watch_file flake-parts/pre-commit-hooks.nix + + +# Check which devshell implementation we are using and load that one +if [ -f flake-parts/devenv/dev.nix ]; then + if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD"); then + echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to dev.nix and hit enter to try again." >&2 + fi +elif [ -f flake-parts/shells/dev.nix ]; then + if ! use flake .#dev --accept-flake-config; then + echo "devshell could not be built. Make sure dev.nix is a valid devshell and try again." >&2 + fi +fi diff --git a/flake-parts-bootstrap/_bootstrap/.gitignore b/flake-parts-bootstrap/_bootstrap/.gitignore new file mode 100644 index 0000000..f699a02 --- /dev/null +++ b/flake-parts-bootstrap/_bootstrap/.gitignore @@ -0,0 +1,243 @@ +# --------- +# Nix/NixOS +# --------- + +## Builds +build/ +result +result-* + +## devshells/devenv/direnv +.direnv +.devenv + +# ----------- +# Editors/IDE +# ----------- + +## VIM + +### Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +### Session +Session.vim +Sessionx.vim + +### Temporary +.netrwhist +*~ +### Auto-generated tag files +tags +### Persistent undo +[._]*.un~ + +## VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +### Local History for Visual Studio Code +.history/ + +### Built Visual Studio Code Extensions +*.vsix + +## Emacs +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +### Org-mode +.org-id-locations +*_archive + +### flymake-mode +*_flymake.* + +### eshell files +/eshell/history +/eshell/lastdir + +### elpa packages +/elpa/ + +### reftex files +*.rel + +### AUCTeX auto folder +/auto/ + +### cask packages +.cask/ +dist/ + +### Flycheck +flycheck_*.el + +### server auth directory +/server/ + +### projectiles files +.projectile + +### directory configuration +.dir-locals.el + +### network security +/network-security.data + +## JetBrains IDE +### Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +### Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +### User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +### AWS User-specific +.idea/**/aws.xml + +### Generated files +.idea/**/contentModel.xml + +### Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +### Gradle +.idea/**/gradle.xml +.idea/**/libraries + +### CMake +cmake-build-*/ + +### Mongo Explorer plugin +.idea/**/mongoSettings.xml + +### File-based project format +*.iws + +### IntelliJ +out/ + +### mpeltonen/sbt-idea plugin +.idea_modules/ + +### JIRA plugin +atlassian-ide-plugin.xml + +### Cursive Clojure plugin +.idea/replstate.xml + +### SonarLint plugin +.idea/sonarlint/ + +### Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### Editor-based Rest Client +.idea/httpRequests + +### Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + + +# ----------- +# OS specific +# ----------- + +## Linux +*~ +### temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* +### KDE directory preferences +.directory +### Linux trash folder which might appear on any partition or disk +.Trash-* +### .nfs files are created when an open file is removed but is still being accessed +.nfs* + + +## macOS + +### General +.DS_Store +.AppleDouble +.LSOverride + +### Icon must end with two \r +Icon + +### Thumbnails +._* + +### Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +### Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# ----- +# Misc +# ----- + +## Backups +*.bak +*.gho +*.ori +*.orig +*.tmp + +## Tags + +### Ignore tags created by etags, ctags, gtags (GNU global) and cscope +TAGS +.TAGS +!TAGS/ +tags +.tags +!tags/ +gtags.files +GTAGS +GRTAGS +GPATH +GSYMS +cscope.files +cscope.out +cscope.in.out +cscope.po.out diff --git a/flake-parts-bootstrap/_bootstrap/README.md b/flake-parts-bootstrap/_bootstrap/README.md new file mode 100644 index 0000000..836b179 --- /dev/null +++ b/flake-parts-bootstrap/_bootstrap/README.md @@ -0,0 +1,16 @@ +# NAMEPLACEHOLDER + +## About + +TODO Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque +arcu. Fusce tellus odio, dapibus id fermentum quis, suscipit id erat. Maecenas +sollicitudin. Aliquam erat volutpat. Donec iaculis gravida nulla. Proin mattis +lacinia justo. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui +officia deserunt mollit anim id est laborum. Fusce nibh. Mauris metus. Etiam +egestas wisi a erat. Nullam sit amet magna in magna gravida vehicula. +Pellentesque ipsum. Cras pede libero, dapibus nec, pretium sit amet, tempor quis. +Aenean fermentum risus id tortor. + +## References + +1. This project was built using diff --git a/flake-parts-bootstrap/_bootstrap/flake-parts/_bootstrap.nix b/flake-parts-bootstrap/_bootstrap/flake-parts/_bootstrap.nix new file mode 100644 index 0000000..ca8efd0 --- /dev/null +++ b/flake-parts-bootstrap/_bootstrap/flake-parts/_bootstrap.nix @@ -0,0 +1,88 @@ +# --- flake-parts/_bootstrap.nix +{ lib }: +rec { + # This nix file is used to minimally set up and bootstrap the `loadParts` + # function which is then used to load all the modules in the + # `./flake-parts` directory. The user also has the option to remove + # this file and directly load the `loadParts` function from + # the `lib` attribute of the `github:tsandrini/flake-parts-builder` + # flake, however, that brings an additional dependency to the project, + # which may be undesirable for some and isn't really necessary. + loadParts = dir: flatten (mapModules dir (x: x)); + + /* + Recursively flattens a nested attrset into a list of just its values. + + *Type*: `flatten :: AttrSet a -> [a]` + + Example: + ```nix title="Example" linenums="1" + flatten { + keyA = 10; + keyB = "str20"; + keyC = { + keyD = false; + keyE = { + a = 10; + b = "20"; + c = false; + }; + }; + } + => [ 10 "str20" false 10 "20" false ] + ``` + */ + flatten = attrs: lib.collect (x: !lib.isAttrs x) attrs; + + /* + Apply a map to every attribute of an attrset and then filter the resulting + attrset based on a given predicate function. + + *Type*: `mapFilterAttrs :: (AttrSet b -> Bool) -> (AttrSet a -> AttrSet b) -> AttrSet a -> AttrSet b` + */ + mapFilterAttrs = + pred: f: attrs: + lib.filterAttrs pred (lib.mapAttrs' f attrs); + + /* + Recursively read a directory and apply a provided function to every `.nix` + file. Returns an attrset that reflects the filenames and directory + structure of the root. + + Notes: + + 1. Files and directories starting with the `_` or `.git` prefix will be + completely ignored. + + 2. If a directory with a `myDir/default.nix` file will be encountered, + the function will be applied to the `myDir/default.nix` file + instead of recursively loading `myDir` and applying it to every file. + + *Type*: `mapModules :: Path -> (Path -> AttrSet a) -> { name :: String; value :: AttrSet a; }` + + Example: + ```nix title="Example" linenums="1" + mapModules ./modules import + => { hardware = { moduleA = { ... }; }; system = { moduleB = { ... }; }; } + + mapModules ./hosts (host: mkHostCustomFunction myArg host) + => { hostA = { ... }; hostB = { ... }; } + ``` + */ + mapModules = + dir: fn: + mapFilterAttrs (n: v: v != null && !(lib.hasPrefix "_" n) && !(lib.lib.hasPrefix ".git" n)) ( + n: v: + let + path = "${toString dir}/${n}"; + in + if v == "directory" && builtins.pathExists "${path}/default.nix" then + lib.nameValuePair n (fn path) + else if v == "directory" then + lib.nameValuePair n (mapModules path fn) + else if v == "regular" && n != "default.nix" && lib.hasSuffix ".nix" n then + lib.nameValuePair (lib.removeSuffix ".nix" n) (fn path) + else + lib.nameValuePair "" null + ) (builtins.readDir dir); +} diff --git a/flake-parts-bootstrap/_bootstrap/meta.nix b/flake-parts-bootstrap/_bootstrap/meta.nix new file mode 100644 index 0000000..ef91030 --- /dev/null +++ b/flake-parts-bootstrap/_bootstrap/meta.nix @@ -0,0 +1,8 @@ +# --- meta.nix +{ + description = "(Required) Minimal set of functions used to bootstrap your flake-parts project."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/+github/meta.nix b/flake-parts/+github/meta.nix new file mode 100644 index 0000000..d7b0c38 --- /dev/null +++ b/flake-parts/+github/meta.nix @@ -0,0 +1,14 @@ +# --- meta.nix +{ + description = "(Collection) GitHub related parts"; + + inputs = { }; + dependencies = [ + "gh-actions-check" + "gh-actions-flake-update" + "gh-templates-issues" + "gh-templates-PR" + ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/+home-manager/meta.nix b/flake-parts/+home-manager/meta.nix new file mode 100644 index 0000000..9002410 --- /dev/null +++ b/flake-parts/+home-manager/meta.nix @@ -0,0 +1,12 @@ +# --- meta.nix +{ + description = "(Collection) Home-manager related parts."; + + inputs = { }; + dependencies = [ + "hm-modules" + "hm-homes" + ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/+nixos/meta.nix b/flake-parts/+nixos/meta.nix new file mode 100644 index 0000000..2998e84 --- /dev/null +++ b/flake-parts/+nixos/meta.nix @@ -0,0 +1,12 @@ +# --- meta.nix +{ + description = "(Collection) NixOS related parts."; + + inputs = { }; + dependencies = [ + "nixos-hosts" + "nixos-modules" + ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/agenix/flake-parts/agenix/default.nix b/flake-parts/agenix/flake-parts/agenix/default.nix new file mode 100644 index 0000000..fb51143 --- /dev/null +++ b/flake-parts/agenix/flake-parts/agenix/default.nix @@ -0,0 +1,109 @@ +# --- flake-parts/agenix/default.nix +{ + config, + lib, + inputs, + ... +}: +{ + options.secrets = with lib.types; { + secretsPath = lib.mkOption { + type = path; + default = ./secrets; + description = "Path to the actual secrets directory"; + }; + + pubkeys = lib.mkOption { + type = attrsOf (attrsOf anything); + default = { }; + description = '' + The resulting option that will hold the various public keys used around + the flake. + ''; + }; + + pubkeysFile = lib.mkOption { + type = path; + default = ./pubkeys.nix; + description = '' + Path to the pubkeys file that will be used to construct the + `secrets.pubkeys` option. + ''; + }; + + extraPubkeys = lib.mkOption { + type = attrsOf (attrsOf anything); + default = { }; + description = '' + Additional public keys that will be merged into the `secrets.pubkeys` + ''; + }; + }; + + config = { + secrets.pubkeys = (import config.agenix.pubkeysFile) // config.agenix.extraPubkeys; + + flake.nixosModules.security_agenix = + { + config, + lib, + pkgs, + system, + ... + }: + with builtins; + with lib; + let + cfg = config.NAMEPLACEHOLDER.security.agenix; + in + { + options.NAMEPLACEHOLDER.security.agenix = with types; { + enable = mkEnableOption '' + Enables NixOS module that sets up & configures the agenix secrets + backend. + + References + - https://github.com/ryantm/agenix + - https://nixos.wiki/wiki/Agenix + ''; + }; + + imports = with inputs; [ agenix.nixosModules.default ]; + + config = mkIf cfg.enable { + environment.systemPackages = [ + inputs.agenix.packages.${system}.default + pkgs.age + ]; + + age.identityPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + }; + }; + + flake.homeModules.security_agenix = + { config, lib, ... }: + with builtins; + with lib; + let + cfg = config.NAMEPLACEHOLDER.hm.security.agenix; + in + { + options.NAMEPLACEHOLDER.hm.security.agenix = with types; { + enable = mkEnableOption '' + Enable Home Manager module that sets up & configures the agenix + secrets backend. + + References + - https://github.com/ryantm/agenix + - https://nixos.wiki/wiki/Agenix + ''; + }; + + imports = with inputs; [ agenix.homeManagerModules.default ]; + + config = mkIf cfg.enable { + age.identityPaths = [ "${config.home.homeDirectory}/.ssh/id_ed25519" ]; + }; + }; + }; +} diff --git a/flake-parts/agenix/flake-parts/agenix/pubkeys.nix b/flake-parts/agenix/flake-parts/agenix/pubkeys.nix new file mode 100644 index 0000000..d3b94da --- /dev/null +++ b/flake-parts/agenix/flake-parts/agenix/pubkeys.nix @@ -0,0 +1,21 @@ +# --- flake-parts/agenix/pubkeys.nix +let + myUser = "TODO: Add your public key here"; +in +{ + common = { }; + hosts = { + myHost = { + users = { + root = { + sshKey = null; + authorizedKeys = [ ]; + }; + myUser = { + sshKey = null; + authorizedKeys = [ myUser ]; + }; + }; + }; + }; +} diff --git a/templates/.gitignore b/flake-parts/agenix/flake-parts/agenix/secrets/.gitignore similarity index 100% rename from templates/.gitignore rename to flake-parts/agenix/flake-parts/agenix/secrets/.gitignore diff --git a/flake-parts/agenix/meta.nix b/flake-parts/agenix/meta.nix new file mode 100644 index 0000000..0c0e3d1 --- /dev/null +++ b/flake-parts/agenix/meta.nix @@ -0,0 +1,13 @@ +{ + description = "Bindings for the agenix secrets manager with prepared NixOS/HM modules ready to be used in your configurations."; + + inputs = { + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + conflicts = [ ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/devenv/flake-parts/devenv/default.nix b/flake-parts/devenv/flake-parts/devenv/default.nix new file mode 100644 index 0000000..28b8247 --- /dev/null +++ b/flake-parts/devenv/flake-parts/devenv/default.nix @@ -0,0 +1,20 @@ +# --- flake-parts/devenv/default.nix +{ inputs, lib, ... }: +{ + imports = with inputs; [ devenv.flakeModule ]; + + perSystem = + { + config, + pkgs, + system, + ... + }: + { + devenv.shells.dev = import ./dev.nix { + inherit pkgs system; + inherit (inputs) devenv-root; + treefmt-wrapper = if (lib.hasAttr "treefmt" config) then config.treefmt.build.wrapper else null; + }; + }; +} diff --git a/templates/minimal/parts/shells/dev.nix b/flake-parts/devenv/flake-parts/devenv/dev.nix similarity index 56% rename from templates/minimal/parts/shells/dev.nix rename to flake-parts/devenv/flake-parts/devenv/dev.nix index 36d08f8..38c35ca 100644 --- a/templates/minimal/parts/shells/dev.nix +++ b/flake-parts/devenv/flake-parts/devenv/dev.nix @@ -1,8 +1,8 @@ -# --- parts/shells/dev.nix +# --- flake-parts/devenv/dev.nix { pkgs, - treefmt, devenv-root, + treefmt-wrapper ? null, ... }: { @@ -15,32 +15,40 @@ # -------------------------- # --- ENV & SHELL & PKGS --- # -------------------------- - packages = with pkgs; [ - # -- NIX UTILS -- - nix-output-monitor # Processes output of Nix commands to show helpful and pretty information - nixfmt-rfc-style # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt # An opinionated formatter for Nix - # alejandra # The Uncompromising Nix Code Formatter - nh # Yet another nix cli helper - - # -- GIT RELATED UTILS -- - # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs - # cz-cli # The commitizen command line utility - # fh # The official FlakeHub CLI - # gh # GitHub CLI tool - - # -- BASE LANG UTILS -- - markdownlint-cli # Command line interface for MarkdownLint - typos # Source code spell checker - treefmt # one CLI to format the code tree - - # -- (YOUR) EXTRA PKGS -- - ]; + packages = + with pkgs; + ( + (lib.optional (treefmt-wrapper != null) treefmt-wrapper) + ++ [ + # -- NIX UTILS -- + nil # Yet another language server for Nix + statix # Lints and suggestions for the nix programming language + deadnix # Find and remove unused code in .nix source files + nix-output-monitor # Processes output of Nix commands to show helpful and pretty information + nixfmt-rfc-style # An opinionated formatter for Nix + # NOTE Choose a different formatter if you'd like to + # nixfmt # An opinionated formatter for Nix + # alejandra # The Uncompromising Nix Code Formatter + + # -- GIT RELATED UTILS -- + # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs + # cz-cli # The commitizen command line utility + # fh # The official FlakeHub CLI + # gh # GitHub CLI tool + # gh-dash # Github Cli extension to display a dashboard with pull requests and issues + + # -- BASE LANG UTILS -- + markdownlint-cli # Command line interface for MarkdownLint + # nodePackages.prettier # Prettier is an opinionated code formatter + # typos # Source code spell checker + + # -- (YOUR) EXTRA PKGS -- + ] + ); enterShell = '' # Welcome splash text - echo ""; echo -e "\e[1;37;42mWelcome to the practicalFlakes devshell!\e[0m"; echo "" + echo ""; echo -e "\e[1;37;42mWelcome to the NAMEPLACEHOLDER devshell!\e[0m"; echo "" ''; # --------------- @@ -48,7 +56,7 @@ # --------------- scripts = { "rename-project".exec = '' - find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/practicalFlakes/$2/g" + find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/NAMEPLACEHOLDER/$2/g" ''; }; @@ -64,11 +72,13 @@ # ------------------ # --- CONTAINERS --- # ------------------ - devcontainer.enable = true; + # devcontainer.enable = true; # ---------------------- # --- BINARY CACHING --- # ---------------------- + # cachix.pull = [ "pre-commit-hooks" ]; + # cachix.push = "NAME"; # ------------------------ # --- PRE-COMMIT HOOKS --- @@ -77,18 +87,16 @@ # https://devenv.sh/reference/options/#pre-commithooks pre-commit = { hooks = { - treefmt.enable = true; - # We pass our custom treefmt build from parts/treefmt/treefmt.nix for - # devenv to use. - treefmt.package = treefmt; + treefmt.enable = if (treefmt-wrapper != null) then true else false; + treefmt.package = if (treefmt-wrapper != null) then treefmt-wrapper else pkgs.treefmt; nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. - editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig markdownlint.enable = true; # Markdown lint tool # typos.enable = true; # Source code spell checker # actionlint.enable = true; # GitHub workflows linting # commitizen.enable = true; # Commitizen is release management tool designed for teams. + editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig }; }; diff --git a/flake-parts/devenv/meta.nix b/flake-parts/devenv/meta.nix new file mode 100644 index 0000000..f50ae61 --- /dev/null +++ b/flake-parts/devenv/meta.nix @@ -0,0 +1,19 @@ +{ + description = "Flake bindings for the `github:cachix/devenv` development environment."; + + inputs = { + devenv.url = "github:cachix/devenv"; + devenv-root = { + url = "file+file:///dev/null"; + flake = false; + }; + mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; + nix2container = { + url = "github:nlewo/nix2container"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + conflicts = [ "shells" ]; + extraTrustedPublicKeys = [ "https://devenv.cachix.org" ]; + extraSubstituters = [ "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" ]; +} diff --git a/flake-parts/flake-root/flake-parts/flake-root.nix b/flake-parts/flake-root/flake-parts/flake-root.nix new file mode 100644 index 0000000..081537e --- /dev/null +++ b/flake-parts/flake-root/flake-parts/flake-root.nix @@ -0,0 +1,14 @@ +# --- flake-parts/flake-root.nix +{ lib, ... }: +{ + # NOTE This is probably conflicting with https://github.com/srid/flake-root/ + # however it essentially fully replaces that functionality with a simple + # option (thanks to the known structure) so it should be probably fine. + options.flake-root = lib.mkOption { + type = lib.types.path; + description = '' + Provides `config.flake-root` with the path to the flake root. + ''; + default = ../.; + }; +} diff --git a/flake-parts/flake-root/meta.nix b/flake-parts/flake-root/meta.nix new file mode 100644 index 0000000..98da1ca --- /dev/null +++ b/flake-parts/flake-root/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Provides `config.flake-root` variable pointing to the root of the flake project."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gh-actions-cachix/.github/workflows/cachix-push.yml b/flake-parts/gh-actions-cachix/.github/workflows/cachix-push.yml new file mode 100644 index 0000000..98d21e1 --- /dev/null +++ b/flake-parts/gh-actions-cachix/.github/workflows/cachix-push.yml @@ -0,0 +1,36 @@ +name: "Push packages and devshells to the cachix binary cache service" + +on: + push: + branches: + - main + +jobs: + flake-check: + if: false + runs-on: "ubuntu-latest" + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Settings up cachix binary cache..." + uses: cachix/cachix-action@main + with: + name: mycache + # If you chose signing key for write access + signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' + # If you chose API tokens for write access OR if you have a private cache + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + + - name: "Building project packages..." + run: nix build + + - name: "Building project devshells..." + run: nix develop --command echo OK + diff --git a/flake-parts/gh-actions-cachix/meta.nix b/flake-parts/gh-actions-cachix/meta.nix new file mode 100644 index 0000000..41d10fa --- /dev/null +++ b/flake-parts/gh-actions-cachix/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds a simple cachix/cachix-action GitHub action workflow."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gh-actions-check/.github/workflows/flake-check.yml b/flake-parts/gh-actions-check/.github/workflows/flake-check.yml new file mode 100644 index 0000000..25c6355 --- /dev/null +++ b/flake-parts/gh-actions-check/.github/workflows/flake-check.yml @@ -0,0 +1,30 @@ +name: "Run `nix flake-check`" + +on: + push: + branches: + - main + pull_request: + types: [opened, reopened, synchronize] + repository_dispatch: + types: [create-pull-request] + +jobs: + flake-check: + if: false + runs-on: "ubuntu-latest" + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Running `nix flake check`..." + run: nix flake check --show-trace --accept-flake-config + + - name: "Checking flake inputs for stale & insecure nixpkgs versions..." + uses: DeterminateSystems/flake-checker-action@main diff --git a/flake-parts/gh-actions-check/meta.nix b/flake-parts/gh-actions-check/meta.nix new file mode 100644 index 0000000..55fb042 --- /dev/null +++ b/flake-parts/gh-actions-check/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds a simple `nix flake check` GitHub action workflow."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gh-actions-flake-update/.github/workflows/update-flake-lock.yml b/flake-parts/gh-actions-flake-update/.github/workflows/update-flake-lock.yml new file mode 100644 index 0000000..4423840 --- /dev/null +++ b/flake-parts/gh-actions-flake-update/.github/workflows/update-flake-lock.yml @@ -0,0 +1,33 @@ +name: "Periodically update flake inputs in flake.lock" + +on: + workflow_dispatch: # allows manual triggering + schedule: + - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 + +jobs: + update-flake-lock: + runs-on: ubuntu-latest + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Updating flake.lock..." + uses: DeterminateSystems/update-flake-lock@main + with: + pr-title: "Automated action - Update flake.lock" + pr-labels: | + dependencies + automated + + # NOTE You can use a personal access token to identify + # as a concrete user, this may be useful when you want to + # trigger additional CI actions. + # + # token: ${{ secrets.GH_TOKEN_FOR_UPDATES }} diff --git a/flake-parts/gh-actions-flake-update/meta.nix b/flake-parts/gh-actions-flake-update/meta.nix new file mode 100644 index 0000000..08cb8e0 --- /dev/null +++ b/flake-parts/gh-actions-flake-update/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds the periodic `DeterminateSystems/update-flake-lock` GitHub action workflow."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gh-actions-flakehub/.github/workflows/flakehub-publish.yml b/flake-parts/gh-actions-flakehub/.github/workflows/flakehub-publish.yml new file mode 100644 index 0000000..fe18e92 --- /dev/null +++ b/flake-parts/gh-actions-flakehub/.github/workflows/flakehub-publish.yml @@ -0,0 +1,29 @@ +name: "Publish flake to FlakeHub" + +on: + push: + branches: + - main + +jobs: + flakehub-publish: + runs-on: "ubuntu-latest" + permissions: + id-token: "write" + contents: "read" + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Publishing flake to FlakeHub..." + uses: DeterminateSystems/flakehub-push@main + with: + name: "organization/NAMEPLACEHOLDER" # TODO: add info + rolling: true + visibility: "public" diff --git a/flake-parts/gh-actions-flakehub/meta.nix b/flake-parts/gh-actions-flakehub/meta.nix new file mode 100644 index 0000000..8fb36c8 --- /dev/null +++ b/flake-parts/gh-actions-flakehub/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds the push to FlakeHub GitHub action workflow."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gh-actions-pages/.github/workflows/pages.yml b/flake-parts/gh-actions-pages/.github/workflows/pages.yml new file mode 100644 index 0000000..c104597 --- /dev/null +++ b/flake-parts/gh-actions-pages/.github/workflows/pages.yml @@ -0,0 +1,48 @@ +name: "Deploy static content to GitHub Pages" + +on: + workflow_dispatch: + push: + branches: + - main + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run +# in-progress and latest queued. However, do NOT cancel in-progress runs as +# we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + pages: + runs-on: ubuntu-latest + steps: + - name: "Checking out repository..." + uses: actions/checkout@v4 + + - name: "Installing and configuring the nix package manager..." + uses: DeterminateSystems/nix-installer-action@main + + - name: "Setting up magic-nix-cache..." + uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Building static content using `nix build .#pages`..." + run: nix build .#pages + + - name: "Setting up GitHub Pages..." + uses: actions/configure-pages@v3 + + - name: "Uploading static content..." + uses: actions/upload-pages-artifact@v2 + with: + path: "result" + + - name: "Deploying static content to GitHub Pages..." + id: deployment + uses: actions/deploy-pages@v2 diff --git a/flake-parts/gh-actions-pages/meta.nix b/flake-parts/gh-actions-pages/meta.nix new file mode 100644 index 0000000..da8ba58 --- /dev/null +++ b/flake-parts/gh-actions-pages/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds a GitHub action that runs `nix build .#pages` and deploys the result to GitHub pages."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/templates/home/.github/pull_request_template.md b/flake-parts/gh-templates-PR/.github/pull_request_template.md similarity index 60% rename from templates/home/.github/pull_request_template.md rename to flake-parts/gh-templates-PR/.github/pull_request_template.md index c3811fd..4dd4a55 100644 --- a/templates/home/.github/pull_request_template.md +++ b/flake-parts/gh-templates-PR/.github/pull_request_template.md @@ -1,5 +1,3 @@ -# TODO: Place a short descriptive PR name here - ## Overview -## Dependencies (flake inputs) +## Dependencies ## Screenshots -- \[ \] I have tested the relevant changes locally. -- \[ \] I have checked that - `nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD")` - passes. -- \[ \] I have ensured my commits follow the project's commits guidelines. -- \[ \] I have checked that the changes follow a linear history. -- \[ \] (If applicable) I have commented any relevant parts of my code. -- \[ \] (If applicable) I have added appropriate unit/feature tests. -- \[ \] (If applicable) I have updated the documentation accordingly (in English). +- [ ] I have tested the relevant changes locally. +- [ ] I have checked that `nix flake check` passes. +- [ ] I have ensured my commits follow the project's commits guidelines. +- [ ] I have checked that the changes follow a linear history. +- [ ] (If applicable) I have commented any relevant parts of my code. +- [ ] (If applicable) I have added appropriate unit/feature tests. +- [ ] (If applicable) I have updated the documentation accordingly (in English). ## Additional Notes diff --git a/flake-parts/gh-templates-PR/meta.nix b/flake-parts/gh-templates-PR/meta.nix new file mode 100644 index 0000000..1bfbfeb --- /dev/null +++ b/flake-parts/gh-templates-PR/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds a basic GitHub pull request template."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gh-templates-issues/.github/ISSUE_TEMPLATE/bug_report.md b/flake-parts/gh-templates-issues/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..46f629e --- /dev/null +++ b/flake-parts/gh-templates-issues/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,45 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +## Describe the bug +A clear and concise description of what the bug is. + +## Steps To Reproduce +Steps to reproduce the behavior: +1. ... +2. ... +3. ... + +## Expected behavior +A clear and concise description of what you expected to happen. + +## Screenshots +If applicable, add screenshots to help explain your problem. + +## Additional context +Add any other context about the problem here. + +## Notify maintainers + + + +## Metadata +Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result. + +```console +[user@system:~]$ nix-shell -p nix-info --run "nix-info -m" +output here +``` + +--- + +Add a :+1: [reaction] to [issues you find important]. diff --git a/flake-parts/gh-templates-issues/.github/ISSUE_TEMPLATE/feature_request.md b/flake-parts/gh-templates-issues/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3b32cee --- /dev/null +++ b/flake-parts/gh-templates-issues/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: feature-request +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. + +--- + +Add a :+1: [reaction] to [issues you find important]. diff --git a/flake-parts/gh-templates-issues/meta.nix b/flake-parts/gh-templates-issues/meta.nix new file mode 100644 index 0000000..028b1eb --- /dev/null +++ b/flake-parts/gh-templates-issues/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds basic bug/feature GitHub issue templates."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/gitlab-ci-check/.gitlab-ci.yml b/flake-parts/gitlab-ci-check/.gitlab-ci.yml new file mode 100644 index 0000000..359c866 --- /dev/null +++ b/flake-parts/gitlab-ci-check/.gitlab-ci.yml @@ -0,0 +1,13 @@ +image: nixos/nix:latest + +variables: + NIX_CONF_DIR: "/etc/nix" + +before_script: + - echo 'experimental-features = nix-command flakes' > $NIX_CONF_DIR/nix.conf + +flake-check: + script: + - nix flake check --show-trace --accept-flake-config + rules: + - if: '$CI_COMMIT_BRANCH == "main" || $CI_PIPELINE_SOURCE == "merge_request_event"' diff --git a/flake-parts/gitlab-ci-check/meta.nix b/flake-parts/gitlab-ci-check/meta.nix new file mode 100644 index 0000000..341c299 --- /dev/null +++ b/flake-parts/gitlab-ci-check/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Adds a simple `nix flake check` to your GitLab CI/CD pipeline."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/hm-homes/flake-parts/homes/default.nix b/flake-parts/hm-homes/flake-parts/homes/default.nix new file mode 100644 index 0000000..03742a3 --- /dev/null +++ b/flake-parts/hm-homes/flake-parts/homes/default.nix @@ -0,0 +1,60 @@ +# --- flake-parts/homes/default.nix +{ + lib, + inputs, + withSystem, + config, + ... +}: +let + mkHome = + args: home: + { + extraSpecialArgs ? { }, + extraModules ? [ ], + extraOverlays ? [ ], + ... + }: + inputs.home-manager.lib.homeManagerConfiguration { + inherit (args) pkgs; + extraSpecialArgs = { + inherit (args) system; + inherit inputs home; + } // extraSpecialArgs; + modules = [ + { + nixpkgs.overlays = extraOverlays; + nixpkgs.config.allowUnfree = true; + } + ./${home} + ] ++ extraModules; + # NOTE You can also load all of your defined modules in the + # following manner + # + # ++ (lib.attrValues config.flake.homeModules); + }; +in +{ + options.flake.homeConfigurations = lib.mkOption { + type = with lib.types; lazyAttrsOf unspecified; + default = { }; + }; + + config = { + flake.homeConfigurations = { + # "myUser@myHost" = withSystem "x86_64-linux" ( + # args: + # mkHome args "myUser@myHost" { + # extraOverlays = with inputs; [ + # neovim-nightly-overlay.overlays.default + # (final: _prev: { nur = import inputs.nur { pkgs = final; }; }) + # ]; + # } + # ); + }; + + flake.checks."x86_64-linux" = { + # "home-myUser@myHost" = config.flake.homeConfigurations."myUser@myHost".config.home.path; + }; + }; +} diff --git a/flake-parts/hm-homes/meta.nix b/flake-parts/hm-homes/meta.nix new file mode 100644 index 0000000..ca630d0 --- /dev/null +++ b/flake-parts/hm-homes/meta.nix @@ -0,0 +1,12 @@ +{ + description = "Template for your HM homes and a handy generator for you `homeManagerConfiguration` calls."; + + inputs = { + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/hm-modules/flake-parts/modules/home-manager/default.nix b/flake-parts/hm-modules/flake-parts/modules/home-manager/default.nix new file mode 100644 index 0000000..4e7787b --- /dev/null +++ b/flake-parts/hm-modules/flake-parts/modules/home-manager/default.nix @@ -0,0 +1,26 @@ +# --- flake-parts/modules/home-manager/default.nix +{ + lib, + inputs, + self, + ... +}: +let + inherit (inputs.flake-parts.lib) importApply; + localFlake = self; +in +{ + options.flake.homeModules = lib.mkOption { + type = with lib.types; lazyAttrsOf unspecified; + default = { }; + }; + + config.flake.homeModules = { + # NOTE Dogfooding your modules with `importApply` will make them more + # reusable even outside of your flake. For more info see + # https://flake.parts/dogfood-a-reusable-module#example-with-importapply + + # programs_myProgram = importApply ./programs/myProgram { inherit localFlake; }; + # services_myService = importApply ./services/myService { inherit localFlake inputs; }; + }; +} diff --git a/flake-parts/hm-modules/meta.nix b/flake-parts/hm-modules/meta.nix new file mode 100644 index 0000000..129e82c --- /dev/null +++ b/flake-parts/hm-modules/meta.nix @@ -0,0 +1,12 @@ +{ + description = "Basic template for custom home-manager modules."; + + inputs = { + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/lib/flake-parts/lib/default.nix b/flake-parts/lib/flake-parts/lib/default.nix new file mode 100644 index 0000000..c11da19 --- /dev/null +++ b/flake-parts/lib/flake-parts/lib/default.nix @@ -0,0 +1,16 @@ +# --- flake-parts/lib/default.nix +{ + inputs, + lib, + self, + ... +}: +let + localFlake = self; +in +{ + flake.lib = { + # modules = import ./modules { inherit localFlake lib inputs; }; + # functions = import ./functions { inherit localFlake lib; }; + }; +} diff --git a/flake-parts/lib/meta.nix b/flake-parts/lib/meta.nix new file mode 100644 index 0000000..e2cd4fb --- /dev/null +++ b/flake-parts/lib/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Basic template for custom nix library functions."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/nix-topology/flake-parts/nix-topology/default.nix b/flake-parts/nix-topology/flake-parts/nix-topology/default.nix new file mode 100644 index 0000000..2e4d990 --- /dev/null +++ b/flake-parts/nix-topology/flake-parts/nix-topology/default.nix @@ -0,0 +1,23 @@ +# --- flake-parts/nix-topology/default.nix +{ + inputs, + lib, + self, + ... +}: +let + inherit (inputs.flake-parts.lib) importApply; + localFlake = self; +in +{ + imports = with inputs; [ nix-topology.flakeModule ]; + + perSystem = + { ... }: + { + topology.modules = [ + { inherit (localFlake) nixosConfigurations; } + (importApply ./topology.nix { inherit localFlake; }) + ]; + }; +} diff --git a/flake-parts/nix-topology/flake-parts/nix-topology/topology.nix b/flake-parts/nix-topology/flake-parts/nix-topology/topology.nix new file mode 100644 index 0000000..41f0d29 --- /dev/null +++ b/flake-parts/nix-topology/flake-parts/nix-topology/topology.nix @@ -0,0 +1,42 @@ +# --- flake-parts/nix-topology/topology.nix +{ localFlake }: +{ config, ... }: +let + inherit (config.lib.topology) + mkInternet + mkRouter + mkSwitch + mkConnection + ; +in +{ + # Add a node for the internet + nodes.internet = mkInternet { connections = mkConnection "router" "wan1"; }; + + # Add a router that we use to access the internet + nodes.router = mkRouter "Example Router" { + info = "Example Router"; + # image = ./images/fritzbox.png; + interfaceGroups = [ + [ + "eth1" + "eth2" + "eth3" + "eth4" + "wifi" + ] + [ "wan1" ] + ]; + connections.eth1 = mkConnection "exampleHost1" "eth0"; + connections.wifi = mkConnection "exampleHost2" "wlp3s0"; + interfaces.eth1 = { + addresses = [ "192.168.0.1" ]; + network = "home"; + }; + }; + + networks.home = { + name = "Home"; + cidrv4 = "192.168.0.0/24"; + }; +} diff --git a/flake-parts/nix-topology/meta.nix b/flake-parts/nix-topology/meta.nix new file mode 100644 index 0000000..265d63c --- /dev/null +++ b/flake-parts/nix-topology/meta.nix @@ -0,0 +1,10 @@ +{ + description = "Adds bindings for the `github:oddlama/nix-topology` project to generate graphs of your networks."; + + inputs = { + nix-topology.url = "github:oddlama/nix-topology"; + }; + conflicts = [ ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/nixos-hosts/flake-parts/hosts/default.nix b/flake-parts/nixos-hosts/flake-parts/hosts/default.nix new file mode 100644 index 0000000..b6ac1bf --- /dev/null +++ b/flake-parts/nixos-hosts/flake-parts/hosts/default.nix @@ -0,0 +1,80 @@ +# --- flake-parts/hosts/default.nix +{ + lib, + inputs, + withSystem, + config, + ... +}: +let + mkHost = + args: hostName: + { + extraSpecialArgs ? { }, + extraModules ? [ ], + extraOverlays ? [ ], + withHomeManager ? false, + ... + }: + let + baseSpecialArgs = { + inherit (args) system; + inherit inputs hostName; + } // extraSpecialArgs; + in + inputs.nixpkgs.lib.nixosSystem { + inherit (args) system; + specialArgs = baseSpecialArgs // { + inherit lib hostName; + host.hostName = hostName; + }; + modules = + [ + { + nixpkgs.overlays = extraOverlays; + nixpkgs.config.allowUnfree = true; + networking.hostName = hostName; + } + ./${hostName} + ] + ++ extraModules + # NOTE You can also load all of your defined modules in the + # following manner + # + # ++ (lib.attrValues config.flake.nixosModules) + ++ ( + if (withHomeManager && (lib.hasAttr "home-manager" inputs)) then + [ + inputs.home-manager.nixosModules.home-manager + { + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + extraSpecialArgs = baseSpecialArgs; + + # NOTE You can also load all of your defined modules in the + # following manner + # + # sharedModules = lib.attrValues config.flake.homeModules; + }; + } + ] + else + [ ] + ); + }; +in +{ + flake.nixosConfigurations = { + # myExampleHost = withSystem "x86_64-linux" ( + # args: + # mkHost args "spinorbundle" { + # withHomeManager = true; + # extraOverlays = with inputs; [ + # neovim-nightly-overlay.overlays.default + # (final: _prev: { nur = import inputs.nur { pkgs = final; }; }) + # ]; + # } + # ); + }; +} diff --git a/flake-parts/nixos-hosts/meta.nix b/flake-parts/nixos-hosts/meta.nix new file mode 100644 index 0000000..c1b1bf0 --- /dev/null +++ b/flake-parts/nixos-hosts/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Template for your NixOS hosts and a handy generator for `lib.nixosSystem` calls."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/nixos-modules/flake-parts/modules/nixos/default.nix b/flake-parts/nixos-modules/flake-parts/modules/nixos/default.nix new file mode 100644 index 0000000..92f5627 --- /dev/null +++ b/flake-parts/nixos-modules/flake-parts/modules/nixos/default.nix @@ -0,0 +1,16 @@ +{ inputs, self, ... }: +let + inherit (inputs.flake-parts.lib) importApply; + localFlake = self; +in +{ + flake.nixosModules = { + + # NOTE Dogfooding your modules with `importApply` will make them more + # reusable even outside of your flake. For more info see + # https://flake.parts/dogfood-a-reusable-module#example-with-importapply + + # programs_myProgram = importApply ./programs/myProgram.nix { inherit localFlake; }; + # services_myService = importApply ./services/myService.nix { inherit localFlake inputs; }; + }; +} diff --git a/flake-parts/nixos-modules/meta.nix b/flake-parts/nixos-modules/meta.nix new file mode 100644 index 0000000..0768a79 --- /dev/null +++ b/flake-parts/nixos-modules/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Basic template for custom NixOS modules."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/overlays/flake-parts/overlays/default.nix b/flake-parts/overlays/flake-parts/overlays/default.nix new file mode 100644 index 0000000..a885c4b --- /dev/null +++ b/flake-parts/overlays/flake-parts/overlays/default.nix @@ -0,0 +1,12 @@ +# --- flake-parts/overlays/default.nix +{ inputs, self, ... }: +let + localFlake = self; +in +{ + flake.overlays = { + # myOverlay = final: prev: { + # myCustomSet = {}; + # }; + }; +} diff --git a/flake-parts/overlays/meta.nix b/flake-parts/overlays/meta.nix new file mode 100644 index 0000000..74b5aad --- /dev/null +++ b/flake-parts/overlays/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Basic template for custom nixpkgs overlays."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/pkgs/flake-parts/pkgs/default.nix b/flake-parts/pkgs/flake-parts/pkgs/default.nix new file mode 100644 index 0000000..118bc19 --- /dev/null +++ b/flake-parts/pkgs/flake-parts/pkgs/default.nix @@ -0,0 +1,11 @@ +# --- flake-parts/pkgs/default.nix +{ ... }: +{ + perSystem = + { pkgs, ... }: + { + packages = { + # my-custom-package = pkgs.callPackage ./my-custom-package.nix { }; + }; + }; +} diff --git a/flake-parts/pkgs/meta.nix b/flake-parts/pkgs/meta.nix new file mode 100644 index 0000000..3a8707d --- /dev/null +++ b/flake-parts/pkgs/meta.nix @@ -0,0 +1,7 @@ +{ + description = "Basic template for custom nix packages (ie derivations)."; + + inputs = { }; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/pre-commit-hooks/flake-parts/pre-commit-hooks.nix b/flake-parts/pre-commit-hooks/flake-parts/pre-commit-hooks.nix new file mode 100644 index 0000000..3a47ac7 --- /dev/null +++ b/flake-parts/pre-commit-hooks/flake-parts/pre-commit-hooks.nix @@ -0,0 +1,37 @@ +# --- flake-parts/pre-commit-hooks.nix +{ inputs, lib, ... }: +{ + imports = with inputs; [ pre-commit-hooks.flakeModule ]; + + perSystem = + { config, pkgs, ... }: + { + pre-commit.settings = + let + treefmt-wrapper = if (lib.hasAttr "treefmt" config) then config.treefmt.build.wrapper else null; + in + { + excludes = [ "flake.lock" ]; + + hooks = { + treefmt.enable = if (treefmt-wrapper != null) then true else false; + treefmt.package = if (treefmt-wrapper != null) then treefmt-wrapper else pkgs.treefmt; + + nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. + markdownlint.enable = true; # Markdown lint tool + # typos.enable = true; # Source code spell checker + + actionlint.enable = true; # GitHub workflows linting + commitizen.enable = true; # Commitizen is release management tool designed for teams. + editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig + + gitleaks = { + enable = true; + name = "gitleaks"; + entry = "${pkgs.gitleaks}/bin/gitleaks protect --verbose --redact --staged"; + pass_filenames = false; + }; + }; + }; + }; +} diff --git a/flake-parts/pre-commit-hooks/meta.nix b/flake-parts/pre-commit-hooks/meta.nix new file mode 100644 index 0000000..1908228 --- /dev/null +++ b/flake-parts/pre-commit-hooks/meta.nix @@ -0,0 +1,12 @@ +{ + description = "Bindings for pre-commit-hooks.nix and a simple pre-commit-hook template."; + + inputs = { + pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix"; + }; + conflicts = [ "devenv" ]; + extraTrustedPublicKeys = [ + "pre-commit-hooks.cachix.org-1:Pkk3Panw5AW24TOv6kz3PvLhlH8puAsJTBbOPmBo7Rc=" + ]; + extraSubstituters = [ "https://pre-commit-hooks.cachix.org/" ]; +} diff --git a/flake-parts/process-compose-flake/flake-parts/process-compose-flake/default.nix b/flake-parts/process-compose-flake/flake-parts/process-compose-flake/default.nix new file mode 100644 index 0000000..bd78349 --- /dev/null +++ b/flake-parts/process-compose-flake/flake-parts/process-compose-flake/default.nix @@ -0,0 +1,15 @@ +# --- flake-parts/process-compose-flake/default.nix +{ inputs, lib, ... }: +{ + imports = with inputs; [ process-compose-flake.flakeModule ]; + + perSystem = + { pkgs, ... }: + { + process-compose = rec { + default = dev-process; + + dev-process = import ./dev.nix { inherit pkgs lib; }; + }; + }; +} diff --git a/flake-parts/process-compose-flake/flake-parts/process-compose-flake/dev.nix b/flake-parts/process-compose-flake/flake-parts/process-compose-flake/dev.nix new file mode 100644 index 0000000..23934be --- /dev/null +++ b/flake-parts/process-compose-flake/flake-parts/process-compose-flake/dev.nix @@ -0,0 +1,25 @@ +# --- flake-parts/process-compose-flake/dev.nix +{ pkgs, lib }: +{ + # For more info about the process-compose format seek + # https://github.com/Platonic-Systems/process-compose-flake + settings = { + environment = { + MY_ENV_VAR = "Hello from process-compose!"; + }; + + processes = { + hello.command = '' + ${lib.getExe pkgs.hello} -g $MY_ENV_VAR + ''; + }; + }; + + preHook = '' + echo "Running preHook" + ''; + + postHook = '' + echo "Running postHook" + ''; +} diff --git a/flake-parts/process-compose-flake/meta.nix b/flake-parts/process-compose-flake/meta.nix new file mode 100644 index 0000000..70c2b4a --- /dev/null +++ b/flake-parts/process-compose-flake/meta.nix @@ -0,0 +1,11 @@ +{ + description = "Bindings for process-compose-flake and a simple process-compose template."; + + inputs = { + process-compose-flake.url = "github:Platonic-Systems/process-compose-flake"; + }; + + conflicts = [ "devenv" ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/shells/flake-parts/shells/default.nix b/flake-parts/shells/flake-parts/shells/default.nix new file mode 100644 index 0000000..a23fb1f --- /dev/null +++ b/flake-parts/shells/flake-parts/shells/default.nix @@ -0,0 +1,18 @@ +# --- flake-parts/shells/default.nix +{ lib, ... }: +{ + perSystem = + { pkgs, config, ... }: + { + devShells = rec { + default = dev; + + dev = pkgs.callPackage ./dev.nix { + inherit lib; + treefmt-wrapper = if (lib.hasAttr "treefmt" config) then config.treefmt.build.wrapper else null; + dev-process = if (lib.hasAttr "process-compose" config) then config.packages.dev-process else null; + pre-commit = if (lib.hasAttr "pre-commit" config) then config.pre-commit else null; + }; + }; + }; +} diff --git a/flake-parts/shells/flake-parts/shells/dev.nix b/flake-parts/shells/flake-parts/shells/dev.nix new file mode 100644 index 0000000..a83ef13 --- /dev/null +++ b/flake-parts/shells/flake-parts/shells/dev.nix @@ -0,0 +1,64 @@ +# --- flake-parts/shells/dev.nix +{ + lib, + mkShell, + nil, + statix, + deadnix, + nix-output-monitor, + nixfmt-rfc-style, + markdownlint-cli, + writeShellScriptBin, + treefmt-wrapper ? null, + dev-process ? null, + pre-commit ? null, +}: +let + scripts = { + rename-project = writeShellScriptBin "rename-project" '' + find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/NAMEPLACEHOLDER/$2/g" + ''; + }; + + env = { + # MY_ENV_VAR = "Hello, World!"; + # MY_OTHER_ENV_VAR = "Goodbye, World!"; + }; +in +mkShell { + + packages = + (lib.attrValues scripts) + ++ (lib.optional (treefmt-wrapper != null) treefmt-wrapper) + ++ (lib.optional (dev-process != null) dev-process) + ++ [ + # -- NIX UTILS -- + nil # Yet another language server for Nix + statix # Lints and suggestions for the nix programming language + deadnix # Find and remove unused code in .nix source files + nix-output-monitor # Processes output of Nix commands to show helpful and pretty information + nixfmt-rfc-style # An opinionated formatter for Nix + + # -- GIT RELATED UTILS -- + # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs + # cz-cli # The commitizen command line utility + # fh # The official FlakeHub CLI + # gh # GitHub CLI tool + # gh-dash # Github Cli extension to display a dashboard with pull requests and issues + + # -- BASE LANG UTILS -- + markdownlint-cli # Command line interface for MarkdownLint + # nodePackages.prettier # Prettier is an opinionated code formatter + # typos # Source code spell checker + + # -- (YOUR) EXTRA PKGS -- + ]; + + shellHook = '' + ${lib.concatLines (lib.mapAttrsToList (name: value: "export ${name}=${value}") env)} + ${lib.optionalString (pre-commit != null) pre-commit.installationScript} + + # Welcome splash text + echo ""; echo -e "\e[1;37;42mWelcome to the NAMEPLACEHOLDER devshell!\e[0m"; echo "" + ''; +} diff --git a/flake-parts/shells/meta.nix b/flake-parts/shells/meta.nix new file mode 100644 index 0000000..0642262 --- /dev/null +++ b/flake-parts/shells/meta.nix @@ -0,0 +1,9 @@ +{ + description = "Basic template for custom nix devshells (ie. `mkShell` calls) with potential bindings to other parts."; + + inputs = { }; + + conflicts = [ "devenv" ]; + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/systems/flake-parts/systems.nix b/flake-parts/systems/flake-parts/systems.nix new file mode 100644 index 0000000..6adecc1 --- /dev/null +++ b/flake-parts/systems/flake-parts/systems.nix @@ -0,0 +1,9 @@ +# --- flake-parts/systems.nix +{ inputs, ... }: +{ + # NOTE We use the default `systems` defined by the `nix-systems` flake, if + # you need any additional systems, simply add them in the following manner + # + # `systems = (import inputs.systems) ++ [ "armv7l-linux" ];` + systems = import inputs.systems; +} diff --git a/flake-parts/systems/meta.nix b/flake-parts/systems/meta.nix new file mode 100644 index 0000000..1eb65c3 --- /dev/null +++ b/flake-parts/systems/meta.nix @@ -0,0 +1,10 @@ +{ + description = "Sets up the default `systems` of flake-parts using `github:nix-systems/default`."; + + inputs = { + systems.url = "github:nix-systems/default"; + }; + + extraTrustedPublicKeys = [ ]; + extraSubstituters = [ ]; +} diff --git a/flake-parts/treefmt/flake-parts/treefmt.nix b/flake-parts/treefmt/flake-parts/treefmt.nix new file mode 100644 index 0000000..be6d9e2 --- /dev/null +++ b/flake-parts/treefmt/flake-parts/treefmt.nix @@ -0,0 +1,37 @@ +# --- flake-parts/treefmt.nix +{ config, inputs, ... }: +{ + imports = with inputs; [ treefmt-nix.flakeModule ]; + + perSystem = + { pkgs, ... }: + { + treefmt = { + # treefmt is a formatting tool that saves you time: it provides + # developers with a universal way to trigger all formatters needed for the + # project in one place. + # For more information refer to + # + # - https://numtide.github.io/treefmt/ + # - https://github.com/numtide/treefmt-nix + package = pkgs.treefmt; + flakeCheck = true; + flakeFormatter = true; + projectRootFile = config.flake-root + "/flake.nix"; + + programs = { + deadnix.enable = true; # Find and remove unused code in .nix source files + statix.enable = true; # Lints and suggestions for the nix programming language + nixfmt-rfc-style.enable = true; # An opinionated formatter for Nix + # NOTE Choose a different formatter if you'd like to + # nixfmt.enable = true; # An opinionated formatter for Nix + # alejandra.enable = true; # The Uncompromising Nix Code Formatter + + # prettier.enable = true; # Prettier is an opinionated code formatter + # mdformat.enable = true; # CommonMark compliant Markdown formatter + # yamlfmt.enable = true; # An extensible command line tool or library to format yaml files. + # jsonfmt.enable = true; # Formatter for JSON files + }; + }; + }; +} diff --git a/flake-parts/treefmt/meta.nix b/flake-parts/treefmt/meta.nix new file mode 100644 index 0000000..8eb770f --- /dev/null +++ b/flake-parts/treefmt/meta.nix @@ -0,0 +1,11 @@ +{ + description = "Bindings for the treefmt formatter and a basic treefmt configuration."; + + inputs = { + treefmt-nix.url = "github:numtide/treefmt-nix"; + }; + + dependencies = [ "flake-root" ]; + extraTrustedPublicKeys = [ "numtide.cachix.org-1:2ps1kLBUWjxIneOy1Ik6cQjb41X0iXVXeHigGmycPPE=" ]; + extraSubstituters = [ "https://numtide.cachix.org" ]; +} diff --git a/flake.lock b/flake.lock index 99a6af8..782f7ae 100644 --- a/flake.lock +++ b/flake.lock @@ -1,132 +1,5 @@ { "nodes": { - "cachix": { - "inputs": { - "devenv": "devenv_2", - "flake-compat": [ - "devenv", - "flake-compat" - ], - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "pre-commit-hooks": [ - "devenv", - "pre-commit-hooks" - ] - }, - "locked": { - "lastModified": 1712055811, - "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", - "owner": "cachix", - "repo": "cachix", - "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "cachix", - "type": "github" - } - }, - "devenv": { - "inputs": { - "cachix": "cachix", - "flake-compat": "flake-compat_2", - "nix": "nix_2", - "nixpkgs": "nixpkgs_2", - "pre-commit-hooks": "pre-commit-hooks" - }, - "locked": { - "lastModified": 1717877408, - "narHash": "sha256-b6jYnB7nirdK9HRMmiDTN7XVrrUhVKhV9cruGAWTgYU=", - "owner": "cachix", - "repo": "devenv", - "rev": "3712faee803709cbbba8b0f397b9d82d77a2e1de", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "devenv-root": { - "flake": false, - "locked": { - "narHash": "sha256-d6xi4mKdjkX2JFicDIv5niSzpyI0m/Hnm8GGAIU04kY=", - "type": "file", - "url": "file:///dev/null" - }, - "original": { - "type": "file", - "url": "file:///dev/null" - } - }, - "devenv_2": { - "inputs": { - "flake-compat": [ - "devenv", - "cachix", - "flake-compat" - ], - "nix": "nix", - "nixpkgs": "nixpkgs", - "poetry2nix": "poetry2nix", - "pre-commit-hooks": [ - "devenv", - "cachix", - "pre-commit-hooks" - ] - }, - "locked": { - "lastModified": 1708704632, - "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", - "owner": "cachix", - "repo": "devenv", - "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "python-rewrite", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -145,207 +18,18 @@ "type": "github" } }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_3": { - "inputs": { - "systems": "systems_3" - }, - "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "devenv", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "mk-shell-bin": { - "locked": { - "lastModified": 1677004959, - "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", - "owner": "rrbutani", - "repo": "nix-mk-shell-bin", - "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", - "type": "github" - }, - "original": { - "owner": "rrbutani", - "repo": "nix-mk-shell-bin", - "type": "github" - } - }, - "nix": { - "inputs": { - "flake-compat": "flake-compat", - "nixpkgs": [ - "devenv", - "cachix", - "devenv", - "nixpkgs" - ], - "nixpkgs-regression": "nixpkgs-regression" - }, - "locked": { - "lastModified": 1712911606, - "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", - "owner": "domenkozar", - "repo": "nix", - "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.21", - "repo": "nix", - "type": "github" - } - }, - "nix-github-actions": { - "inputs": { - "nixpkgs": [ - "devenv", - "cachix", - "devenv", - "poetry2nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1688870561, - "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", - "owner": "nix-community", - "repo": "nix-github-actions", - "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "nix-github-actions", - "type": "github" - } - }, - "nix2container": { - "inputs": { - "flake-utils": "flake-utils_3", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1712990762, - "narHash": "sha256-hO9W3w7NcnYeX8u8cleHiSpK2YJo7ecarFTUlbybl7k=", - "owner": "nlewo", - "repo": "nix2container", - "rev": "20aad300c925639d5d6cbe30013c8357ce9f2a2e", - "type": "github" - }, - "original": { - "owner": "nlewo", - "repo": "nix2container", - "type": "github" - } - }, - "nix_2": { - "inputs": { - "flake-compat": [ - "devenv", - "flake-compat" - ], - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "nixpkgs-regression": "nixpkgs-regression_2" - }, - "locked": { - "lastModified": 1712911606, - "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", - "owner": "domenkozar", - "repo": "nix", - "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "devenv-2.21", - "repo": "nix", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1692808169, - "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", - "owner": "NixOS", + "lastModified": 1718160348, + "narHash": "sha256-9YrUjdztqi4Gz8n3mBuqvCkMo4ojrA6nASwyIKWMpus=", + "owner": "nixos", "repo": "nixpkgs", - "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", + "rev": "57d6973abba7ea108bac64ae7629e7431e0199b6", "type": "github" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", + "owner": "nixos", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -362,165 +46,11 @@ "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz" } }, - "nixpkgs-regression": { - "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - } - }, - "nixpkgs-regression_2": { - "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1710695816, - "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "614b4613980a522ba49f0d194531beddbb7220d3", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.11", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1713361204, - "narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=", - "owner": "cachix", - "repo": "devenv-nixpkgs", - "rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6", - "type": "github" - }, - "original": { - "owner": "cachix", - "ref": "rolling", - "repo": "devenv-nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1717602782, - "narHash": "sha256-pL9jeus5QpX5R+9rsp3hhZ+uplVHscNJh8n8VpqscM0=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "e8057b67ebf307f01bdcc8fba94d94f75039d1f6", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_4": { - "locked": { - "lastModified": 1708475490, - "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "0e74ca98a74bc7270d28838369593635a5db3260", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "poetry2nix": { - "inputs": { - "flake-utils": "flake-utils", - "nix-github-actions": "nix-github-actions", - "nixpkgs": [ - "devenv", - "cachix", - "devenv", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1692876271, - "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", - "owner": "nix-community", - "repo": "poetry2nix", - "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "poetry2nix", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": [ - "devenv", - "flake-compat" - ], - "flake-utils": "flake-utils_2", - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1713775815, - "narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, "root": { "inputs": { - "devenv": "devenv", - "devenv-root": "devenv-root", "flake-parts": "flake-parts", - "mk-shell-bin": "mk-shell-bin", - "nix2container": "nix2container", - "nixpkgs": "nixpkgs_3", - "systems": "systems_4", - "treefmt-nix": "treefmt-nix" + "nixpkgs": "nixpkgs", + "systems": "systems" } }, "systems": { @@ -537,69 +67,6 @@ "repo": "default", "type": "github" } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_4": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": "nixpkgs_4" - }, - "locked": { - "lastModified": 1717850719, - "narHash": "sha256-npYqVg+Wk4oxnWrnVG7416fpfrlRhp/lQ6wQ4DHI8YE=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "4fc1c45a5f50169f9f29f6a98a438fb910b834ed", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 5dcb8f8..7339447 100644 --- a/flake.nix +++ b/flake.nix @@ -1,227 +1,268 @@ +# --- flake.nix { - description = "PracticalFlakesTemplate - Highly opinionated nix flakes starter template that focuses on modularity."; + description = "Nix flakes interactive template builder based on flake-parts written in Rust."; inputs = { - # --- BASE DEPENDENCIES --- nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; flake-parts.url = "github:hercules-ci/flake-parts"; systems.url = "github:nix-systems/default"; - - # --- DEV DEPENDENCIES --- - devenv.url = "github:cachix/devenv"; - devenv-root = { - url = "file+file:///dev/null"; - flake = false; - }; - mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - treefmt-nix.url = "github:numtide/treefmt-nix"; - - # --- (YOUR) EXTRA DEPENDENCIES --- - }; - - # NOTE Here you can add additional binary cache substituers that you trust. - # There are also some sensible default caches commented out that you - # might consider using. - nixConfig = { - extra-substituters = [ - "https://cache.nixos.org" - "https://nix-community.cachix.org/" - "https://devenv.cachix.org" - "https://tsandrini.cachix.org" - ]; - extra-trusted-public-keys = [ - "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" - "tsandrini.cachix.org-1:t0AzIUglIqwiY+vz/WRWXrOkDZN8TwY3gk+n+UDt4gw=" - ]; }; outputs = inputs@{ flake-parts, ... }: + let + inherit (inputs.nixpkgs) lib; + + tsandrini = { + email = "tomas.sandrini@seznam.cz"; + name = "TomΓ‘Ε‘ Sandrini"; + github = "tsandrini"; + githubId = 21975189; + }; + + mkFlakeParts = + args@{ stdenv, ... }: + let + finalArgs = { + name = "flake-parts"; + version = "1.0.0"; + + dontConfigure = true; + dontBuild = true; + dontCheck = true; + + installPhase = '' + mkdir -p $out/flake-parts + cp -rv $src/* $out/flake-parts + ''; + } // args; + in + stdenv.mkDerivation finalArgs; + in flake-parts.lib.mkFlake { inherit inputs; } { - imports = with inputs; [ - treefmt-nix.flakeModule - devenv.flakeModule - ]; + systems = import inputs.systems; - flake = { - templates = - let - welcomeText = '' - Hi! You've just created a fresh new flakes project using the - practical-flakes-template. You can start by looking around or - running the development environment either via direnv (`direnv allow`) + flake.lib = rec { + inherit mkFlakeParts; - Furthermore don't forget to rename your project using - `rename-project . myAwesomeNewProject` + flatten = attrs: lib.collect (x: !lib.isAttrs x) attrs; - For more info refer to - https://github.com/tsandrini/practical-flakes-template/ - ''; - in - { - default = inputs.self.templates.main; - main = { - inherit welcomeText; - path = ./templates/main; - description = "Highly opinionated nix flakes starter template that focuses on modularity."; - }; - - minimal = { - inherit welcomeText; - path = ./templates/minimal; - description = "Minimal version of the highly opiniated nix flakes starter template."; - }; - - isolated = { - inherit welcomeText; - path = ./templates/isolated; - description = "Isolated (./nix) version of the highly opiniated nix flakes starter template."; - }; - - isolated-minimal = { - inherit welcomeText; - path = ./templates/isolated-minimal; - description = "Isolated (./nix) and minimal version of the highly opiniated nix flakes starter template."; - }; - - home = { - inherit welcomeText; - path = ./templates/home; - description = "Full version of the highly opiniated nix flakes starter template that includes prewired home-manager"; - }; - }; + mapFilterAttrs = + pred: f: attrs: + lib.filterAttrs pred (lib.mapAttrs' f attrs); + + mapModules = + dir: fn: + mapFilterAttrs (n: v: v != null && !(lib.hasPrefix "_" n) && !(lib.lib.hasPrefix ".git" n)) ( + n: v: + let + path = "${toString dir}/${n}"; + in + if v == "directory" && builtins.pathExists "${path}/default.nix" then + lib.nameValuePair n (fn path) + else if v == "directory" then + lib.nameValuePair n (mapModules path fn) + else if v == "regular" && n != "default.nix" && lib.hasSuffix ".nix" n then + lib.nameValuePair (lib.removeSuffix ".nix" n) (fn path) + else + lib.nameValuePair "" null + ) (builtins.readDir dir); + + # NOTE In case anyone ditches _bootstrap and wants to use + # load-parts directly from here. + loadParts = dir: flatten (mapModules dir (x: x)); }; perSystem = - { config, pkgs, ... }: { - treefmt = { - package = pkgs.treefmt; - flakeCheck = true; - flakeFormatter = true; - projectRootFile = ./flake.nix; - programs = { - deadnix.enable = true; - statix.enable = true; - nixfmt-rfc-style.enable = true; - # NOTE Choose a different formatter if you'd like to - # nixfmt.enable = true; - # alejandra.enable = true; - - prettier.enable = true; - mdformat.enable = true; - yamlfmt.enable = true; - jsonfmt.enable = true; - - shellcheck.enable = true; - shfmt.enable = true; - }; - }; + config, + pkgs, + system, + ... + }: + { + packages = rec { + default = builder; - devenv.shells.dev = { - - # -------------------------- - # --- ENV & SHELL & PKGS --- - # -------------------------- - packages = with pkgs; [ - # -- NIX UTILS -- - nix-output-monitor # Processes output of Nix commands to show helpful and pretty information - nixfmt-rfc-style # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt # An opinionated formatter for Nix - # alejandra # The Uncompromising Nix Code Formatter - nh # Yet another nix cli helper - - # -- GIT RELATED UTILS -- - commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs - cz-cli # The commitizen command line utility - fh # The official FlakeHub CLI - gh # GitHub CLI tool - - # -- LANGUAGE RELATED UTILS -- - markdownlint-cli # Command line interface for MarkdownLint - typos # Source code spell checker - config.treefmt.build.wrapper # one CLI to format the code tree - - # -- (YOUR) EXTRA PKGS -- - nodePackages.prettier # Prettier is an opinionated code formatter - ]; - - enterShell = '' - # Welcome splash text - echo ""; echo -e "\e[1;37;42mWelcome to the practicalFlakes devshell!\e[0m"; echo "" - ''; + builder = + let + package = + { + lib, + rustPlatform, + nixfmt-rfc-style, + tsandrini, + }: + rustPlatform.buildRustPackage { + name = "flake-parts-builder"; + version = "1.0.0"; + + src = [ + ./src + ./Cargo.toml + ./Cargo.lock + ]; + + unpackPhase = '' + runHook preUnpack + for srcItem in $src; do + if [ -d "$srcItem" ]; then + cp -r "$srcItem" $(stripHash "$srcItem") + else + cp "$srcItem" $(stripHash "$srcItem") + fi + done + runHook postUnpack + ''; + + cargoSha256 = "sha256-JYCiIbStvpmO4CO3Sp7tMHUdWpFMKiveE5ATIyK0UVo="; - # --------------- - # --- SCRIPTS --- - # --------------- - scripts = { - "rename-project".exec = '' - find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/practicalFlakes/$2/g" - ''; - }; - - # ----------------- - # --- LANGUAGES --- - # ----------------- - languages.nix.enable = true; - - # ---------------------------- - # --- PROCESSES & SERVICES --- - # ---------------------------- - - # ------------------ - # --- CONTAINERS --- - # ------------------ - devcontainer.enable = true; - - # ---------------------- - # --- BINARY CACHING --- - # ---------------------- - # NOTE All available hooks options are listed at - # https://devenv.sh/reference/options/#pre-commithooks - pre-commit = { - hooks = { - treefmt.enable = true; - # We pass our custom treefmt build from parts/treefmt/treefmt.nix for - # devenv to use. - treefmt.package = config.treefmt.build.wrapper; - - nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. - markdownlint.enable = true; # Markdown lint tool - typos.enable = true; # Source code spell checker - editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig - - actionlint.enable = true; # GitHub workflows linting - commitizen.enable = true; # Commitizen is release management tool designed for teams. - }; - }; - - # -------------- - # --- FLAKES --- - # -------------- - devenv.flakesIntegration = true; - - # This is currently needed for devenv to properly run in pure hermetic - # mode while still being able to run processes & services and modify - # (some parts) of the active shell. - devenv.root = + buildInputs = [ nixfmt-rfc-style ]; + + meta = with lib; { + homepage = "https://github.com/tsandrini/flake-parts-builder"; + description = "Nix flakes interactive template builder based on flake-parts written in Rust."; + license = licenses.mit; + platforms = [ system ]; + maintainers = [ tsandrini ]; + mainProgram = "flake-parts-builder"; + }; + }; + in + pkgs.callPackage package { inherit tsandrini; }; + + docs = + let + package = + { + lib, + rustPlatform, + builder, + }: + rustPlatform.buildRustPackage { + inherit (builder) src unpackPhase version; + name = "${builder.name}-docs"; + + cargoSha256 = "sha256-Jsha+Aoe5R6g4H7KNX2VX62S+NGj1SrobeCakjgFw24="; + + doCheck = false; + + buildPhase = '' + cargo doc --no-deps --release + ''; + + meta = builder.meta // { + description = "Documentation for ${builder.meta.description}"; + mainProgram = null; + }; + }; + in + pkgs.callPackage package { inherit builder; }; + + flake-parts = let - devenvRootFileContent = builtins.readFile inputs.devenv-root.outPath; + package = + { + lib, + stdenv, + tsandrini, + mkFlakeParts, + }: + mkFlakeParts { + inherit stdenv; + name = "flake-parts"; + version = "1.0.0"; + src = ./flake-parts; + + meta = with lib; { + homepage = "https://github.com/tsandrini/flake-parts-builder"; + description = "The base collection of flake-parts for the flake-parts-builder."; + license = licenses.mit; + platforms = [ system ]; + maintainers = [ tsandrini ]; + }; + }; in - pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; + pkgs.callPackage package { inherit tsandrini mkFlakeParts; }; - # --------------------- - # --- MISCELLANEOUS --- - # --------------------- - difftastic.enable = true; + flake-parts-bootstrap = + let + package = + { + lib, + stdenv, + tsandrini, + mkFlakeParts, + }: + mkFlakeParts { + inherit stdenv; + name = "flake-parts-bootstrap"; + version = "1.0.0"; + src = ./flake-parts-bootstrap; + + meta = with lib; { + homepage = "https://github.com/tsandrini/flake-parts-builder"; + description = "The base collection of flake-parts for the flake-parts-builder."; + license = licenses.mit; + platforms = [ system ]; + maintainers = [ tsandrini ]; + }; + }; + in + pkgs.callPackage package { inherit tsandrini mkFlakeParts; }; + }; + + devShells = rec { + default = dev; + + dev = + let + package = + { + mkShell, + nil, + statix, + deadnix, + nix-output-monitor, + nixfmt-rfc-style, + commitizen, + cz-cli, + gh, + gh-dash, + markdownlint-cli, + }: + mkShell { + buildInputs = [ + # -- NIX UTILS -- + nil # Yet another language server for Nix + statix # Lints and suggestions for the nix programming language + deadnix # Find and remove unused code in .nix source files + nix-output-monitor # Processes output of Nix commands to show helpful and pretty information + nixfmt-rfc-style # An opinionated formatter for Nix + + # -- GIT RELATED UTILS -- + commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs + cz-cli # The commitizen command line utility + # fh # The official FlakeHub CLI + gh # GitHub CLI tool + gh-dash # Github Cli extension to display a dashboard with pull requests and issues + + # -- BASE LANG UTILS -- + markdownlint-cli # Command line interface for MarkdownLint + # nodePackages.prettier # Prettier is an opinionated code formatter + # typos # Source code spell checker + + # -- (YOUR) EXTRA PKGS -- + ]; + + shellHook = '' + # Welcome splash text + echo ""; echo -e "\e[1;37;42mWelcome to the flake-parts-builder devshell!\e[0m"; echo "" + ''; + }; + in + pkgs.callPackage package { }; }; }; }; diff --git a/src/assets/flake-inputs.nix.template b/src/assets/flake-inputs.nix.template new file mode 100644 index 0000000..53f4647 --- /dev/null +++ b/src/assets/flake-inputs.nix.template @@ -0,0 +1,24 @@ + {# NOTE over time the community has developed a certain formatting + style for flake.nix inputs that tends to be shared among most + of us, which is not a simple "JSON"-like dump. This is why I + opted to manually parse the JSON dump. #} +{%- if context.inputs is defined %} +{%- for input_name in context.inputs %} + {%- set input = context.inputs[input_name] -%} + {%- if not input.inputs is defined and not input.flake is defined %} + {{ input_name }}.url = "{{ input.url }}"; + {%- else %} + {{ input_name }} = { + url = "{{ input.url }}"; + {%- if input.inputs is defined %} + {%- for follow_name in input.inputs %} + inputs.{{ follow_name }}.follows = "{{ input.inputs[follow_name].follows }}"; + {%- endfor %} + {%- endif %} + {%- if input.flake is defined %} + flake = {{ input.flake }}; + {%- endif %} + }; + {%- endif %} +{%- endfor %} +{% endif %} \ No newline at end of file diff --git a/src/assets/flake.nix.template b/src/assets/flake.nix.template new file mode 100644 index 0000000..0764158 --- /dev/null +++ b/src/assets/flake.nix.template @@ -0,0 +1,71 @@ +# --- flake.nix +{ +description = "TODO Add description of your new project"; + + inputs = { + # --- BASE DEPENDENCIES --- + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + + # --- YOUR DEPENDENCIES --- + {%- with context = context.flake_inputs_context %} + {%- include "flake-inputs.nix" ignore missing -%} + {% endwith -%} + }; + + # NOTE Here you can add additional binary cache substituers that you trust. + # There are also some sensible default caches commented out that you + # might consider using, however, you are advised to doublecheck the keys. + nixConfig = { + extra-trusted-public-keys = [ + # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + {% if context.extra_trusted_public_keys is defined -%} + {% for key in context.extra_trusted_public_keys -%} + # "{{ key }}" + {% endfor -%} + {% endif -%} + ]; + extra-substituters = [ + # "https://cache.nixos.org" + # "https://nix-community.cachix.org/" + {% if context.extra_substituters is defined -%} + {% for substituter in context.extra_substituters -%} + # "{{ substituter }}" + {% endfor -%} + {% endif -%} + ]; + }; + + outputs = + inputs@{ flake-parts, ... }: + let + inherit (inputs.nixpkgs) lib; + inherit (import ./flake-parts/_bootstrap.nix { inherit lib; }) loadParts; + in + flake-parts.lib.mkFlake { inherit inputs; } { + + # We recursively traverse all of the flakeModules in ./flake-parts and + # import only the final modules, meaning that you can have an arbitrary + # nested structure that suffices your needs. For example + # + # - ./flake-parts + # - modules/ + # - nixos/ + # - myNixosModule1.nix + # - myNixosModule2.nix + # - default.nix + # - home-manager/ + # - myHomeModule1.nix + # - myHomeModule2.nix + # - default.nix + # - sharedModules.nix + # - pkgs/ + # - myPackage1.nix + # - myPackage2.nix + # - default.nix + # - mySimpleModule.nix + # - _not_a_module.nix + imports = loadParts ./flake-parts; + }; +} diff --git a/src/cmd/add.rs b/src/cmd/add.rs new file mode 100644 index 0000000..3e417ab --- /dev/null +++ b/src/cmd/add.rs @@ -0,0 +1,95 @@ +use clap::Args; +use color_eyre::eyre::Result; +use fs_extra::dir::{self, CopyOptions}; +use tempfile::tempdir; + +use crate::cmd::init::{parse_required_parts_tuples, prepare_tmpdir, InitCommand}; +use crate::config::{BASE_DERIVATION_NAME, SELF_FLAKE_URI}; +use crate::parts::FlakePartsStore; +use crate::templates::FlakeInputsContext; + +// TODO: I might figure out a way to do this automatically in the future, but +// it's way too complicated for now. +// TODO for some reason broken formatting +/// Add additional flake-parts to an already initialized project. +/// +/// This is similar to the init command, but differs in two significant ways: +/// +/// 1. No `_bootstrap` part is added, as the project is already bootstrapped. +/// +/// 2. `flake.nix` is left untouched as the user may have already made manual changes. +/// Additional inputs will be printed to the console and the user is +/// advised to add them manually. +#[derive(Debug, Args)] +pub struct AddCommand { + #[clap(flatten)] + pub init: InitCommand, +} + +pub fn add(mut cmd: AddCommand) -> Result<()> { + if !cmd.init.shared_args.disable_base_parts { + cmd.init + .shared_args + .parts_stores + .push(format!("{}#{}", SELF_FLAKE_URI, BASE_DERIVATION_NAME)); + } + + // NOTE we init stores here to have sensible ownerships of FlakePartTuples + let stores = cmd + .init + .shared_args + .parts_stores + .iter() + .map(|store| FlakePartsStore::from_flake_uri(&store)) + .collect::>>()?; + + let parts_tuples = parse_required_parts_tuples(&cmd.init, &stores)?; + + let path = cmd + .init + .path + .canonicalize() + .unwrap_or_else(|_| cmd.init.path.clone()); + + // TODO probably yield an error instead + if !path.exists() { + dir::create_all(&path, false)?; + } + + let tmpdir = tempdir()?; + prepare_tmpdir( + &tmpdir, + &parts_tuples, + path.to_str(), + &cmd.init.strategy, + false, + )?; + + // NOTE the flake.nix file shouldn't be present due to the strucutre of + // flake-parts, but I am way tooo paranoid. + if tmpdir.path().join("flake.nix").exists() { + std::fs::remove_file(tmpdir.path().join("flake.nix"))?; + } + + let metadata = parts_tuples + .iter() + .map(|part_tuple| &part_tuple.part.metadata) + .collect::>(); + + let flake_context = FlakeInputsContext::from_merged_metadata(&metadata); + + let rendered = flake_context.render()?; + println!("Please add the following snippet to your `flake.nix` inputs:"); + println!("{}", rendered); + + dir::copy( + &tmpdir, + &cmd.init.path, + &CopyOptions::new() + .content_only(true) + .skip_exist(!cmd.init.force) + .overwrite(cmd.init.force), + )?; + + Ok(()) +} diff --git a/src/cmd/init.rs b/src/cmd/init.rs new file mode 100644 index 0000000..a510ca6 --- /dev/null +++ b/src/cmd/init.rs @@ -0,0 +1,299 @@ +use clap::{Args, ValueEnum}; +use color_eyre::eyre::Result; +use fs_extra::dir::{self, CopyOptions}; +use std::fs; +use std::path::PathBuf; +use tempfile::{tempdir, TempDir}; +use thiserror::Error; + +use crate::cmd::SharedArgs; +use crate::config::{ + BASE_DERIVATION_NAME, BOOTSTRAP_DERIVATION_NAME, META_FILE, NAMEPLACEHOLDER, SELF_FLAKE_URI, +}; +use crate::fs_utils::{regex_in_dir_recursive, reset_permissions}; +use crate::nix::nixfmt_file; +use crate::parts::{FlakePartTuple, FlakePartsStore}; +use crate::templates::FlakeContext; + +/// Initialize a new flake-parts projects using the builder. +#[derive(Debug, Args)] +pub struct InitCommand { + #[clap(flatten)] + pub shared_args: SharedArgs, + + /// Path (relative or absolute) for the desired flake-parts project. + /// You can either pass an empty or non-existing directory, in which case + /// all content will be new or you can pass an existing directory already + /// populated with files. In such case the directories will be merged + /// according to the strategy specified in `--strategy`. + #[clap(verbatim_doc_comment)] + pub path: PathBuf, + + /// Which parts to include in the project separated by commas. To see + /// which ones are available use the `list` subcommand. + #[arg( + short = 'p', + long = "parts", + required = true, + value_delimiter = ',', + verbatim_doc_comment + )] + pub parts: Vec, + + /// Strategy to use when encountering already existing files + #[arg(value_enum, short, long, default_value = "skip", verbatim_doc_comment)] + pub strategy: InitStrategy, + + /// Force initialization in case of conflicting parts. Note that in such + /// cases you should probably also pass a merging strategy that fits your + /// specific needs. + #[arg( + long = "ignore-conflicts", + default_value_t = false, + verbatim_doc_comment + )] + pub ignore_conflicts: bool, + + /// Force initialization in case of unresolved dependencies. This can happen + /// if you request parts that have 3rd party dependencies on parts stores + /// that aren't included via the `--include` or `-I` flag. + #[arg( + long = "ignore-unresolved-deps", + default_value_t = false, + verbatim_doc_comment + )] + pub ignore_unresolved_deps: bool, + + /// Force overwriting of local files in case of initialization in + /// a non-empty directory + #[arg(long = "force", default_value_t = false, verbatim_doc_comment)] + pub force: bool, +} + +#[derive(Debug, Copy, Clone, PartialEq, ValueEnum)] +pub enum InitStrategy { + /// Skip file if already present in the filesystem + #[clap(verbatim_doc_comment)] + Skip, + + /// Overwrite file if already present in the filesystem + #[clap(verbatim_doc_comment)] + Overwrite, + + /// Try to merge file if already present in the filesystem. + /// This will use a diff like patching algorithm and may fail + /// in case of conflicts. (TODO not public yet) + #[clap(verbatim_doc_comment)] + Merge, +} + +#[derive(Error, Debug)] +pub enum PartsTuplesParsingError { + #[error("The following user required parts couldn't be resolved: {0:?}")] + MissingPartsError(Vec), + + #[error("You have requested parts that conflict with each other: {0:?} If you wish to ignore these conflicts use the `--ignore-conflicts` flag")] + ConflictingPartsError(Vec), + + #[error("The following dependencies were required but couldn't be resolved: {0:?} Please include the necessary flake-parts stores using the `-I` flag or pass the `--ignore-unresolved-deps` flag to ignore this error and force initialization.")] + UnresolvedDependenciesError(Vec), +} + +// NOTE +// 1. Load all FlakePartsStores +// 2. Create an iterator over all parts (don't collect them yet) +// 3. Construct a final vec of all parts that should be used +// a. First we parse the CLI parts +// b. Then we iterate over those to add potential dependencies +// c. Unique filter +// d. Combine these two +// 4. We finally can create a vec of all parts that should be used +// 5. Collect! (profit) +pub fn parse_required_parts_tuples<'a>( + cmd: &InitCommand, + stores: &'a Vec, +) -> Result>, PartsTuplesParsingError> { + let all_parts_tuples = stores + .iter() + .flat_map(|store| { + store + .parts + .iter() + .map(move |part| FlakePartTuple::new(store, part.to_owned())) + }) + .collect::>(); + + let user_req_flake_strings = cmd.parts.clone(); + + // TODO remove + println!("User required parts: {:?}", user_req_flake_strings); + + let (resolved_deps, unresolved_deps) = { + let start_indices: Vec = all_parts_tuples + .iter() + .enumerate() + .filter(|&(_, part_tuple)| { + let flake_uri = part_tuple.to_flake_uri(None); + user_req_flake_strings + .iter() + .any(|req| req == &flake_uri || req == &part_tuple.part.name) + }) + .map(|(index, _)| index) + .collect(); + + FlakePartTuple::resolve_dependencies_of(&all_parts_tuples, start_indices) + }; + + if !unresolved_deps.is_empty() { + return Err(PartsTuplesParsingError::UnresolvedDependenciesError( + unresolved_deps, + )); + } + + let all_req_flake_strings = user_req_flake_strings + .iter() + .chain(resolved_deps.iter()) + .collect::>(); + + // TODO remove + println!("All required parts: {:?}", all_req_flake_strings); + + let final_parts_tuples = all_parts_tuples + .into_iter() + .filter(|part_tuple| { + let flake_uri = part_tuple.to_flake_uri(None); + all_req_flake_strings + .iter() + .any(|&req| req == &flake_uri || req == &part_tuple.part.name) + }) + .collect::>(); + + let final_parts_uris = final_parts_tuples + .iter() + .map(|flake_part| flake_part.to_flake_uri(None)) + .collect::>(); + + // TODO remove + println!("Final parts: {:?}", final_parts_uris); + + let missing_parts = + FlakePartTuple::find_missing_parts_in(&final_parts_tuples, &user_req_flake_strings); + + if missing_parts.len() > 0 { + return Err(PartsTuplesParsingError::MissingPartsError( + missing_parts.into_iter().cloned().collect::>(), + )); + } + + // TODO probably print that we are ignoring conflicts + if !cmd.ignore_conflicts { + // check_for_conflicts(&final_parts_tuples)?; + let conflicts = FlakePartTuple::find_conflicting_parts_in(&final_parts_tuples); + + if conflicts.len() > 0 { + return Err(PartsTuplesParsingError::ConflictingPartsError( + conflicts + .into_iter() + .map(|flake_part| flake_part.to_flake_uri(None)) + .collect::>(), + )); + } + } + + Ok(final_parts_tuples) +} + +pub fn prepare_tmpdir( + tmpdir: &TempDir, + parts_tuples: &Vec, + target_name: Option<&str>, + init_strategy: &InitStrategy, + render_flake_nix: bool, +) -> Result<()> { + // TODO MERGE STRATEGY + let tmp_path = tmpdir.path(); + for part_tuple in parts_tuples { + dir::copy( + &part_tuple.part.nix_store_path, + &tmp_path, + &CopyOptions::new() + .content_only(true) + .skip_exist(init_strategy == &InitStrategy::Skip) + .overwrite(init_strategy == &InitStrategy::Overwrite), + )?; + } + + // TODO fails if no META_FILE is present + // check if meta exists and delete it if yes + + std::fs::remove_file(tmp_path.join(META_FILE))?; + + reset_permissions(tmp_path.to_str().unwrap())?; + + if render_flake_nix { + let metadata = parts_tuples + .iter() + .map(|part_tuple| &part_tuple.part.metadata) + .collect::>(); + + let flake_context = FlakeContext::from_merged_metadata(&metadata); + + let rendered = flake_context.render()?; + fs::write(tmp_path.join("flake.nix"), rendered)?; + nixfmt_file(&tmp_path.join("flake.nix"))?; + } + + // This becomes None when `.`, `../`,etc... is passed + if let Some(name) = target_name { + regex_in_dir_recursive(tmp_path.to_str().unwrap(), &NAMEPLACEHOLDER, name)?; + } + + Ok(()) +} + +pub fn init(mut cmd: InitCommand) -> Result<()> { + if !cmd.shared_args.disable_base_parts { + cmd.shared_args + .parts_stores + .push(format!("{}#{}", SELF_FLAKE_URI, BASE_DERIVATION_NAME)); + } + + // NOTE this one is required even if you disable base store parts + cmd.shared_args + .parts_stores + .push(format!("{}#{}", SELF_FLAKE_URI, BOOTSTRAP_DERIVATION_NAME)); + cmd.parts.push(format!( + "{}#{}/_bootstrap", + SELF_FLAKE_URI, BOOTSTRAP_DERIVATION_NAME + )); + + // NOTE we init stores here to have sensible ownerships of FlakePartTuples + let stores = cmd + .shared_args + .parts_stores + .iter() + .map(|store| FlakePartsStore::from_flake_uri(&store)) + .collect::>>()?; + + let parts_tuples = parse_required_parts_tuples(&cmd, &stores)?; + + let path = cmd.path.canonicalize().unwrap_or_else(|_| cmd.path.clone()); + + if !path.exists() { + dir::create_all(&path, false)?; + } + + let tmpdir = tempdir()?; + prepare_tmpdir(&tmpdir, &parts_tuples, path.to_str(), &cmd.strategy, true)?; + + dir::copy( + &tmpdir, + &cmd.path, + &CopyOptions::new() + .content_only(true) + .skip_exist(!cmd.force) + .overwrite(cmd.force), + )?; + + Ok(()) +} diff --git a/src/cmd/list.rs b/src/cmd/list.rs new file mode 100644 index 0000000..66cb71b --- /dev/null +++ b/src/cmd/list.rs @@ -0,0 +1,65 @@ +use clap::Args; +use color_eyre::eyre::Result; +use std::io::Write; +use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; + +use crate::cmd::SharedArgs; +use crate::config::{BASE_DERIVATION_NAME, BOOTSTRAP_DERIVATION_NAME, SELF_FLAKE_URI}; +use crate::parts::FlakePartsStore; + +/// List all available flake-parts in all parts stores provided by the user. +#[derive(Debug, Args)] +pub struct ListCommand { + #[clap(flatten)] + pub shared_args: SharedArgs, +} + +pub fn list(mut cmd: ListCommand) -> Result<()> { + if !cmd.shared_args.disable_base_parts { + cmd.shared_args + .parts_stores + .push(format!("{}#{}", SELF_FLAKE_URI, BASE_DERIVATION_NAME)); + } + + // NOTE this one is required even if you disable base store parts + cmd.shared_args + .parts_stores + .push(format!("{}#{}", SELF_FLAKE_URI, BOOTSTRAP_DERIVATION_NAME)); + + let mut stdout = StandardStream::stdout(ColorChoice::Auto); + + cmd.shared_args + .parts_stores + .iter() + .try_for_each(|flake_uri| { + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; + writeln!(&mut stdout, " # {}", flake_uri)?; + + // TODO maybe some error message instead of unwrap? + FlakePartsStore::from_flake_uri(&flake_uri) + .unwrap() + .parts + .iter() + .try_for_each(|part| { + // Visually distinguish collections + let color = if part.name.contains('+') { + Color::Cyan + } else { + Color::Red + }; + + stdout.set_color(ColorSpec::new().set_fg(Some(color)))?; + + write!(&mut stdout, " - {}: ", part.name)?; + + stdout.set_color(ColorSpec::new().set_fg(Some(Color::White)))?; + + writeln!(&mut stdout, "{}", part.metadata.description)?; + + Ok(()) as Result<()> + })?; + + println!(""); + Ok(()) + }) +} diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs new file mode 100644 index 0000000..37f94ee --- /dev/null +++ b/src/cmd/mod.rs @@ -0,0 +1,41 @@ +use clap::Args; + +pub mod add; +pub mod init; +pub mod list; + +#[derive(Debug, Args)] +pub struct SharedArgs { + /// Additional parts templates stores to load. This currently accepts any + /// valid flakes derivation URI. For example: + /// + /// - `github:tsandrini/flake-parts-builder#flake-parts` + /// - `../myDir#flake-parts` + /// - `.#different-flake-parts` + /// + /// NOTE: the derivation needs to have the parts stored at + /// `$out/flake-parts`. You can also use `lib.mkFlakeParts` defined + /// in `flake.nix` to make this easier. + #[arg( + short = 'I', + long = "include", + value_delimiter = ',', + verbatim_doc_comment + )] + pub parts_stores: Vec, + + /// Disable base parts provided by this flake, that is, + /// `github:tsandrini/flake-parts-builder#flake-parts`. Useful in case + /// you'd like to override certain parts or simply not use the one provided + /// by this repo. + /// + /// NOTE: _bootstrap part is always included for the project to + /// properly function (if you really need to you can override the files + /// with your own versions) + #[arg(long = "disable-base", default_value_t = false, verbatim_doc_comment)] + pub disable_base_parts: bool, + + /// Enable verbose logging + #[arg(short, long, default_value_t = false)] + pub verbose: bool, +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..90eb8a5 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,7 @@ +pub static FLAKE_TEMPLATE: &'static str = include_str!("assets/flake.nix.template"); +pub static FLAKE_INPUTS_TEMPLATE: &'static str = include_str!("assets/flake-inputs.nix.template"); +pub static META_FILE: &'static str = "meta.nix"; +pub static NAMEPLACEHOLDER: &'static str = "NAMEPLACEHOLDER"; +pub static BASE_DERIVATION_NAME: &'static str = "flake-parts"; +pub static BOOTSTRAP_DERIVATION_NAME: &'static str = "flake-parts-bootstrap"; +pub static SELF_FLAKE_URI: &'static str = "github:tsandrini/flake-parts-builder/v1"; diff --git a/src/fs_utils.rs b/src/fs_utils.rs new file mode 100644 index 0000000..df64be7 --- /dev/null +++ b/src/fs_utils.rs @@ -0,0 +1,117 @@ +use color_eyre::eyre::Result; +use diff::{slice, Result as DiffResult}; +use fs_extra::dir::{self, CopyOptions}; +use regex::Regex; +use std::fs::{self, File, Permissions}; +use std::io::{self, Read, Write}; +use std::os::unix::fs::PermissionsExt; +use std::path::Path; +use walkdir::WalkDir; + +use crate::config::META_FILE; + +// TODO might implement a "merging" strategy instead of skipping/overwriting +// but currently not entirely sure about its use case +#[allow(dead_code)] +pub fn merge_files(base: &Path, theirs: &Path, ours: &Path) -> Result<()> { + let base_content = fs::read_to_string(base)?; + let their_content = fs::read_to_string(theirs)?; + let our_content = fs::read_to_string(ours)?; + + let base_lines = base_content.lines().collect::>(); + let their_lines = their_content.lines().collect::>(); + let our_lines = our_content.lines().collect::>(); + + let diffs = slice(&base_lines, &their_lines); + + let mut merged_lines = Vec::new(); + let mut our_iter = our_lines.iter(); + for diff in diffs { + match diff { + DiffResult::Both(_, line) => { + // Both versions are the same + merged_lines.push(*line); + our_iter.next(); // Move along ours as well + } + DiffResult::Left(_) => { + // Line is only in base, so we take from ours + if let Some(line) = our_iter.next() { + merged_lines.push(*line); + } + } + DiffResult::Right(line) => { + // Line is only in theirs + merged_lines.push(*line); + } + } + } + // Append remaining lines from ours + for line in our_iter { + merged_lines.push(*line); + } + + fs::write(ours, merged_lines.join("\n"))?; + Ok(()) +} + +// TODO +#[allow(dead_code)] +pub fn merge_dirs(src: &Path, dst: &Path, options: &CopyOptions) -> Result<()> { + for entry in WalkDir::new(src) + .into_iter() + .filter_entry(|e| e.file_name() != META_FILE) + { + let entry = entry?; + let target_path = dst.join(entry.path().strip_prefix(src)?); + + if target_path.exists() && false { + if entry.path().is_file() { + // Attempt to merge files + merge_files(&entry.path(), &target_path, &entry.path())?; + } + } else { + if entry.path().is_dir() { + dir::create_all(&target_path, false)?; + } else { + // TODO copy_with_progress? + dir::copy(&entry.path(), &target_path, &options)?; + } + } + } + Ok(()) +} + +pub fn reset_permissions(path: &str) -> std::io::Result<()> { + for entry in WalkDir::new(path).into_iter().filter_map(|e| e.ok()) { + let path = entry.path(); + let metadata = fs::metadata(path)?; + + if metadata.is_dir() { + fs::set_permissions(path, Permissions::from_mode(0o755))?; + } else if metadata.is_file() { + fs::set_permissions(path, Permissions::from_mode(0o644))?; + } + } + Ok(()) +} + +pub fn regex_in_dir_recursive(dir: &str, pattern: &str, replacement: &str) -> io::Result<()> { + let re = Regex::new(pattern).unwrap(); + + for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) { + if entry.file_type().is_file() { + let path = entry.path(); + let mut contents = String::new(); + { + let mut file = File::open(path)?; + file.read_to_string(&mut contents)?; + } + let new_contents = re.replace_all(&contents, replacement).to_string(); + if new_contents != contents { + let mut file = File::create(path)?; + file.write_all(new_contents.as_bytes())?; + } + } + } + Ok(()) +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..7505165 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,53 @@ +//! Nix flakes interactive template builder based on flake-parts written +//! in Rust. +//! +//! TODO lorem ipsum +use clap::{Parser, Subcommand}; +use color_eyre::eyre::Result; + +pub mod cmd; +pub mod config; +pub mod fs_utils; +pub mod nix; +pub mod parts; +pub mod templates; + +use crate::cmd::add::{add, AddCommand}; +use crate::cmd::init::{init, InitCommand}; +use crate::cmd::list::{list, ListCommand}; + +/// Nix flakes interactive template builder based on flake-parts written +/// in Rust. +#[derive(Debug, Parser)] +#[command(author, version, about, long_about = None, verbatim_doc_comment)] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Debug, Subcommand)] +enum Commands { + Init(InitCommand), + List(ListCommand), + Add(AddCommand), +} + +// TODO add logging +// TODO add tests +// TODO better docs +fn main() -> Result<()> { + color_eyre::install()?; + let cli = Cli::parse(); + + match cli.command { + Commands::Init(cmd) => init(cmd), + Commands::List(cmd) => list(cmd), + Commands::Add(cmd) => add(cmd), + } +} + +#[test] +fn verify_cli() { + use clap::CommandFactory; + Cli::command().debug_assert(); +} diff --git a/src/nix.rs b/src/nix.rs new file mode 100644 index 0000000..aa53660 --- /dev/null +++ b/src/nix.rs @@ -0,0 +1,32 @@ +use color_eyre::eyre::Result; +use std::path::PathBuf; +use std::process::Command; + +use crate::config::META_FILE; + +pub fn get_flake_store_path(flake_uri: &str) -> Result { + let nix_info = Command::new("nix") + .args(["build", "--no-link", "--print-out-paths", &flake_uri]) + .output()?; + + let output = String::from_utf8(nix_info.stdout)?; + Ok(PathBuf::from(output.trim())) +} + +pub fn eval_meta_file(path: &PathBuf) -> Result { + let nix_eval = Command::new("nix") + .args(["eval", "--json", "--file", META_FILE]) + .current_dir(&path) + .output()?; + + let output = String::from_utf8(nix_eval.stdout)?; + Ok(output) +} + +pub fn nixfmt_file(path: &PathBuf) -> Result<()> { + let path = path.to_str().unwrap(); // TODO + + Command::new("nixfmt").args([&path]).output()?; + + Ok(()) +} diff --git a/src/parts.rs b/src/parts.rs new file mode 100644 index 0000000..993432a --- /dev/null +++ b/src/parts.rs @@ -0,0 +1,218 @@ +//! Provides a way to parse and store flake parts metadata +use color_eyre::eyre::Result; +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; +use std::fs; +use std::path::PathBuf; +use thiserror::Error; + +use crate::nix::{eval_meta_file, get_flake_store_path}; + +#[derive(Debug, Clone)] +pub struct FlakePart { + pub name: String, + pub nix_store_path: PathBuf, + pub metadata: FlakePartMetadata, +} + +// TODO helper struct to evade overcomplicated lifetimes +// beware that the store references will live only as long +// as the original function call +#[derive(Debug)] +pub struct FlakePartTuple<'a> { + pub store: &'a FlakePartsStore, + pub part: FlakePart, +} + +pub fn normalize_flake_string(target: &str, flake: &str, derivation: Option<&str>) -> String { + if target.contains('#') { + target.to_string() + } else if let Some(derivation) = derivation { + format!("{}#{}/{}", flake, derivation, target) + } else { + format!("{}/{}", flake, target) + } +} + +impl<'a> FlakePartTuple<'a> { + pub fn new(store: &'a FlakePartsStore, part: FlakePart) -> Self { + Self { store, part } + } + + pub fn to_flake_uri(&self, derivation: Option<&str>) -> String { + normalize_flake_string(&self.part.name, &self.store.flake_uri, derivation) + } + + pub fn resolve_dependencies_of( + parts_tuples_pool: &Vec, + start_indices: Vec, + ) -> (Vec, Vec) { + use std::collections::{HashSet, VecDeque}; + let mut resolved_dependencies = HashSet::new(); + let mut unresolved_dependencies = Vec::new(); + let mut to_process = VecDeque::from(start_indices); + + while let Some(index) = to_process.pop_front() { + let part_tuple = &parts_tuples_pool[index]; + for dep in &part_tuple.part.metadata.dependencies { + let normalized_dep = normalize_flake_string(dep, &part_tuple.store.flake_uri, None); + if resolved_dependencies.insert(normalized_dep.clone()) { + // If this is a new dependency, try to find the corresponding PartTuple + if let Some(dep_index) = parts_tuples_pool + .iter() + .position(|p| p.to_flake_uri(None) == normalized_dep) + { + to_process.push_back(dep_index); + } else { + // This dependency couldn't be resolved + unresolved_dependencies.push(normalized_dep); + } + } + } + } + + ( + resolved_dependencies.into_iter().collect(), + unresolved_dependencies, + ) + } + + pub fn find_conflicting_parts_in( + parts_tuples: &'a Vec, + ) -> Vec<&'a FlakePartTuple<'a>> { + let conflicting_parts_uris = parts_tuples + .iter() + .flat_map(|part_tuple| { + part_tuple.part.metadata.conflicts.iter().map(|conflict| { + normalize_flake_string(&conflict, &part_tuple.store.flake_uri, None) + }) + }) + .collect::>(); + + let conflicting_parts: Vec<&'a FlakePartTuple> = parts_tuples + .iter() + .filter(|&uri| conflicting_parts_uris.contains(&uri.to_flake_uri(None))) + .collect::>(); + + conflicting_parts + } + + pub fn find_missing_parts_in<'b>( + parts_tuples: &Vec, + required_parts: &'b Vec, + ) -> Vec<&'b String> { + required_parts + .iter() + .filter(|&uri| { + !parts_tuples.iter().any(|part_tuple| { + uri == &part_tuple.to_flake_uri(None) || uri == &part_tuple.part.name + }) + }) + .collect::>() + } +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct FlakePartMetadata { + #[serde(default)] + pub description: String, + + #[serde(default)] + pub inputs: JsonValue, + + #[serde(default)] + pub dependencies: Vec, + + #[serde(default)] + pub conflicts: Vec, + + #[serde(rename = "extraTrustedPublicKeys", default)] + pub extra_trusted_public_keys: Vec, + + #[serde(rename = "extraSubstituters", default)] + pub extra_substituters: Vec, +} + +#[derive(Debug)] +pub struct FlakePartsStore { + pub flake_uri: String, + pub nix_store_path: PathBuf, + pub parts: Vec, +} + +#[derive(Error, Debug)] +pub enum FlakePartParseError { + #[error("provided flake part path is invalid")] + InvalidPathError(), + + #[error("failed to evaluate flake part metadata")] + NixEvalError(#[from] std::io::Error), + + #[error("failed to parse the UTF-8 output of nix eval")] + NixEvalUTF8Error(#[from] std::string::FromUtf8Error), + + #[error("failed to convert flake parts metadata to JSON")] + MetadataConversionError(#[from] serde_json::Error), +} + +impl FlakePart { + fn new(name: String, nix_store_path: PathBuf, metadata: FlakePartMetadata) -> Self { + Self { + name, + nix_store_path, + metadata, + } + } + + pub fn from_path(nix_store_path: PathBuf) -> Result { + let name = nix_store_path + .file_name() + .ok_or(FlakePartParseError::InvalidPathError())? + .to_str() + .ok_or(FlakePartParseError::InvalidPathError())?; + + let eval_output = eval_meta_file(&nix_store_path)?; + + let metadata: FlakePartMetadata = serde_json::from_str(&eval_output) + .map_err(|e| FlakePartParseError::MetadataConversionError(e))?; + + Ok(Self::new(name.to_string(), nix_store_path, metadata)) + } +} + +#[derive(Error, Debug)] +pub enum FlakePartsStoreParseError { + #[error("failed to realize flake uri to a valid store path")] + StoreRealizationError(#[from] std::io::Error), + + #[error("failed to parse the UTF-8 output of nix build command")] + NixBuildUTF8Error(#[from] std::string::FromUtf8Error), + + #[error("failed to parse flake part")] + FlakePartParseError(#[from] FlakePartParseError), +} + +impl FlakePartsStore { + fn new(flake_uri: String, nix_store_path: PathBuf, parts: Vec) -> Self { + Self { + flake_uri, + nix_store_path, + parts, + } + } + + // TODO handle errors + pub fn from_flake_uri(flake_uri: &str) -> Result { + let nix_store_path = get_flake_store_path(flake_uri)?; + + let parts = fs::read_dir(nix_store_path.join("flake-parts"))? + .map(|entry| { + let entry = entry?; + + Ok(FlakePart::from_path(entry.path())?) + }) + .collect::>()?; + + Ok(Self::new(flake_uri.to_string(), nix_store_path, parts)) + } +} diff --git a/src/templates.rs b/src/templates.rs new file mode 100644 index 0000000..6422b39 --- /dev/null +++ b/src/templates.rs @@ -0,0 +1,96 @@ +use color_eyre::eyre::Result; +use serde::Serialize; +use serde_json::Value as JsonValue; + +use minijinja::{context, Environment}; + +use crate::config::{FLAKE_INPUTS_TEMPLATE, FLAKE_TEMPLATE}; +use crate::parts::FlakePartMetadata; + +#[derive(Debug, Serialize)] +pub struct FlakeInputsContext { + pub inputs: JsonValue, +} + +impl FlakeInputsContext { + fn new(inputs: JsonValue) -> Self { + Self { inputs } + } + + pub fn from_merged_metadata(metadata: &Vec<&FlakePartMetadata>) -> Self { + let inputs = metadata + .iter() + .fold(JsonValue::Object(Default::default()), |mut acc, m| { + if let (JsonValue::Object(acc_obj), JsonValue::Object(inputs_obj)) = + (&mut acc, &m.inputs) + { + for (k, v) in inputs_obj.iter() { + acc_obj.insert(k.clone(), v.clone()); + } + } + acc + }); + + Self::new(inputs) + } + + pub fn render(&self) -> Result { + let mut env = Environment::new(); + env.add_template("flake-inputs.nix", &FLAKE_INPUTS_TEMPLATE) + .unwrap(); + let tmpl = env.get_template("flake-inputs.nix").unwrap(); + let rendered = tmpl.render(context! ( context => self))?; + Ok(rendered) + } +} + +#[derive(Debug, Serialize)] +pub struct FlakeContext { + pub flake_inputs_context: FlakeInputsContext, + pub extra_trusted_public_keys: Vec, + pub extra_substituters: Vec, +} + +impl FlakeContext { + fn new( + flake_inputs_context: FlakeInputsContext, + extra_trusted_public_keys: Vec, + extra_substituters: Vec, + ) -> Self { + Self { + flake_inputs_context, + extra_trusted_public_keys, + extra_substituters, + } + } + + pub fn from_merged_metadata(metadata: &Vec<&FlakePartMetadata>) -> Self { + let flake_inputs_context = FlakeInputsContext::from_merged_metadata(metadata); + + let extra_trusted_public_keys = metadata + .iter() + .flat_map(|m| m.extra_trusted_public_keys.iter().cloned()) + .collect::>(); + + let extra_substituters = metadata + .iter() + .flat_map(|m| m.extra_substituters.iter().cloned()) + .collect::>(); + + Self::new( + flake_inputs_context, + extra_trusted_public_keys, + extra_substituters, + ) + } + + pub fn render(&self) -> Result { + let mut env = Environment::new(); + env.add_template("flake.nix", &FLAKE_TEMPLATE).unwrap(); + env.add_template("flake-inputs.nix", &FLAKE_INPUTS_TEMPLATE) + .unwrap(); + let tmpl = env.get_template("flake.nix").unwrap(); + let rendered = tmpl.render(context! ( context => self))?; + Ok(rendered) + } +} diff --git a/templates/home/.envrc b/templates/home/.envrc deleted file mode 100644 index 6611954..0000000 --- a/templates/home/.envrc +++ /dev/null @@ -1,12 +0,0 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -watch_file flake.nix -watch_file flake.lock -watch_file parts/shells/dev.nix - -if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD") -then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 -fi diff --git a/templates/home/.github/workflows/check-on-merge.yml b/templates/home/.github/workflows/check-on-merge.yml deleted file mode 100644 index abfe3a8..0000000 --- a/templates/home/.github/workflows/check-on-merge.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: "flake check" -on: - pull_request: - types: [opened, reopened, synchronize] -jobs: - check: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - - name: Check Nix flake Nixpkgs inputs - uses: DeterminateSystems/flake-checker-action@main diff --git a/templates/home/.github/workflows/flakehub.yml b/templates/home/.github/workflows/flakehub.yml deleted file mode 100644 index 615f9fb..0000000 --- a/templates/home/.github/workflows/flakehub.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "FlakeHub" -on: - push: - branches: - - "main" -jobs: - flakehub-publish: - if: false # NOTE: Comment out this line to enable flakehub - runs-on: "ubuntu-latest" - permissions: - id-token: "write" - contents: "read" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - uses: DeterminateSystems/flakehub-push@main - with: - name: "organization/repository" # TODO: add info - rolling: true - visibility: "public" diff --git a/templates/home/.github/workflows/update-flake-lock.yml b/templates/home/.github/workflows/update-flake-lock.yml deleted file mode 100644 index 701d59b..0000000 --- a/templates/home/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: update-flake-lock -on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 - -jobs: - lockfile: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - pr-title: "Automated action - Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR - dependencies - automated diff --git a/templates/home/.gitignore b/templates/home/.gitignore deleted file mode 100644 index 2d8df24..0000000 --- a/templates/home/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# OS generated files # -###################### -.DS_Store -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db - -# IDEA Ignores # -################ -*.iml -*.ipr -*.iws -.idea/ -out/ -local.properties - -# Project related # -################ -result/ -build/ - -result -.direnv/ -.devenv/ - -.devcontainer.json -.pre-commit-config.yaml diff --git a/templates/home/.gitlab-ci.yml b/templates/home/.gitlab-ci.yml deleted file mode 100644 index 2d3fabf..0000000 --- a/templates/home/.gitlab-ci.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: nixos/nix:latest -variables: - NIX_CONF_DIR: "/etc/nix" -before_script: - - echo 'experimental-features = nix-command flakes' > $NIX_CONF_DIR/nix.conf -check: - script: - - nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' diff --git a/templates/home/CHANGELOG.md b/templates/home/CHANGELOG.md deleted file mode 100644 index 825c32f..0000000 --- a/templates/home/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog diff --git a/templates/home/README.md b/templates/home/README.md deleted file mode 100644 index 23a85fe..0000000 --- a/templates/home/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# practicalFlakes - -## Description - -This flake has been generated from the -[tsandrini/practical-flakes-template](https://github.com/tsandrini/practical-flakes-template/) -project. The next steps for your development are - -1. **development environment** - - either use [direnv](https://github.com/direnv/direnv) and `direnv allow` - - or explicitly enter the shell via - `nix develop .#dev --override-input devenv-root "file+file://"<(printf %s "$PWD")` -1. **rename the project** - - while not many, there are some places in the code that have a `practicalFlakes` - identifier, you can use the `rename-project` (available in the dev environment) - script to change these - - `rename-project . myCoolNewProject` diff --git a/templates/home/flake.nix b/templates/home/flake.nix deleted file mode 100644 index 36ad4cc..0000000 --- a/templates/home/flake.nix +++ /dev/null @@ -1,114 +0,0 @@ -{ - description = "practicalFlakes - TODO Add a description of your new project"; - - inputs = { - # --- BASE DEPENDENCIES --- - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - systems.url = "github:nix-systems/default"; - - # --- DEV DEPENDENCIES --- - devenv.url = "github:cachix/devenv"; - devenv-root = { - url = "file+file:///dev/null"; - flake = false; - }; - mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - treefmt-nix.url = "github:numtide/treefmt-nix"; - - # --- (NOTE, YOUR) EXTRA DEPENDENCIES --- - home-manager = { - url = "github:nix-community/home-manager"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; - - # NOTE Here you can add additional binary cache substituers that you trust. - # There are also some sensible default caches commented out that you - # might consider using. - nixConfig = { - extra-trusted-public-keys = [ - # "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" - # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - extra-substituters = [ - # "https://devenv.cachix.org" - # "https://cache.nixos.org" - # "https://nix-community.cachix.org/" - ]; - }; - - outputs = - inputs@{ flake-parts, ... }: - let - inherit (inputs) nixpkgs; - inherit (lib.practicalFlakes) mapModules flatten; - - # You should ideally use relative paths in each individual part from ./parts, - # however, if needed you can use the `projectPath` variable that is passed - # to every flakeModule to properly anchor your absolute paths. - projectPath = ./.; - - # We extend the base library with our own custom helpers as well - # as override any of the nixpkgs default functions that we'd like - # to override. This instance is then passed to every part in ./parts so that - # you can use it in your custom modules - lib = nixpkgs.lib.extend ( - self: _super: { - practicalFlakes = import ./lib { - inherit inputs projectPath; - pkgs = nixpkgs; - lib = self; - }; - } - ); - specialArgs = { - inherit lib projectPath; - }; - in - flake-parts.lib.mkFlake { inherit inputs specialArgs; } { - # We recursively traverse all of the flakeModules in ./parts and import only - # the final modules, meaning that you can have an arbitrary nested structure - # that suffices your needs. For example - # - # - ./parts - # - modules/ - # - nixos/ - # - myNixosModule1.nix - # - myNixosModule2.nix - # - default.nix - # - home-manager/ - # - myHomeModule1.nix - # - myHomeModule2.nix - # - default.nix - # - sharedModules.nix - # - pkgs/ - # - myPackage1.nix - # - myPackage2.nix - # - default.nix - # - mySimpleModule.nix - imports = flatten (mapModules ./parts (x: x)); - - # NOTE We use the default `systems` defined by the `nix-systems` flake, if - # you need any additional systems, simply add them in the following manner - # - # `systems = (import inputs.systems) ++ [ "armv7l-linux" ];` - systems = import inputs.systems; - flake.lib = lib.practicalFlakes; - - # NOTE Since the official flakes output schema is unfortunately very - # limited you can enable the debug mode if you need to inspect certain - # outputs of your flake. Simply - # 1. uncomment the following line - # 2. hop into a repl from the project root - `nix repl` - # 3. load the flake - `:lf .` - # After that you can inspect the flake from the root attribute `debug.flake` - # - # debug = true; - }; -} diff --git a/templates/home/lib/.gitignore b/templates/home/lib/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/lib/_bootstrap-lib.nix b/templates/home/lib/_bootstrap-lib.nix deleted file mode 100644 index cefa2cd..0000000 --- a/templates/home/lib/_bootstrap-lib.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- lib/_bootstrap-lib.nix -{ lib, ... }: -with lib; -with builtins; -rec { - # This file should provide the bare minimum to bootstrap the lib, namely the - # mapModules' function to enable properly loading the library files and its - # functions - - mapFilterAttrs' = - pred: f: attrs: - filterAttrs pred (mapAttrs' f attrs); - - mapModules' = - dir: fn: - mapFilterAttrs' (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules' path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/home/lib/asserts.nix b/templates/home/lib/asserts.nix deleted file mode 100644 index c845309..0000000 --- a/templates/home/lib/asserts.nix +++ /dev/null @@ -1,13 +0,0 @@ -# --- lib/asserts.nix -_: { - # Example assertion - # ----------------- - # assertModulesLoaded = - # cfg: { - # assertion = hasAttr "practicalFlakes" cfg; - # message = '' - # Simple example assertion that checkc if the practicalFlakes namespace - # is present - # ''; - # }; -} diff --git a/templates/home/lib/attrsets.nix b/templates/home/lib/attrsets.nix deleted file mode 100644 index ed0d7f2..0000000 --- a/templates/home/lib/attrsets.nix +++ /dev/null @@ -1,65 +0,0 @@ -# --- lib/attrsets.nix -{ lib, ... }: -with lib; -with builtins; -{ - /* - Apply a map to every attribute of an attrset and then filter the resulting - attrset based on a given predicate function. - - *Type*: `mapFilterAttrs :: (AttrSet b -> Bool) -> (AttrSet a -> AttrSet b) -> AttrSet a -> AttrSet b` - */ - mapFilterAttrs = - # (AttrSet b -> Bool) Predicate used for filtering - pred: - # (AttrSet a -> AttrSet b) Function used for transforming the given AttrSets - f: - # (AttrSet a) Initial attrset - attrs: - filterAttrs pred (mapAttrs' f attrs); - - /* - Recursively merges a list of attrsets. - - *Type*: `mergeAttrs :: [AttrSet] -> AttrSet` - - Example: - ```nix title="Example" linenums="1" - mergeAttrs [ - { keyA = 1; keyB = 3; } - { keyB = 10; keyC = "hey"; nestedKey = { A = null; }; } - { nestedKey = { A = 3; B = 4; }; } - ] - => { keyA = 1; keyB = 10; keyC = "hey"; nestedKey = { A = 3; B = 4; };} - ``` - */ - mergeAttrs = - # ([AttrSet]) The list of attrsets - attrs: foldl' (acc: elem: acc // elem) { } attrs; - - /* - Recursively flattens a nested attrset into a list of just its values. - - *Type*: `flatten :: AttrSet a -> [a]` - - Example: - ```nix title="Example" linenums="1" - flatten { - keyA = 10; - keyB = "str20"; - keyC = { - keyD = false; - keyE = { - a = 10; - b = "20"; - c = false; - }; - }; - } - => [ 10 "str20" false 10 "20" false ] - ``` - */ - flatten = - # (AttrSet a) Initial nested attrset - attrs: collect (x: !isAttrs x) attrs; -} diff --git a/templates/home/lib/default.nix b/templates/home/lib/default.nix deleted file mode 100644 index 8fe4f76..0000000 --- a/templates/home/lib/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -# --- lib/default.nix -{ - pkgs, - lib, - inputs, - projectPath ? ./.., - ... -}: -let - inherit (bootstrap) mapModules'; - - bootstrap = import ./_bootstrap-lib.nix { inherit lib; }; - - practicalFlakes = lib.makeExtensible ( - self: - with self; - mapModules' ./. ( - file: - import file { - inherit - pkgs - lib - self - inputs - projectPath - ; - } - ) - ); -in -practicalFlakes.extend (_self: super: lib.foldr (a: b: a // b) { } (lib.attrValues super)) diff --git a/templates/home/lib/licenses.nix b/templates/home/lib/licenses.nix deleted file mode 100644 index 3c02c4f..0000000 --- a/templates/home/lib/licenses.nix +++ /dev/null @@ -1,2 +0,0 @@ -# --- lib/licenses.nix -_: { } diff --git a/templates/home/lib/lists.nix b/templates/home/lib/lists.nix deleted file mode 100644 index 3cdf869..0000000 --- a/templates/home/lib/lists.nix +++ /dev/null @@ -1,18 +0,0 @@ -# --- lib/lists.nix -_: { - # Example function - # ----------------- - /* - # Map function with flipped arguments. - - # *Type*: `flipMap :: (a -> b) -> [a] -> [b]` - - # Example: - # ```nix title="Example" linenums="1" - # flipmap (x: x * x) [ 1 2 3 ] - # => [ 1 4 9 ] - # ``` - # - */ - # flipMap = flip map; -} diff --git a/templates/home/lib/maintainers.nix b/templates/home/lib/maintainers.nix deleted file mode 100644 index 8cf4e05..0000000 --- a/templates/home/lib/maintainers.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- lib/maintainers.nix -_: { - # Example maintainer - # ----------------- - # exampleMaintainer = { - # email = "exampleMaintainer@myMail.com"; - # name = "Example Maintainer"; - # github = "exampleMaintainer"; - # githubId = 12345678; - # }; -} diff --git a/templates/home/lib/modules.nix b/templates/home/lib/modules.nix deleted file mode 100644 index e44c444..0000000 --- a/templates/home/lib/modules.nix +++ /dev/null @@ -1,53 +0,0 @@ -# --- lib/modules.nix -{ lib, self, ... }: -let - inherit (self.attrsets) mapFilterAttrs; -in -with lib; -with builtins; -rec { - /* - Recursively read a directory and apply a provided function to every `.nix` - file. Returns an attrset that reflects the filenames and directory - structure of the root. - - Notes: - - 1. Files and directories starting with the `_` or `.git` prefix will be completely - ignored. - - 2. If a directory with a `myDir/default.nix` file will be encountered, - the function will be applied to the `myDir/default.nix` file - instead of recursively loading `myDir` and applying it to every file. - - *Type*: `mapModules :: Path -> (Path -> AttrSet a) -> { name :: String; value :: AttrSet a; }` - - Example: - ```nix title="Example" linenums="1" - mapModules ./modules import - => { hardware = { moduleA = { ... }; }; system = { moduleB = { ... }; }; } - - mapModules ./hosts (host: mkHostCustomFunction myArg host) - => { hostA = { ... }; hostB = { ... }; } - ``` - */ - mapModules = - # (Path) Root directory on which should the recursive mapping be applied - dir: - # (Path -> AttrSet a) Function that transforms node paths to their custom attrsets - fn: - mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/home/lib/options.nix b/templates/home/lib/options.nix deleted file mode 100644 index e4c67ee..0000000 --- a/templates/home/lib/options.nix +++ /dev/null @@ -1,16 +0,0 @@ -# --- lib/options.nix -_: { - # Example function - # ----------------- - # /* - # Creates an enableOption (ie `mkEnableOption`), however, already - # preenabled. - # - # *Type*: `String -> Option` - # */ - # mkAlreadyEnabledOption = description: - # (mkEnableOption description) - # // { - # default = true; - # }; -} diff --git a/templates/home/lib/strings.nix b/templates/home/lib/strings.nix deleted file mode 100644 index 35b51b0..0000000 --- a/templates/home/lib/strings.nix +++ /dev/null @@ -1,20 +0,0 @@ -# --- lib/strings.nix -_: { - # Example function - # ----------------- - # /* - # Given an absolute path to a file, return the dirname of that file. - - # *Type*: `dirnameFromPath :: Path -> Path` - - # Example: - # ```nix title="Example" linenums="1" - # dirnameFromPath "/etc/myDir/file.nix" - # => "/etc/myDir" - # ``` - # */ - # dirnameFromPath = - # # (Path) Absolute path to a given file - # dir: - # trivial.pipe dir [toString (strings.splitString "/") lists.last]; -} diff --git a/templates/home/lib/types.nix b/templates/home/lib/types.nix deleted file mode 100644 index e7b9c94..0000000 --- a/templates/home/lib/types.nix +++ /dev/null @@ -1,8 +0,0 @@ -# --- lib/types.nix -_: { - # Example email type - # ------------------ - # email = - # addCheck str - # (str: match "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}" str != null); -} diff --git a/templates/home/parts/.gitignore b/templates/home/parts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/parts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/parts/homes/default.nix b/templates/home/parts/homes/default.nix deleted file mode 100644 index 5988e7f..0000000 --- a/templates/home/parts/homes/default.nix +++ /dev/null @@ -1,48 +0,0 @@ -# --- parts/homes/default.nix -# { -# lib, -# inputs, -# projectPath, -# withSystem, -# self, -# ... -# }: let -# mkHome = args: home: { -# extraSpecialArgs ? {}, -# extraModules ? [], -# extraOverlays ? [], -# ... -# }: -# inputs.home-manager.lib.homeManagerConfiguration { -# inherit (args) pkgs; -# extraSpecialArgs = -# { -# inherit (args) system self' inputs'; -# inherit inputs home projectPath self; -# } -# // extraSpecialArgs; -# modules = -# [ -# { -# nixpkgs.overlays = extraOverlays; -# nixpkgs.config.allowUnfree = true; -# } -# ./${home} -# ] -# ++ extraModules; -# }; -# in { -# options.flake.homeConfigurations = lib.mkOption { -# type = with lib.types; lazyAttrsOf unspecified; -# default = {}; -# }; -# config = { -# flake.homeConfigurations = { -# "myHost@myUser" = withSystem "x86_64-linux" (args: mkHome args "myHost@myUser" {}); -# }; -# flake.checks."x86_64-linux" = { -# "home-myHost@myUser" = config.flake.homeConfigurations."myHost@myUser".config.home.path; -# }; -# }; -# } -{ } diff --git a/templates/home/parts/hosts/.gitignore b/templates/home/parts/hosts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/parts/hosts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/parts/hosts/default.nix b/templates/home/parts/hosts/default.nix deleted file mode 100644 index 5680ab5..0000000 --- a/templates/home/parts/hosts/default.nix +++ /dev/null @@ -1,66 +0,0 @@ -# --- parts/hosts/default.nix -# { -# lib, -# inputs, -# self, -# projectPath, -# withSystem, -# ... -# }: let -# mkHost = args: hostName: { -# extraSpecialArgs ? {}, -# extraModules ? [], -# extraOverlays ? [], -# withHomeManager ? false, -# ... -# }: let -# baseSpecialArgs = -# { -# inherit (args) system self' inputs'; -# inherit inputs self hostName projectPath; -# } -# // extraSpecialArgs; -# in -# lib.nixosSystem { -# inherit (args) system; -# specialArgs = -# baseSpecialArgs -# // { -# inherit lib hostName; -# host.hostName = hostName; -# }; -# modules = -# [ -# { -# nixpkgs.overlays = extraOverlays; -# nixpkgs.config.allowUnfree = true; -# networking.hostName = hostName; -# } -# ./${hostName} -# ] -# ++ extraModules -# ++ ( -# if withHomeManager -# then [ -# inputs.home-manager.nixosModules.home-manager -# { -# home-manager = { -# useGlobalPkgs = true; -# useUserPackages = true; -# extraSpecialArgs = baseSpecialArgs; -# sharedModules = [] # TODO: add shared modules here; -# }; -# } -# ] -# else [] -# ); -# }; -# in { -# flake.nixosConfigurations = { -# exampleHost = withSystem "x86_64-linux" (args: mkHost args "exampleHost" {}); -# anotherExampleHost = withSystem "x86_64-linux" (args: mkHost args "anotherExampleHost" { -# withHomeManager = true; -# }); -# }; -# } -{ } diff --git a/templates/home/parts/modules/.gitignore b/templates/home/parts/modules/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/parts/modules/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/parts/modules/default.nix b/templates/home/parts/modules/default.nix deleted file mode 100644 index 16728d9..0000000 --- a/templates/home/parts/modules/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -# --- parts/modules/default.nix -_: { - imports = [ - ./nixos - ./home-manager - ]; -} diff --git a/templates/home/parts/modules/home-manager/default.nix b/templates/home/parts/modules/home-manager/default.nix deleted file mode 100644 index 3f9de11..0000000 --- a/templates/home/parts/modules/home-manager/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -# --- parts/modules/home-manager/default.nix -{ - inputs, - self, - lib, - ... -}: -let - inherit (inputs.flake-parts.lib) importApply; - localFlake = self; -in -{ - options.flake.homeModules = lib.mkOption { - type = with lib.types; lazyAttrsOf unspecified; - default = { }; - }; - - config.flake.homeModules = { - example-module = importApply ./example-module.nix { inherit localFlake; }; - }; -} diff --git a/templates/home/parts/modules/home-manager/example-module.nix b/templates/home/parts/modules/home-manager/example-module.nix deleted file mode 100644 index 3947216..0000000 --- a/templates/home/parts/modules/home-manager/example-module.nix +++ /dev/null @@ -1,40 +0,0 @@ -# --- parts/modules/home-manager/example-module.nix -{ localFlake }: -{ - config, - lib, - pkgs, - ... -}: -with builtins; -with lib; -let - inherit (localFlake.lib) mkOverrideAtModuleLevel; - - cfg = config.practicalFlakes.hm.example-module; - _ = mkOverrideAtModuleLevel; -in -{ - options.practicalFlakes.hm.example-module = with types; { - enable = mkEnableOption (mdDoc '' - Enable the NixOS example module that enables neovim and installs git - ''); - }; - - config = mkIf cfg.enable (mkMerge [ - # |----------------------------------------------------------------------| # - { - home.packages = with pkgs; [ git ]; - - # By using mkOverrideAtModuleLevel we can set a sensible override - # priority that is higher than the /modules priority, however, - # it can still be easily changed by the end user in their host/home - # configurations. - programs.neovim.enable = _ true; - home.sessionVariables.MY_AWESOME_VAR = _ "Hello, everything working!"; - } - # |----------------------------------------------------------------------| # - ]); - - meta.maintainers = with localFlake.lib.maintainers; [ ]; -} diff --git a/templates/home/parts/modules/nixos/default.nix b/templates/home/parts/modules/nixos/default.nix deleted file mode 100644 index 55eb995..0000000 --- a/templates/home/parts/modules/nixos/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/modules/nixos/default.nix -{ inputs, self, ... }: -let - inherit (inputs.flake-parts.lib) importApply; - localFlake = self; -in -{ - flake.nixosModules = { - example-module = importApply ./example-module.nix { inherit localFlake; }; - }; -} diff --git a/templates/home/parts/modules/nixos/example-module.nix b/templates/home/parts/modules/nixos/example-module.nix deleted file mode 100644 index 277e1d0..0000000 --- a/templates/home/parts/modules/nixos/example-module.nix +++ /dev/null @@ -1,39 +0,0 @@ -# --- parts/modules/nixos/example-module.nix -{ localFlake }: -{ - config, - lib, - pkgs, - ... -}: -with builtins; -with lib; -let - inherit (localFlake.lib) mkOverrideAtModuleLevel; - - cfg = config.practicalFlakes.example-module; - _ = mkOverrideAtModuleLevel; -in -{ - options.practicalFlakes.example-module = with types; { - enable = mkEnableOption (mdDoc '' - Enable the NixOS example module that enables neovim and installs git - ''); - }; - - config = mkIf cfg.enable (mkMerge [ - # |----------------------------------------------------------------------| # - { - environment.systemPackages = with pkgs; [ git ]; - - # By using mkOverrideAtModuleLevel we can set a sensible override - # priority that is higher than the /modules priority, however, - # it can still be easily changed by the end user in their host/home - # configurations. - programs.neovim.enable = _ true; - } - # |----------------------------------------------------------------------| # - ]); - - meta.maintainers = with localFlake.lib.maintainers; [ ]; -} diff --git a/templates/home/parts/pkgs/.gitignore b/templates/home/parts/pkgs/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/parts/pkgs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/parts/pkgs/default.nix b/templates/home/parts/pkgs/default.nix deleted file mode 100644 index 9291148..0000000 --- a/templates/home/parts/pkgs/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/pkgs/default.nix -{ lib, ... }: -{ - perSystem = - { pkgs, system, ... }: - { - packages = { - example-package = pkgs.callPackage ./example-package.nix { inherit lib system; }; - }; - }; -} diff --git a/templates/home/parts/pkgs/example-package.nix b/templates/home/parts/pkgs/example-package.nix deleted file mode 100644 index e5f8f24..0000000 --- a/templates/home/parts/pkgs/example-package.nix +++ /dev/null @@ -1,24 +0,0 @@ -# --- parts/pkgs/example-package.nix -{ - lib, - system, - stdenv, - ... -}: -stdenv.mkDerivation rec { - name = "example-pkg"; - version = "v0.1.0"; - - src = ./.; - installPhase = '' - mkdir -p $out - echo "Hello, this is an example package" > $out/example.txt - ''; - - meta = with lib; { - description = "Example package"; - license = licenses.mit; - platforms = [ system ]; - maintainers = [ ]; - }; -} diff --git a/templates/home/parts/shells/.gitignore b/templates/home/parts/shells/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/parts/shells/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/parts/shells/default.nix b/templates/home/parts/shells/default.nix deleted file mode 100644 index 2cbee09..0000000 --- a/templates/home/parts/shells/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -# --- parts/shells/default.nix -{ inputs, projectPath, ... }: -{ - imports = with inputs; [ devenv.flakeModule ]; - - perSystem = - { config, pkgs, ... }: - { - devenv.shells.dev = import ./dev.nix { - inherit pkgs projectPath; - inherit (inputs) devenv-root; - treefmt = config.treefmt.build.wrapper; - }; - }; -} diff --git a/templates/home/parts/shells/dev.nix b/templates/home/parts/shells/dev.nix deleted file mode 100644 index acd241b..0000000 --- a/templates/home/parts/shells/dev.nix +++ /dev/null @@ -1,137 +0,0 @@ -# --- parts/shells/dev.nix - -{ - pkgs, - treefmt, - devenv-root, - ... -}: -{ - # DEVENV: Fast, Declarative, Reproducible, and Composable Developer - # Environments using Nix developed by Cachix. For more information refer to - # - # - https://devenv.sh/ - # - https://github.com/cachix/devenv - - # -------------------------- - # --- ENV & SHELL & PKGS --- - # -------------------------- - packages = with pkgs; [ - # -- NIX UTILS -- - nix-output-monitor # Processes output of Nix commands to show helpful and pretty information - nixfmt-rfc-style # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt # An opinionated formatter for Nix - # alejandra # The Uncompromising Nix Code Formatter - nh # Yet another nix cli helper - - # -- GIT RELATED UTILS -- - # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs - # cz-cli # The commitizen command line utility - # fh # The official FlakeHub CLI - # gh # GitHub CLI tool - - # -- BASE LANG UTILS -- - markdownlint-cli # Command line interface for MarkdownLint - typos # Source code spell checker - treefmt # one CLI to format the code tree - - # -- (YOUR) EXTRA PKGS -- - ]; - - # env = { - # MYUSER = "user"; - # # ... - # }; - - # NOTE If you'd like to automatically load a .env file you can use these - # following expressions - # - # dotenv.enable = true; - # dotenv.filename = ".env.development"; - - enterShell = '' - # Welcome splash text - echo ""; echo -e "\e[1;37;42mWelcome to the practicalFlakes devshell!\e[0m"; echo "" - ''; - - # --------------- - # --- SCRIPTS --- - # --------------- - scripts = { - "rename-project".exec = '' - find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/practicalFlakes/$2/g" - ''; - }; - - # ----------------- - # --- LANGUAGES --- - # ----------------- - languages.nix.enable = true; - - # NOTE You can enable additional language support in the following manner - # languages.python.enable = true; - # languages.python.version = "3.11.3"; - - # languages.rust.enable = true; - # languages.rust.channel = "stable"; - - # ---------------------------- - # --- PROCESSES & SERVICES --- - # ---------------------------- - - # ------------------ - # --- CONTAINERS --- - # ------------------ - devcontainer.enable = true; - - # ---------------------- - # --- BINARY CACHING --- - # ---------------------- - # NOTE Here you can configure automatic cachix binary cache pulling & pushing - # to/from a cache named "mycache" - # - # cachix.pull = [ "pre-commit-hooks" ]; - # cachix.push = "mycache"; - - # ------------------------ - # --- PRE-COMMIT HOOKS --- - # ------------------------ - # NOTE All available hooks options are listed at - # https://devenv.sh/reference/options/#pre-commithooks - pre-commit = { - hooks = { - treefmt.enable = true; - # We pass our custom treefmt build from parts/treefmt/treefmt.nix for - # devenv to use. - treefmt.package = treefmt; - - nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. - editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig - markdownlint.enable = true; # Markdown lint tool - # typos.enable = true; # Source code spell checker - - # actionlint.enable = true; # GitHub workflows linting - # commitizen.enable = true; # Commitizen is release management tool designed for teams. - }; - }; - - # -------------- - # --- FLAKES --- - # -------------- - devenv.flakesIntegration = true; - - # This is currently needed for devenv to properly run in pure hermetic - # mode while still being able to run processes & services and modify - # (some parts) of the active shell. - devenv.root = - let - devenvRootFileContent = builtins.readFile devenv-root.outPath; - in - pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; - - # --------------------- - # --- MISCELLANEOUS --- - # --------------------- - difftastic.enable = true; -} diff --git a/templates/home/parts/treefmt/.gitignore b/templates/home/parts/treefmt/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/home/parts/treefmt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/home/parts/treefmt/default.nix b/templates/home/parts/treefmt/default.nix deleted file mode 100644 index 7f3112e..0000000 --- a/templates/home/parts/treefmt/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/treefmt/default.nix -{ projectPath, inputs, ... }: -{ - imports = with inputs; [ treefmt-nix.flakeModule ]; - - perSystem = - { pkgs, ... }: - { - treefmt = import ./treefmt.nix { inherit pkgs projectPath; }; - }; -} diff --git a/templates/home/parts/treefmt/treefmt.nix b/templates/home/parts/treefmt/treefmt.nix deleted file mode 100644 index 13025fb..0000000 --- a/templates/home/parts/treefmt/treefmt.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- parts/treefmt/treefmt.nix -{ pkgs, projectPath, ... }: -{ - # treefmt is a formatting tool that saves you time: it provides - # developers with a universal way to trigger all formatters needed for the - # project in one place. - # For more information refer to - # - # - https://numtide.github.io/treefmt/ - # - https://github.com/numtide/treefmt-nix - - package = pkgs.treefmt; - flakeCheck = true; - flakeFormatter = true; - projectRootFile = projectPath + "/flake.nix"; - - programs = { - deadnix.enable = true; # Find and remove unused code in .nix source files - statix.enable = true; # Lints and suggestions for the nix programming language - nixfmt-rfc-style.enable = true; # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt.enable = true; # An opinionated formatter for Nix - # alejandra.enable = true; # The Uncompromising Nix Code Formatter - - prettier.enable = true; # Prettier is an opinionated code formatter - mdformat.enable = true; # CommonMark compliant Markdown formatter - yamlfmt.enable = true; # An extensible command line tool or library to format yaml files. - jsonfmt.enable = true; # Formatter for JSON files - }; -} diff --git a/templates/isolated-minimal/.envrc b/templates/isolated-minimal/.envrc deleted file mode 100644 index 6c4b45d..0000000 --- a/templates/isolated-minimal/.envrc +++ /dev/null @@ -1,12 +0,0 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -watch_file flake.nix -watch_file flake.lock -watch_file nix/parts/shells/dev.nix - -if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD") -then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 -fi diff --git a/templates/isolated-minimal/.github/pull_request_template.md b/templates/isolated-minimal/.github/pull_request_template.md deleted file mode 100644 index c3811fd..0000000 --- a/templates/isolated-minimal/.github/pull_request_template.md +++ /dev/null @@ -1,42 +0,0 @@ -# TODO: Place a short descriptive PR name here - -## Overview - - - -## Testing - - - -## Dependencies (flake inputs) - - - -## Checklist - - - -- \[ \] I have tested the relevant changes locally. -- \[ \] I have checked that - `nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD")` - passes. -- \[ \] I have ensured my commits follow the project's commits guidelines. -- \[ \] I have checked that the changes follow a linear history. -- \[ \] (If applicable) I have commented any relevant parts of my code. -- \[ \] (If applicable) I have added appropriate unit/feature tests. -- \[ \] (If applicable) I have updated the documentation accordingly (in English). - -## Additional Notes - - diff --git a/templates/isolated-minimal/.github/workflows/check-on-merge.yml b/templates/isolated-minimal/.github/workflows/check-on-merge.yml deleted file mode 100644 index abfe3a8..0000000 --- a/templates/isolated-minimal/.github/workflows/check-on-merge.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: "flake check" -on: - pull_request: - types: [opened, reopened, synchronize] -jobs: - check: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - - name: Check Nix flake Nixpkgs inputs - uses: DeterminateSystems/flake-checker-action@main diff --git a/templates/isolated-minimal/.github/workflows/flakehub.yml b/templates/isolated-minimal/.github/workflows/flakehub.yml deleted file mode 100644 index 615f9fb..0000000 --- a/templates/isolated-minimal/.github/workflows/flakehub.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "FlakeHub" -on: - push: - branches: - - "main" -jobs: - flakehub-publish: - if: false # NOTE: Comment out this line to enable flakehub - runs-on: "ubuntu-latest" - permissions: - id-token: "write" - contents: "read" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - uses: DeterminateSystems/flakehub-push@main - with: - name: "organization/repository" # TODO: add info - rolling: true - visibility: "public" diff --git a/templates/isolated-minimal/.github/workflows/update-flake-lock.yml b/templates/isolated-minimal/.github/workflows/update-flake-lock.yml deleted file mode 100644 index 701d59b..0000000 --- a/templates/isolated-minimal/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: update-flake-lock -on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 - -jobs: - lockfile: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - pr-title: "Automated action - Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR - dependencies - automated diff --git a/templates/isolated-minimal/.gitignore b/templates/isolated-minimal/.gitignore deleted file mode 100644 index 2d8df24..0000000 --- a/templates/isolated-minimal/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# OS generated files # -###################### -.DS_Store -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db - -# IDEA Ignores # -################ -*.iml -*.ipr -*.iws -.idea/ -out/ -local.properties - -# Project related # -################ -result/ -build/ - -result -.direnv/ -.devenv/ - -.devcontainer.json -.pre-commit-config.yaml diff --git a/templates/isolated-minimal/.gitlab-ci.yml b/templates/isolated-minimal/.gitlab-ci.yml deleted file mode 100644 index 2d3fabf..0000000 --- a/templates/isolated-minimal/.gitlab-ci.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: nixos/nix:latest -variables: - NIX_CONF_DIR: "/etc/nix" -before_script: - - echo 'experimental-features = nix-command flakes' > $NIX_CONF_DIR/nix.conf -check: - script: - - nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' diff --git a/templates/isolated-minimal/CHANGELOG.md b/templates/isolated-minimal/CHANGELOG.md deleted file mode 100644 index 825c32f..0000000 --- a/templates/isolated-minimal/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog diff --git a/templates/isolated-minimal/README.md b/templates/isolated-minimal/README.md deleted file mode 100644 index 23a85fe..0000000 --- a/templates/isolated-minimal/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# practicalFlakes - -## Description - -This flake has been generated from the -[tsandrini/practical-flakes-template](https://github.com/tsandrini/practical-flakes-template/) -project. The next steps for your development are - -1. **development environment** - - either use [direnv](https://github.com/direnv/direnv) and `direnv allow` - - or explicitly enter the shell via - `nix develop .#dev --override-input devenv-root "file+file://"<(printf %s "$PWD")` -1. **rename the project** - - while not many, there are some places in the code that have a `practicalFlakes` - identifier, you can use the `rename-project` (available in the dev environment) - script to change these - - `rename-project . myCoolNewProject` diff --git a/templates/isolated-minimal/flake.nix b/templates/isolated-minimal/flake.nix deleted file mode 100644 index 4664f67..0000000 --- a/templates/isolated-minimal/flake.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - description = "practicalFlakes - TODO Add a description of your new project"; - - inputs = { - # --- BASE DEPENDENCIES --- - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - systems.url = "github:nix-systems/default"; - - # --- DEV DEPENDENCIES --- - devenv.url = "github:cachix/devenv"; - devenv-root = { - url = "file+file:///dev/null"; - flake = false; - }; - mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - treefmt-nix.url = "github:numtide/treefmt-nix"; - - # --- (NOTE, YOUR) EXTRA DEPENDENCIES --- - }; - - # NOTE Here you can add additional binary cache substituers that you trust. - # There are also some sensible default caches commented out that you - # might consider using. - nixConfig = { - extra-trusted-public-keys = [ - # "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" - # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - extra-substituters = [ - # "https://devenv.cachix.org" - # "https://cache.nixos.org" - # "https://nix-community.cachix.org/" - ]; - }; - - outputs = - inputs@{ flake-parts, ... }: - let - inherit (inputs) nixpkgs; - inherit (lib.practicalFlakes) mapModules flatten; - - # You should ideally use relative paths in each individual part from ./parts, - # however, if needed you can use the `projectPath` variable that is passed - # to every flakeModule to properly anchor your absolute paths. - projectPath = ./.; - - # We extend the base library with our own custom helpers as well - # as override any of the nixpkgs default functions that we'd like - # to override. This instance is then passed to every part in ./parts so that - # you can use it in your custom modules - lib = nixpkgs.lib.extend ( - self: _super: { - practicalFlakes = import ./nix/lib { - inherit inputs projectPath; - pkgs = nixpkgs; - lib = self; - }; - } - ); - specialArgs = { - inherit lib projectPath; - }; - in - flake-parts.lib.mkFlake { inherit inputs specialArgs; } { - # We recursively traverse all of the flakeModules in ./parts and import only - # the final modules, meaning that you can have an arbitrary nested structure - # that suffices your needs. For example - # - # - ./nix/parts - # - modules/ - # - nixos/ - # - myNixosModule1.nix - # - myNixosModule2.nix - # - default.nix - # - home-manager/ - # - myHomeModule1.nix - # - myHomeModule2.nix - # - default.nix - # - sharedModules.nix - # - pkgs/ - # - myPackage1.nix - # - myPackage2.nix - # - default.nix - # - mySimpleModule.nix - imports = flatten (mapModules ./nix/parts (x: x)); - - # NOTE We use the default `systems` defined by the `nix-systems` flake, if - # you need any additional systems, simply add them in the following manner - # - # `systems = (import inputs.systems) ++ [ "armv7l-linux" ];` - systems = import inputs.systems; - flake.lib = lib.practicalFlakes; - - # NOTE Since the official flakes output schema is unfortunately very - # limited you can enable the debug mode if you need to inspect certain - # outputs of your flake. Simply - # 1. uncomment the following line - # 2. hop into a repl from the project root - `nix repl` - # 3. load the flake - `:lf .` - # After that you can inspect the flake from the root attribute `debug.flake` - # - # debug = true; - }; -} diff --git a/templates/isolated-minimal/nix/.gitignore b/templates/isolated-minimal/nix/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated-minimal/nix/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated-minimal/nix/lib/.gitignore b/templates/isolated-minimal/nix/lib/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated-minimal/nix/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated-minimal/nix/lib/_bootstrap-lib.nix b/templates/isolated-minimal/nix/lib/_bootstrap-lib.nix deleted file mode 100644 index 62de8f3..0000000 --- a/templates/isolated-minimal/nix/lib/_bootstrap-lib.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- nix/lib/_bootstrap-lib.nix -{ lib, ... }: -with lib; -with builtins; -rec { - # This file should provide the bare minimum to bootstrap the lib, namely the - # mapModules' function to enable properly loading the library files and its - # functions - - mapFilterAttrs' = - pred: f: attrs: - filterAttrs pred (mapAttrs' f attrs); - - mapModules' = - dir: fn: - mapFilterAttrs' (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules' path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/isolated-minimal/nix/lib/attrsets.nix b/templates/isolated-minimal/nix/lib/attrsets.nix deleted file mode 100644 index fde2977..0000000 --- a/templates/isolated-minimal/nix/lib/attrsets.nix +++ /dev/null @@ -1,65 +0,0 @@ -# --- nix/lib/attrsets.nix -{ lib, ... }: -with lib; -with builtins; -rec { - /* - Apply a map to every attribute of an attrset and then filter the resulting - attrset based on a given predicate function. - - *Type*: `mapFilterAttrs :: (AttrSet b -> Bool) -> (AttrSet a -> AttrSet b) -> AttrSet a -> AttrSet b` - */ - mapFilterAttrs = - # (AttrSet b -> Bool) Predicate used for filtering - pred: - # (AttrSet a -> AttrSet b) Function used for transforming the given AttrSets - f: - # (AttrSet a) Initial attrset - attrs: - filterAttrs pred (mapAttrs' f attrs); - - /* - Recursively merges a list of attrsets. - - *Type*: `mergeAttrs :: [AttrSet] -> AttrSet` - - Example: - ```nix title="Example" linenums="1" - mergeAttrs [ - { keyA = 1; keyB = 3; } - { keyB = 10; keyC = "hey"; nestedKey = { A = null; }; } - { nestedKey = { A = 3; B = 4; }; } - ] - => { keyA = 1; keyB = 10; keyC = "hey"; nestedKey = { A = 3; B = 4; };} - ``` - */ - mergeAttrs = - # ([AttrSet]) The list of attrsets - attrs: foldl' (acc: elem: acc // elem) { } attrs; - - /* - Recursively flattens a nested attrset into a list of just its values. - - *Type*: `flatten :: AttrSet a -> [a]` - - Example: - ```nix title="Example" linenums="1" - flatten { - keyA = 10; - keyB = "str20"; - keyC = { - keyD = false; - keyE = { - a = 10; - b = "20"; - c = false; - }; - }; - } - => [ 10 "str20" false 10 "20" false ] - ``` - */ - flatten = - # (AttrSet a) Initial nested attrset - attrs: collect (x: !isAttrs x) attrs; -} diff --git a/templates/isolated-minimal/nix/lib/default.nix b/templates/isolated-minimal/nix/lib/default.nix deleted file mode 100644 index 5b0899c..0000000 --- a/templates/isolated-minimal/nix/lib/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -# --- nix/lib/default.nix -{ - pkgs, - lib, - inputs, - projectPath ? ./.., - ... -}: -let - inherit (bootstrap) mapModules'; - - bootstrap = import ./_bootstrap-lib.nix { inherit lib; }; - - practicalFlakes = lib.makeExtensible ( - self: - with self; - mapModules' ./. ( - file: - import file { - inherit - pkgs - lib - self - inputs - projectPath - ; - } - ) - ); -in -practicalFlakes.extend (_self: super: lib.foldr (a: b: a // b) { } (lib.attrValues super)) diff --git a/templates/isolated-minimal/nix/lib/modules.nix b/templates/isolated-minimal/nix/lib/modules.nix deleted file mode 100644 index af5566e..0000000 --- a/templates/isolated-minimal/nix/lib/modules.nix +++ /dev/null @@ -1,53 +0,0 @@ -# --- nix/lib/modules.nix -{ lib, self, ... }: -let - inherit (self.attrsets) mapFilterAttrs; -in -with lib; -with builtins; -rec { - /* - Recursively read a directory and apply a provided function to every `.nix` - file. Returns an attrset that reflects the filenames and directory - structure of the root. - - Notes: - - 1. Files and directories starting with the `_` or `.git` prefix will be completely - ignored. - - 2. If a directory with a `myDir/default.nix` file will be encountered, - the function will be applied to the `myDir/default.nix` file - instead of recursively loading `myDir` and applying it to every file. - - *Type*: `mapModules :: Path -> (Path -> AttrSet a) -> { name :: String; value :: AttrSet a; }` - - Example: - ```nix title="Example" linenums="1" - mapModules ./modules import - => { hardware = { moduleA = { ... }; }; system = { moduleB = { ... }; }; } - - mapModules ./hosts (host: mkHostCustomFunction myArg host) - => { hostA = { ... }; hostB = { ... }; } - ``` - */ - mapModules = - # (Path) Root directory on which should the recursive mapping be applied - dir: - # (Path -> AttrSet a) Function that transforms node paths to their custom attrsets - fn: - mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/isolated-minimal/nix/parts/.gitignore b/templates/isolated-minimal/nix/parts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated-minimal/nix/parts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated-minimal/nix/parts/shells/.gitignore b/templates/isolated-minimal/nix/parts/shells/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated-minimal/nix/parts/shells/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated-minimal/nix/parts/shells/default.nix b/templates/isolated-minimal/nix/parts/shells/default.nix deleted file mode 100644 index 5cd214f..0000000 --- a/templates/isolated-minimal/nix/parts/shells/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -# --- nix/parts/shells/default.nix -{ inputs, projectPath, ... }: -{ - imports = with inputs; [ devenv.flakeModule ]; - - perSystem = - { config, pkgs, ... }: - { - devenv.shells.dev = import ./dev.nix { - inherit pkgs projectPath; - inherit (inputs) devenv-root; - treefmt = config.treefmt.build.wrapper; - }; - }; -} diff --git a/templates/isolated-minimal/nix/parts/shells/dev.nix b/templates/isolated-minimal/nix/parts/shells/dev.nix deleted file mode 100644 index 0a7463b..0000000 --- a/templates/isolated-minimal/nix/parts/shells/dev.nix +++ /dev/null @@ -1,113 +0,0 @@ -# --- nix/parts/shells/dev.nix -{ - pkgs, - treefmt, - devenv-root, - ... -}: -{ - # DEVENV: Fast, Declarative, Reproducible, and Composable Developer - # Environments using Nix developed by Cachix. For more information refer to - # - # - https://devenv.sh/ - # - https://github.com/cachix/devenv - - # -------------------------- - # --- ENV & SHELL & PKGS --- - # -------------------------- - packages = with pkgs; [ - # -- NIX UTILS -- - nix-output-monitor # Processes output of Nix commands to show helpful and pretty information - nixfmt-rfc-style # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt # An opinionated formatter for Nix - # alejandra # The Uncompromising Nix Code Formatter - nh # Yet another nix cli helper - - # -- GIT RELATED UTILS -- - # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs - # cz-cli # The commitizen command line utility - # fh # The official FlakeHub CLI - # gh # GitHub CLI tool - - # -- BASE LANG UTILS -- - markdownlint-cli # Command line interface for MarkdownLint - typos # Source code spell checker - treefmt # one CLI to format the code tree - - # -- (YOUR) EXTRA PKGS -- - ]; - - enterShell = '' - # Welcome splash text - echo ""; echo -e "\e[1;37;42mWelcome to the practicalFlakes devshell!\e[0m"; echo "" - ''; - - # --------------- - # --- SCRIPTS --- - # --------------- - scripts = { - "rename-project".exec = '' - find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/practicalFlakes/$2/g" - ''; - }; - - # ----------------- - # --- LANGUAGES --- - # ----------------- - languages.nix.enable = true; - - # ---------------------------- - # --- PROCESSES & SERVICES --- - # ---------------------------- - - # ------------------ - # --- CONTAINERS --- - # ------------------ - devcontainer.enable = true; - - # ---------------------- - # --- BINARY CACHING --- - # ---------------------- - - # ------------------------ - # --- PRE-COMMIT HOOKS --- - # ------------------------ - # NOTE All available hooks options are listed at - # https://devenv.sh/reference/options/#pre-commithooks - pre-commit = { - hooks = { - treefmt.enable = true; - # We pass our custom treefmt build from parts/treefmt/treefmt.nix for - # devenv to use. - treefmt.package = treefmt; - - nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. - editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig - markdownlint.enable = true; # Markdown lint tool - # typos.enable = true; # Source code spell checker - - # actionlint.enable = true; # GitHub workflows linting - # commitizen.enable = true; # Commitizen is release management tool designed for teams. - }; - }; - - # -------------- - # --- FLAKES --- - # -------------- - devenv.flakesIntegration = true; - - # This is currently needed for devenv to properly run in pure hermetic - # mode while still being able to run processes & services and modify - # (some parts) of the active shell. - devenv.root = - let - devenvRootFileContent = builtins.readFile devenv-root.outPath; - in - pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; - - # --------------------- - # --- MISCELLANEOUS --- - # --------------------- - difftastic.enable = true; -} diff --git a/templates/isolated-minimal/nix/parts/treefmt/.gitignore b/templates/isolated-minimal/nix/parts/treefmt/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated-minimal/nix/parts/treefmt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated-minimal/nix/parts/treefmt/default.nix b/templates/isolated-minimal/nix/parts/treefmt/default.nix deleted file mode 100644 index 6b67334..0000000 --- a/templates/isolated-minimal/nix/parts/treefmt/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- nix/parts/treefmt/default.nix -{ projectPath, inputs, ... }: -{ - imports = with inputs; [ treefmt-nix.flakeModule ]; - - perSystem = - { pkgs, ... }: - { - treefmt = import ./treefmt.nix { inherit pkgs projectPath; }; - }; -} diff --git a/templates/isolated-minimal/nix/parts/treefmt/treefmt.nix b/templates/isolated-minimal/nix/parts/treefmt/treefmt.nix deleted file mode 100644 index dfd3bde..0000000 --- a/templates/isolated-minimal/nix/parts/treefmt/treefmt.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- nix/parts/treefmt/treefmt.nix -{ pkgs, projectPath, ... }: -{ - # treefmt is a formatting tool that saves you time: it provides - # developers with a universal way to trigger all formatters needed for the - # project in one place. - # For more information refer to - # - # - https://numtide.github.io/treefmt/ - # - https://github.com/numtide/treefmt-nix - - package = pkgs.treefmt; - flakeCheck = true; - flakeFormatter = true; - projectRootFile = projectPath + "/flake.nix"; - - programs = { - deadnix.enable = true; # Find and remove unused code in .nix source files - statix.enable = true; # Lints and suggestions for the nix programming language - nixfmt-rfc-style.enable = true; # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt.enable = true; # An opinionated formatter for Nix - # alejandra.enable = true; # The Uncompromising Nix Code Formatter - - prettier.enable = true; # Prettier is an opinionated code formatter - mdformat.enable = true; # CommonMark compliant Markdown formatter - yamlfmt.enable = true; # An extensible command line tool or library to format yaml files. - jsonfmt.enable = true; # Formatter for JSON files - }; -} diff --git a/templates/isolated/.envrc b/templates/isolated/.envrc deleted file mode 100644 index 6c4b45d..0000000 --- a/templates/isolated/.envrc +++ /dev/null @@ -1,12 +0,0 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -watch_file flake.nix -watch_file flake.lock -watch_file nix/parts/shells/dev.nix - -if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD") -then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 -fi diff --git a/templates/isolated/.github/pull_request_template.md b/templates/isolated/.github/pull_request_template.md deleted file mode 100644 index c3811fd..0000000 --- a/templates/isolated/.github/pull_request_template.md +++ /dev/null @@ -1,42 +0,0 @@ -# TODO: Place a short descriptive PR name here - -## Overview - - - -## Testing - - - -## Dependencies (flake inputs) - - - -## Checklist - - - -- \[ \] I have tested the relevant changes locally. -- \[ \] I have checked that - `nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD")` - passes. -- \[ \] I have ensured my commits follow the project's commits guidelines. -- \[ \] I have checked that the changes follow a linear history. -- \[ \] (If applicable) I have commented any relevant parts of my code. -- \[ \] (If applicable) I have added appropriate unit/feature tests. -- \[ \] (If applicable) I have updated the documentation accordingly (in English). - -## Additional Notes - - diff --git a/templates/isolated/.github/workflows/check-on-merge.yml b/templates/isolated/.github/workflows/check-on-merge.yml deleted file mode 100644 index abfe3a8..0000000 --- a/templates/isolated/.github/workflows/check-on-merge.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: "flake check" -on: - pull_request: - types: [opened, reopened, synchronize] -jobs: - check: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - - name: Check Nix flake Nixpkgs inputs - uses: DeterminateSystems/flake-checker-action@main diff --git a/templates/isolated/.github/workflows/flakehub.yml b/templates/isolated/.github/workflows/flakehub.yml deleted file mode 100644 index 615f9fb..0000000 --- a/templates/isolated/.github/workflows/flakehub.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "FlakeHub" -on: - push: - branches: - - "main" -jobs: - flakehub-publish: - if: false # NOTE: Comment out this line to enable flakehub - runs-on: "ubuntu-latest" - permissions: - id-token: "write" - contents: "read" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - uses: DeterminateSystems/flakehub-push@main - with: - name: "organization/repository" # TODO: add info - rolling: true - visibility: "public" diff --git a/templates/isolated/.github/workflows/update-flake-lock.yml b/templates/isolated/.github/workflows/update-flake-lock.yml deleted file mode 100644 index 701d59b..0000000 --- a/templates/isolated/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: update-flake-lock -on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 - -jobs: - lockfile: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - pr-title: "Automated action - Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR - dependencies - automated diff --git a/templates/isolated/.gitignore b/templates/isolated/.gitignore deleted file mode 100644 index 2d8df24..0000000 --- a/templates/isolated/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# OS generated files # -###################### -.DS_Store -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db - -# IDEA Ignores # -################ -*.iml -*.ipr -*.iws -.idea/ -out/ -local.properties - -# Project related # -################ -result/ -build/ - -result -.direnv/ -.devenv/ - -.devcontainer.json -.pre-commit-config.yaml diff --git a/templates/isolated/.gitlab-ci.yml b/templates/isolated/.gitlab-ci.yml deleted file mode 100644 index 2d3fabf..0000000 --- a/templates/isolated/.gitlab-ci.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: nixos/nix:latest -variables: - NIX_CONF_DIR: "/etc/nix" -before_script: - - echo 'experimental-features = nix-command flakes' > $NIX_CONF_DIR/nix.conf -check: - script: - - nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' diff --git a/templates/isolated/CHANGELOG.md b/templates/isolated/CHANGELOG.md deleted file mode 100644 index 825c32f..0000000 --- a/templates/isolated/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog diff --git a/templates/isolated/README.md b/templates/isolated/README.md deleted file mode 100644 index 23a85fe..0000000 --- a/templates/isolated/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# practicalFlakes - -## Description - -This flake has been generated from the -[tsandrini/practical-flakes-template](https://github.com/tsandrini/practical-flakes-template/) -project. The next steps for your development are - -1. **development environment** - - either use [direnv](https://github.com/direnv/direnv) and `direnv allow` - - or explicitly enter the shell via - `nix develop .#dev --override-input devenv-root "file+file://"<(printf %s "$PWD")` -1. **rename the project** - - while not many, there are some places in the code that have a `practicalFlakes` - identifier, you can use the `rename-project` (available in the dev environment) - script to change these - - `rename-project . myCoolNewProject` diff --git a/templates/isolated/flake.nix b/templates/isolated/flake.nix deleted file mode 100644 index 3926eb0..0000000 --- a/templates/isolated/flake.nix +++ /dev/null @@ -1,106 +0,0 @@ -{ - description = "practicalFlakes - TODO Add a description of your new project"; - - inputs = { - # --- BASE DEPENDENCIES --- - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - systems.url = "github:nix-systems/default"; - - # --- DEV DEPENDENCIES --- - treefmt-nix.url = "github:numtide/treefmt-nix"; - devenv.url = "github:cachix/devenv"; - mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - # --- (NOTE, YOUR) EXTRA DEPENDENCIES --- - }; - - # NOTE Here you can add additional binary cache substituers that you trust. - # There are also some sensible default caches commented out that you - # might consider using. - nixConfig = { - extra-trusted-public-keys = [ - # "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" - # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - extra-substituters = [ - # "https://devenv.cachix.org" - # "https://cache.nixos.org" - # "https://nix-community.cachix.org/" - ]; - }; - - outputs = - inputs@{ flake-parts, ... }: - let - inherit (inputs) nixpkgs; - inherit (lib.practicalFlakes) mapModules flatten; - - # You should ideally use relative paths in each individual part from ./parts, - # however, if needed you can use the `projectPath` variable that is passed - # to every flakeModule to properly anchor your absolute paths. - projectPath = ./.; - - # We extend the base library with our own custom helpers as well - # as override any of the nixpkgs default functions that we'd like - # to override. This instance is then passed to every part in ./parts so that - # you can use it in your custom modules - lib = nixpkgs.lib.extend ( - self: _super: { - practicalFlakes = import ./nix/lib { - inherit inputs projectPath; - pkgs = nixpkgs; - lib = self; - }; - } - ); - specialArgs = { - inherit lib projectPath; - }; - in - flake-parts.lib.mkFlake { inherit inputs specialArgs; } { - # We recursively traverse all of the flakeModules in ./parts and import only - # the final modules, meaning that you can have an arbitrary nested structure - # that suffices your needs. For example - # - # - ./nix/parts - # - modules/ - # - nixos/ - # - myNixosModule1.nix - # - myNixosModule2.nix - # - default.nix - # - home-manager/ - # - myHomeModule1.nix - # - myHomeModule2.nix - # - default.nix - # - sharedModules.nix - # - pkgs/ - # - myPackage1.nix - # - myPackage2.nix - # - default.nix - # - mySimpleModule.nix - imports = flatten (mapModules ./nix/parts (x: x)); - - # NOTE We use the default `systems` defined by the `nix-systems` flake, if - # you need any additional systems, simply add them in the following manner - # - # `systems = (import inputs.systems) ++ [ "armv7l-linux" ];` - systems = import inputs.systems; - flake.lib = lib.practicalFlakes; - - # NOTE Since the official flakes output schema is unfortunately very - # limited you can enable the debug mode if you need to inspect certain - # outputs of your flake. Simply - # 1. uncomment the following line - # 2. hop into a repl from the project root - `nix repl` - # 3. load the flake - `:lf .` - # After that you can inspect the flake from the root attribute `debug.flake` - # - # debug = true; - }; -} diff --git a/templates/isolated/nix/.gitignore b/templates/isolated/nix/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/lib/.gitignore b/templates/isolated/nix/lib/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/lib/_bootstrap-lib.nix b/templates/isolated/nix/lib/_bootstrap-lib.nix deleted file mode 100644 index 62de8f3..0000000 --- a/templates/isolated/nix/lib/_bootstrap-lib.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- nix/lib/_bootstrap-lib.nix -{ lib, ... }: -with lib; -with builtins; -rec { - # This file should provide the bare minimum to bootstrap the lib, namely the - # mapModules' function to enable properly loading the library files and its - # functions - - mapFilterAttrs' = - pred: f: attrs: - filterAttrs pred (mapAttrs' f attrs); - - mapModules' = - dir: fn: - mapFilterAttrs' (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules' path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/isolated/nix/lib/asserts.nix b/templates/isolated/nix/lib/asserts.nix deleted file mode 100644 index 648e500..0000000 --- a/templates/isolated/nix/lib/asserts.nix +++ /dev/null @@ -1,13 +0,0 @@ -# --- nix/lib/asserts.nix -_: { - # Example assertion - # ----------------- - # assertModulesLoaded = - # cfg: { - # assertion = hasAttr "practicalFlakes" cfg; - # message = '' - # Simple example assertion that checkc if the practicalFlakes namespace - # is present - # ''; - # }; -} diff --git a/templates/isolated/nix/lib/attrsets.nix b/templates/isolated/nix/lib/attrsets.nix deleted file mode 100644 index 54f295a..0000000 --- a/templates/isolated/nix/lib/attrsets.nix +++ /dev/null @@ -1,65 +0,0 @@ -# --- nix/lib/attrsets.nix -{ lib, ... }: -with lib; -with builtins; -{ - /* - Apply a map to every attribute of an attrset and then filter the resulting - attrset based on a given predicate function. - - *Type*: `mapFilterAttrs :: (AttrSet b -> Bool) -> (AttrSet a -> AttrSet b) -> AttrSet a -> AttrSet b` - */ - mapFilterAttrs = - # (AttrSet b -> Bool) Predicate used for filtering - pred: - # (AttrSet a -> AttrSet b) Function used for transforming the given AttrSets - f: - # (AttrSet a) Initial attrset - attrs: - filterAttrs pred (mapAttrs' f attrs); - - /* - Recursively merges a list of attrsets. - - *Type*: `mergeAttrs :: [AttrSet] -> AttrSet` - - Example: - ```nix title="Example" linenums="1" - mergeAttrs [ - { keyA = 1; keyB = 3; } - { keyB = 10; keyC = "hey"; nestedKey = { A = null; }; } - { nestedKey = { A = 3; B = 4; }; } - ] - => { keyA = 1; keyB = 10; keyC = "hey"; nestedKey = { A = 3; B = 4; };} - ``` - */ - mergeAttrs = - # ([AttrSet]) The list of attrsets - attrs: foldl' (acc: elem: acc // elem) { } attrs; - - /* - Recursively flattens a nested attrset into a list of just its values. - - *Type*: `flatten :: AttrSet a -> [a]` - - Example: - ```nix title="Example" linenums="1" - flatten { - keyA = 10; - keyB = "str20"; - keyC = { - keyD = false; - keyE = { - a = 10; - b = "20"; - c = false; - }; - }; - } - => [ 10 "str20" false 10 "20" false ] - ``` - */ - flatten = - # (AttrSet a) Initial nested attrset - attrs: collect (x: !isAttrs x) attrs; -} diff --git a/templates/isolated/nix/lib/default.nix b/templates/isolated/nix/lib/default.nix deleted file mode 100644 index 5b0899c..0000000 --- a/templates/isolated/nix/lib/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -# --- nix/lib/default.nix -{ - pkgs, - lib, - inputs, - projectPath ? ./.., - ... -}: -let - inherit (bootstrap) mapModules'; - - bootstrap = import ./_bootstrap-lib.nix { inherit lib; }; - - practicalFlakes = lib.makeExtensible ( - self: - with self; - mapModules' ./. ( - file: - import file { - inherit - pkgs - lib - self - inputs - projectPath - ; - } - ) - ); -in -practicalFlakes.extend (_self: super: lib.foldr (a: b: a // b) { } (lib.attrValues super)) diff --git a/templates/isolated/nix/lib/licenses.nix b/templates/isolated/nix/lib/licenses.nix deleted file mode 100644 index e30582c..0000000 --- a/templates/isolated/nix/lib/licenses.nix +++ /dev/null @@ -1,2 +0,0 @@ -# --- nix/lib/licenses.nix -_: { } diff --git a/templates/isolated/nix/lib/lists.nix b/templates/isolated/nix/lib/lists.nix deleted file mode 100644 index b717144..0000000 --- a/templates/isolated/nix/lib/lists.nix +++ /dev/null @@ -1,18 +0,0 @@ -# --- nix/lib/lists.nix -_: { - # Example function - # ----------------- - /* - # Map function with flipped arguments. - - # *Type*: `flipMap :: (a -> b) -> [a] -> [b]` - - # Example: - # ```nix title="Example" linenums="1" - # flipmap (x: x * x) [ 1 2 3 ] - # => [ 1 4 9 ] - # ``` - # - */ - # flipMap = flip map; -} diff --git a/templates/isolated/nix/lib/maintainers.nix b/templates/isolated/nix/lib/maintainers.nix deleted file mode 100644 index 8814a8f..0000000 --- a/templates/isolated/nix/lib/maintainers.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- nix/lib/maintainers.nix -_: { - # Example maintainer - # ----------------- - # exampleMaintainer = { - # email = "exampleMaintainer@myMail.com"; - # name = "Example Maintainer"; - # github = "exampleMaintainer"; - # githubId = 12345678; - # }; -} diff --git a/templates/isolated/nix/lib/modules.nix b/templates/isolated/nix/lib/modules.nix deleted file mode 100644 index af5566e..0000000 --- a/templates/isolated/nix/lib/modules.nix +++ /dev/null @@ -1,53 +0,0 @@ -# --- nix/lib/modules.nix -{ lib, self, ... }: -let - inherit (self.attrsets) mapFilterAttrs; -in -with lib; -with builtins; -rec { - /* - Recursively read a directory and apply a provided function to every `.nix` - file. Returns an attrset that reflects the filenames and directory - structure of the root. - - Notes: - - 1. Files and directories starting with the `_` or `.git` prefix will be completely - ignored. - - 2. If a directory with a `myDir/default.nix` file will be encountered, - the function will be applied to the `myDir/default.nix` file - instead of recursively loading `myDir` and applying it to every file. - - *Type*: `mapModules :: Path -> (Path -> AttrSet a) -> { name :: String; value :: AttrSet a; }` - - Example: - ```nix title="Example" linenums="1" - mapModules ./modules import - => { hardware = { moduleA = { ... }; }; system = { moduleB = { ... }; }; } - - mapModules ./hosts (host: mkHostCustomFunction myArg host) - => { hostA = { ... }; hostB = { ... }; } - ``` - */ - mapModules = - # (Path) Root directory on which should the recursive mapping be applied - dir: - # (Path -> AttrSet a) Function that transforms node paths to their custom attrsets - fn: - mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/isolated/nix/lib/options.nix b/templates/isolated/nix/lib/options.nix deleted file mode 100644 index 8d40976..0000000 --- a/templates/isolated/nix/lib/options.nix +++ /dev/null @@ -1,16 +0,0 @@ -# --- nix/lib/options.nix -_: { - # Example function - # ----------------- - # /* - # Creates an enableOption (ie `mkEnableOption`), however, already - # preenabled. - # - # *Type*: `String -> Option` - # */ - # mkAlreadyEnabledOption = description: - # (mkEnableOption description) - # // { - # default = true; - # }; -} diff --git a/templates/isolated/nix/lib/strings.nix b/templates/isolated/nix/lib/strings.nix deleted file mode 100644 index 08567df..0000000 --- a/templates/isolated/nix/lib/strings.nix +++ /dev/null @@ -1,20 +0,0 @@ -# --- nix/lib/strings.nix -_: { - # Example function - # ----------------- - # /* - # Given an absolute path to a file, return the dirname of that file. - - # *Type*: `dirnameFromPath :: Path -> Path` - - # Example: - # ```nix title="Example" linenums="1" - # dirnameFromPath "/etc/myDir/file.nix" - # => "/etc/myDir" - # ``` - # */ - # dirnameFromPath = - # # (Path) Absolute path to a given file - # dir: - # trivial.pipe dir [toString (strings.splitString "/") lists.last]; -} diff --git a/templates/isolated/nix/lib/types.nix b/templates/isolated/nix/lib/types.nix deleted file mode 100644 index d097fcc..0000000 --- a/templates/isolated/nix/lib/types.nix +++ /dev/null @@ -1,8 +0,0 @@ -# --- nix/lib/types.nix -_: { - # Example email type - # ------------------ - # email = - # addCheck str - # (str: match "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}" str != null); -} diff --git a/templates/isolated/nix/parts/.gitignore b/templates/isolated/nix/parts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/parts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/parts/hosts/.gitignore b/templates/isolated/nix/parts/hosts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/parts/hosts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/parts/hosts/default.nix b/templates/isolated/nix/parts/hosts/default.nix deleted file mode 100644 index bc6bda0..0000000 --- a/templates/isolated/nix/parts/hosts/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -# --- nix/parts/hosts/default.nix -# { -# lib, -# inputs, -# projectPath, -# withSystem, -# ... -# }: let -# mkHost = args: hostName: { -# extraSpecialArgs ? {}, -# extraModules ? [], -# extraOverlays ? [], -# }: -# lib.nixosSystem { -# inherit (args) system; -# specialArgs = -# { -# inherit (args) system self' inputs'; -# inherit inputs lib hostName projectPath; -# } -# // extraSpecialArgs; -# modules = -# [ -# { -# nixpkgs.overlays = extraOverlays; -# nixpkgs.config.allowUnfree = true; -# networking.hostName = hostName; -# } -# ./${hostName} -# ] -# ++ extraModules; -# }; -# in { -# flake.nixosConfigurations = { -# # exampleHost = withSystem "x86_64-linux" (args: mkHost args "exampleHost" {}); -# }; -# } -{ } diff --git a/templates/isolated/nix/parts/modules/.gitignore b/templates/isolated/nix/parts/modules/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/parts/modules/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/parts/modules/default.nix b/templates/isolated/nix/parts/modules/default.nix deleted file mode 100644 index 77cc9f1..0000000 --- a/templates/isolated/nix/parts/modules/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- nix/parts/modules/default.nix -{ inputs, self, ... }: -let - inherit (inputs.flake-parts.lib) importApply; - localFlake = self; -in -{ - flake.nixosModules = { - example-module = importApply ./example-module.nix { inherit localFlake; }; - }; -} diff --git a/templates/isolated/nix/parts/modules/example-module.nix b/templates/isolated/nix/parts/modules/example-module.nix deleted file mode 100644 index 0593369..0000000 --- a/templates/isolated/nix/parts/modules/example-module.nix +++ /dev/null @@ -1,39 +0,0 @@ -# --- nix/parts/modules/example-module.nix -{ localFlake }: -{ - config, - lib, - pkgs, - ... -}: -with builtins; -with lib; -let - inherit (localFlake.lib) mkOverrideAtModuleLevel; - - cfg = config.practicalFlakes.example-module; - _ = mkOverrideAtModuleLevel; -in -{ - options.practicalFlakes.example-module = with types; { - enable = mkEnableOption (mdDoc '' - Enable the NixOS example module that enables neovim and installs git - ''); - }; - - config = mkIf cfg.enable (mkMerge [ - # |----------------------------------------------------------------------| # - { - environment.systemPackages = with pkgs; [ git ]; - - # By using mkOverrideAtModuleLevel we can set a sensible override - # priority that is higher than the /modules priority, however, - # it can still be easily changed by the end user in their host/home - # configurations. - programs.neovim.enable = _ true; - } - # |----------------------------------------------------------------------| # - ]); - - meta.maintainers = with localFlake.lib.maintainers; [ ]; -} diff --git a/templates/isolated/nix/parts/pkgs/.gitignore b/templates/isolated/nix/parts/pkgs/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/parts/pkgs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/parts/pkgs/default.nix b/templates/isolated/nix/parts/pkgs/default.nix deleted file mode 100644 index ba83e89..0000000 --- a/templates/isolated/nix/parts/pkgs/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- nix/parts/pkgs/default.nix -{ lib, ... }: -{ - perSystem = - { pkgs, system, ... }: - { - packages = { - example-package = pkgs.callPackage ./example-package.nix { inherit lib system; }; - }; - }; -} diff --git a/templates/isolated/nix/parts/pkgs/example-package.nix b/templates/isolated/nix/parts/pkgs/example-package.nix deleted file mode 100644 index c78c1af..0000000 --- a/templates/isolated/nix/parts/pkgs/example-package.nix +++ /dev/null @@ -1,24 +0,0 @@ -# --- nix/parts/pkgs/example-package.nix -{ - lib, - system, - stdenv, - ... -}: -stdenv.mkDerivation rec { - name = "example-pkg"; - version = "v0.1.0"; - - src = ./.; - installPhase = '' - mkdir -p $out - echo "Hello, this is an example package" > $out/example.txt - ''; - - meta = with lib; { - description = "Example package"; - license = licenses.mit; - platforms = [ system ]; - maintainers = [ ]; - }; -} diff --git a/templates/isolated/nix/parts/shells/.gitignore b/templates/isolated/nix/parts/shells/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/parts/shells/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/parts/shells/default.nix b/templates/isolated/nix/parts/shells/default.nix deleted file mode 100644 index 3227ca3..0000000 --- a/templates/isolated/nix/parts/shells/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -# --- nix/parts/shells/default.nix -{ inputs, projectPath, ... }: -{ - imports = with inputs; [ devenv.flakeModule ]; - perSystem = - { config, pkgs, ... }: - { - devenv.shells.dev = import ./dev.nix { - inherit pkgs projectPath; - inherit (inputs) devenv-root; - treefmt = config.treefmt.build.wrapper; - }; - }; -} diff --git a/templates/isolated/nix/parts/shells/dev.nix b/templates/isolated/nix/parts/shells/dev.nix deleted file mode 100644 index 6b8d87d..0000000 --- a/templates/isolated/nix/parts/shells/dev.nix +++ /dev/null @@ -1,136 +0,0 @@ -# --- nix/parts/shells/dev.nix -{ - pkgs, - treefmt, - devenv-root, - ... -}: -{ - # DEVENV: Fast, Declarative, Reproducible, and Composable Developer - # Environments using Nix developed by Cachix. For more information refer to - # - # - https://devenv.sh/ - # - https://github.com/cachix/devenv - - # -------------------------- - # --- ENV & SHELL & PKGS --- - # -------------------------- - packages = with pkgs; [ - # -- NIX UTILS -- - nix-output-monitor # Processes output of Nix commands to show helpful and pretty information - nixfmt-rfc-style # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt # An opinionated formatter for Nix - # alejandra # The Uncompromising Nix Code Formatter - nh # Yet another nix cli helper - - # -- GIT RELATED UTILS -- - # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs - # cz-cli # The commitizen command line utility - # fh # The official FlakeHub CLI - # gh # GitHub CLI tool - - # -- BASE LANG UTILS -- - markdownlint-cli # Command line interface for MarkdownLint - typos # Source code spell checker - treefmt # one CLI to format the code tree - - # -- (YOUR) EXTRA PKGS -- - ]; - - # env = { - # MYUSER = "user"; - # # ... - # }; - - # NOTE If you'd like to automatically load a .env file you can use these - # following expressions - # - # dotenv.enable = true; - # dotenv.filename = ".env.development"; - - enterShell = '' - # Welcome splash text - echo ""; echo -e "\e[1;37;42mWelcome to the practicalFlakes devshell!\e[0m"; echo "" - ''; - - # --------------- - # --- SCRIPTS --- - # --------------- - scripts = { - "rename-project".exec = '' - find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/practicalFlakes/$2/g" - ''; - }; - - # ----------------- - # --- LANGUAGES --- - # ----------------- - languages.nix.enable = true; - - # NOTE You can enable additional language support in the following manner - # languages.python.enable = true; - # languages.python.version = "3.11.3"; - - # languages.rust.enable = true; - # languages.rust.channel = "stable"; - - # ---------------------------- - # --- PROCESSES & SERVICES --- - # ---------------------------- - - # ------------------ - # --- CONTAINERS --- - # ------------------ - devcontainer.enable = true; - - # ---------------------- - # --- BINARY CACHING --- - # ---------------------- - # NOTE Here you can configure automatic cachix binary cache pulling & pushing - # to/from a cache named "mycache" - # - # cachix.pull = [ "pre-commit-hooks" ]; - # cachix.push = "mycache"; - - # ------------------------ - # --- PRE-COMMIT HOOKS --- - # ------------------------ - # NOTE All available hooks options are listed at - # https://devenv.sh/reference/options/#pre-commithooks - pre-commit = { - hooks = { - treefmt.enable = true; - # We pass our custom treefmt build from parts/treefmt/treefmt.nix for - # devenv to use. - treefmt.package = treefmt; - - nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. - editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig - markdownlint.enable = true; # Markdown lint tool - # typos.enable = true; # Source code spell checker - - # actionlint.enable = true; # GitHub workflows linting - # commitizen.enable = true; # Commitizen is release management tool designed for teams. - }; - }; - - # -------------- - # --- FLAKES --- - # -------------- - devenv.flakesIntegration = true; - - # This is currently needed for devenv to properly run in pure hermetic - # mode while still being able to run processes & services and modify - # (some parts) of the active shell. - devenv.root = - let - devenvRootFileContent = builtins.readFile devenv-root.outPath; - in - pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; - - # --------------------- - # --- MISCELLANEOUS --- - # --------------------- - difftastic.enable = true; -} diff --git a/templates/isolated/nix/parts/treefmt/.gitignore b/templates/isolated/nix/parts/treefmt/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/isolated/nix/parts/treefmt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/isolated/nix/parts/treefmt/default.nix b/templates/isolated/nix/parts/treefmt/default.nix deleted file mode 100644 index 6b67334..0000000 --- a/templates/isolated/nix/parts/treefmt/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- nix/parts/treefmt/default.nix -{ projectPath, inputs, ... }: -{ - imports = with inputs; [ treefmt-nix.flakeModule ]; - - perSystem = - { pkgs, ... }: - { - treefmt = import ./treefmt.nix { inherit pkgs projectPath; }; - }; -} diff --git a/templates/isolated/nix/parts/treefmt/treefmt.nix b/templates/isolated/nix/parts/treefmt/treefmt.nix deleted file mode 100644 index dfd3bde..0000000 --- a/templates/isolated/nix/parts/treefmt/treefmt.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- nix/parts/treefmt/treefmt.nix -{ pkgs, projectPath, ... }: -{ - # treefmt is a formatting tool that saves you time: it provides - # developers with a universal way to trigger all formatters needed for the - # project in one place. - # For more information refer to - # - # - https://numtide.github.io/treefmt/ - # - https://github.com/numtide/treefmt-nix - - package = pkgs.treefmt; - flakeCheck = true; - flakeFormatter = true; - projectRootFile = projectPath + "/flake.nix"; - - programs = { - deadnix.enable = true; # Find and remove unused code in .nix source files - statix.enable = true; # Lints and suggestions for the nix programming language - nixfmt-rfc-style.enable = true; # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt.enable = true; # An opinionated formatter for Nix - # alejandra.enable = true; # The Uncompromising Nix Code Formatter - - prettier.enable = true; # Prettier is an opinionated code formatter - mdformat.enable = true; # CommonMark compliant Markdown formatter - yamlfmt.enable = true; # An extensible command line tool or library to format yaml files. - jsonfmt.enable = true; # Formatter for JSON files - }; -} diff --git a/templates/main/.envrc b/templates/main/.envrc deleted file mode 100644 index 6611954..0000000 --- a/templates/main/.envrc +++ /dev/null @@ -1,12 +0,0 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -watch_file flake.nix -watch_file flake.lock -watch_file parts/shells/dev.nix - -if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD") -then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 -fi diff --git a/templates/main/.github/pull_request_template.md b/templates/main/.github/pull_request_template.md deleted file mode 100644 index c3811fd..0000000 --- a/templates/main/.github/pull_request_template.md +++ /dev/null @@ -1,42 +0,0 @@ -# TODO: Place a short descriptive PR name here - -## Overview - - - -## Testing - - - -## Dependencies (flake inputs) - - - -## Checklist - - - -- \[ \] I have tested the relevant changes locally. -- \[ \] I have checked that - `nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD")` - passes. -- \[ \] I have ensured my commits follow the project's commits guidelines. -- \[ \] I have checked that the changes follow a linear history. -- \[ \] (If applicable) I have commented any relevant parts of my code. -- \[ \] (If applicable) I have added appropriate unit/feature tests. -- \[ \] (If applicable) I have updated the documentation accordingly (in English). - -## Additional Notes - - diff --git a/templates/main/.github/workflows/check-on-merge.yml b/templates/main/.github/workflows/check-on-merge.yml deleted file mode 100644 index abfe3a8..0000000 --- a/templates/main/.github/workflows/check-on-merge.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: "flake check" -on: - pull_request: - types: [opened, reopened, synchronize] -jobs: - check: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - - name: Check Nix flake Nixpkgs inputs - uses: DeterminateSystems/flake-checker-action@main diff --git a/templates/main/.github/workflows/flakehub.yml b/templates/main/.github/workflows/flakehub.yml deleted file mode 100644 index 615f9fb..0000000 --- a/templates/main/.github/workflows/flakehub.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "FlakeHub" -on: - push: - branches: - - "main" -jobs: - flakehub-publish: - if: false # NOTE: Comment out this line to enable flakehub - runs-on: "ubuntu-latest" - permissions: - id-token: "write" - contents: "read" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - uses: DeterminateSystems/flakehub-push@main - with: - name: "organization/repository" # TODO: add info - rolling: true - visibility: "public" diff --git a/templates/main/.github/workflows/update-flake-lock.yml b/templates/main/.github/workflows/update-flake-lock.yml deleted file mode 100644 index 701d59b..0000000 --- a/templates/main/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: update-flake-lock -on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 - -jobs: - lockfile: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - pr-title: "Automated action - Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR - dependencies - automated diff --git a/templates/main/.gitignore b/templates/main/.gitignore deleted file mode 100644 index 2d8df24..0000000 --- a/templates/main/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# OS generated files # -###################### -.DS_Store -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db - -# IDEA Ignores # -################ -*.iml -*.ipr -*.iws -.idea/ -out/ -local.properties - -# Project related # -################ -result/ -build/ - -result -.direnv/ -.devenv/ - -.devcontainer.json -.pre-commit-config.yaml diff --git a/templates/main/.gitlab-ci.yml b/templates/main/.gitlab-ci.yml deleted file mode 100644 index 2d3fabf..0000000 --- a/templates/main/.gitlab-ci.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: nixos/nix:latest -variables: - NIX_CONF_DIR: "/etc/nix" -before_script: - - echo 'experimental-features = nix-command flakes' > $NIX_CONF_DIR/nix.conf -check: - script: - - nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' diff --git a/templates/main/CHANGELOG.md b/templates/main/CHANGELOG.md deleted file mode 100644 index 825c32f..0000000 --- a/templates/main/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog diff --git a/templates/main/README.md b/templates/main/README.md deleted file mode 100644 index 23a85fe..0000000 --- a/templates/main/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# practicalFlakes - -## Description - -This flake has been generated from the -[tsandrini/practical-flakes-template](https://github.com/tsandrini/practical-flakes-template/) -project. The next steps for your development are - -1. **development environment** - - either use [direnv](https://github.com/direnv/direnv) and `direnv allow` - - or explicitly enter the shell via - `nix develop .#dev --override-input devenv-root "file+file://"<(printf %s "$PWD")` -1. **rename the project** - - while not many, there are some places in the code that have a `practicalFlakes` - identifier, you can use the `rename-project` (available in the dev environment) - script to change these - - `rename-project . myCoolNewProject` diff --git a/templates/main/flake.nix b/templates/main/flake.nix deleted file mode 100644 index 2897069..0000000 --- a/templates/main/flake.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - description = "practicalFlakes - TODO Add a description of your new project"; - - inputs = { - # --- BASE DEPENDENCIES --- - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - systems.url = "github:nix-systems/default"; - - # --- DEV DEPENDENCIES --- - devenv.url = "github:cachix/devenv"; - devenv-root = { - url = "file+file:///dev/null"; - flake = false; - }; - mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - treefmt-nix.url = "github:numtide/treefmt-nix"; - - # --- (NOTE, YOUR) EXTRA DEPENDENCIES --- - }; - - # NOTE Here you can add additional binary cache substituers that you trust. - # There are also some sensible default caches commented out that you - # might consider using. - nixConfig = { - extra-trusted-public-keys = [ - # "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" - # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - extra-substituters = [ - # "https://devenv.cachix.org" - # "https://cache.nixos.org" - # "https://nix-community.cachix.org/" - ]; - }; - - outputs = - inputs@{ flake-parts, ... }: - let - inherit (inputs) nixpkgs; - inherit (lib.practicalFlakes) mapModules flatten; - - # You should ideally use relative paths in each individual part from ./parts, - # however, if needed you can use the `projectPath` variable that is passed - # to every flakeModule to properly anchor your absolute paths. - projectPath = ./.; - - # We extend the base library with our own custom helpers as well - # as override any of the nixpkgs default functions that we'd like - # to override. This instance is then passed to every part in ./parts so that - # you can use it in your custom modules - lib = nixpkgs.lib.extend ( - self: _super: { - practicalFlakes = import ./lib { - inherit inputs projectPath; - pkgs = nixpkgs; - lib = self; - }; - } - ); - specialArgs = { - inherit lib projectPath; - }; - in - flake-parts.lib.mkFlake { inherit inputs specialArgs; } { - # We recursively traverse all of the flakeModules in ./parts and import only - # the final modules, meaning that you can have an arbitrary nested structure - # that suffices your needs. For example - # - # - ./parts - # - modules/ - # - nixos/ - # - myNixosModule1.nix - # - myNixosModule2.nix - # - default.nix - # - home-manager/ - # - myHomeModule1.nix - # - myHomeModule2.nix - # - default.nix - # - sharedModules.nix - # - pkgs/ - # - myPackage1.nix - # - myPackage2.nix - # - default.nix - # - mySimpleModule.nix - imports = flatten (mapModules ./parts (x: x)); - - # NOTE We use the default `systems` defined by the `nix-systems` flake, if - # you need any additional systems, simply add them in the following manner - # - # `systems = (import inputs.systems) ++ [ "armv7l-linux" ];` - systems = import inputs.systems; - flake.lib = lib.practicalFlakes; - - # NOTE Since the official flakes output schema is unfortunately very - # limited you can enable the debug mode if you need to inspect certain - # outputs of your flake. Simply - # 1. uncomment the following line - # 2. hop into a repl from the project root - `nix repl` - # 3. load the flake - `:lf .` - # After that you can inspect the flake from the root attribute `debug.flake` - # - # debug = true; - }; -} diff --git a/templates/main/lib/.gitignore b/templates/main/lib/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/lib/_bootstrap-lib.nix b/templates/main/lib/_bootstrap-lib.nix deleted file mode 100644 index cefa2cd..0000000 --- a/templates/main/lib/_bootstrap-lib.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- lib/_bootstrap-lib.nix -{ lib, ... }: -with lib; -with builtins; -rec { - # This file should provide the bare minimum to bootstrap the lib, namely the - # mapModules' function to enable properly loading the library files and its - # functions - - mapFilterAttrs' = - pred: f: attrs: - filterAttrs pred (mapAttrs' f attrs); - - mapModules' = - dir: fn: - mapFilterAttrs' (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules' path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/main/lib/asserts.nix b/templates/main/lib/asserts.nix deleted file mode 100644 index c845309..0000000 --- a/templates/main/lib/asserts.nix +++ /dev/null @@ -1,13 +0,0 @@ -# --- lib/asserts.nix -_: { - # Example assertion - # ----------------- - # assertModulesLoaded = - # cfg: { - # assertion = hasAttr "practicalFlakes" cfg; - # message = '' - # Simple example assertion that checkc if the practicalFlakes namespace - # is present - # ''; - # }; -} diff --git a/templates/main/lib/attrsets.nix b/templates/main/lib/attrsets.nix deleted file mode 100644 index ed0d7f2..0000000 --- a/templates/main/lib/attrsets.nix +++ /dev/null @@ -1,65 +0,0 @@ -# --- lib/attrsets.nix -{ lib, ... }: -with lib; -with builtins; -{ - /* - Apply a map to every attribute of an attrset and then filter the resulting - attrset based on a given predicate function. - - *Type*: `mapFilterAttrs :: (AttrSet b -> Bool) -> (AttrSet a -> AttrSet b) -> AttrSet a -> AttrSet b` - */ - mapFilterAttrs = - # (AttrSet b -> Bool) Predicate used for filtering - pred: - # (AttrSet a -> AttrSet b) Function used for transforming the given AttrSets - f: - # (AttrSet a) Initial attrset - attrs: - filterAttrs pred (mapAttrs' f attrs); - - /* - Recursively merges a list of attrsets. - - *Type*: `mergeAttrs :: [AttrSet] -> AttrSet` - - Example: - ```nix title="Example" linenums="1" - mergeAttrs [ - { keyA = 1; keyB = 3; } - { keyB = 10; keyC = "hey"; nestedKey = { A = null; }; } - { nestedKey = { A = 3; B = 4; }; } - ] - => { keyA = 1; keyB = 10; keyC = "hey"; nestedKey = { A = 3; B = 4; };} - ``` - */ - mergeAttrs = - # ([AttrSet]) The list of attrsets - attrs: foldl' (acc: elem: acc // elem) { } attrs; - - /* - Recursively flattens a nested attrset into a list of just its values. - - *Type*: `flatten :: AttrSet a -> [a]` - - Example: - ```nix title="Example" linenums="1" - flatten { - keyA = 10; - keyB = "str20"; - keyC = { - keyD = false; - keyE = { - a = 10; - b = "20"; - c = false; - }; - }; - } - => [ 10 "str20" false 10 "20" false ] - ``` - */ - flatten = - # (AttrSet a) Initial nested attrset - attrs: collect (x: !isAttrs x) attrs; -} diff --git a/templates/main/lib/default.nix b/templates/main/lib/default.nix deleted file mode 100644 index 8fe4f76..0000000 --- a/templates/main/lib/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -# --- lib/default.nix -{ - pkgs, - lib, - inputs, - projectPath ? ./.., - ... -}: -let - inherit (bootstrap) mapModules'; - - bootstrap = import ./_bootstrap-lib.nix { inherit lib; }; - - practicalFlakes = lib.makeExtensible ( - self: - with self; - mapModules' ./. ( - file: - import file { - inherit - pkgs - lib - self - inputs - projectPath - ; - } - ) - ); -in -practicalFlakes.extend (_self: super: lib.foldr (a: b: a // b) { } (lib.attrValues super)) diff --git a/templates/main/lib/licenses.nix b/templates/main/lib/licenses.nix deleted file mode 100644 index 3c02c4f..0000000 --- a/templates/main/lib/licenses.nix +++ /dev/null @@ -1,2 +0,0 @@ -# --- lib/licenses.nix -_: { } diff --git a/templates/main/lib/lists.nix b/templates/main/lib/lists.nix deleted file mode 100644 index 172e821..0000000 --- a/templates/main/lib/lists.nix +++ /dev/null @@ -1,21 +0,0 @@ -# --- lib/lists.nix -{ lib, ... }: -with lib; -with builtins; -rec { - # Example function - # ----------------- - /* - # Map function with flipped arguments. - - # *Type*: `flipMap :: (a -> b) -> [a] -> [b]` - - # Example: - # ```nix title="Example" linenums="1" - # flipmap (x: x * x) [ 1 2 3 ] - # => [ 1 4 9 ] - # ``` - # - */ - # flipMap = flip map; -} diff --git a/templates/main/lib/maintainers.nix b/templates/main/lib/maintainers.nix deleted file mode 100644 index 8cf4e05..0000000 --- a/templates/main/lib/maintainers.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- lib/maintainers.nix -_: { - # Example maintainer - # ----------------- - # exampleMaintainer = { - # email = "exampleMaintainer@myMail.com"; - # name = "Example Maintainer"; - # github = "exampleMaintainer"; - # githubId = 12345678; - # }; -} diff --git a/templates/main/lib/modules.nix b/templates/main/lib/modules.nix deleted file mode 100644 index e44c444..0000000 --- a/templates/main/lib/modules.nix +++ /dev/null @@ -1,53 +0,0 @@ -# --- lib/modules.nix -{ lib, self, ... }: -let - inherit (self.attrsets) mapFilterAttrs; -in -with lib; -with builtins; -rec { - /* - Recursively read a directory and apply a provided function to every `.nix` - file. Returns an attrset that reflects the filenames and directory - structure of the root. - - Notes: - - 1. Files and directories starting with the `_` or `.git` prefix will be completely - ignored. - - 2. If a directory with a `myDir/default.nix` file will be encountered, - the function will be applied to the `myDir/default.nix` file - instead of recursively loading `myDir` and applying it to every file. - - *Type*: `mapModules :: Path -> (Path -> AttrSet a) -> { name :: String; value :: AttrSet a; }` - - Example: - ```nix title="Example" linenums="1" - mapModules ./modules import - => { hardware = { moduleA = { ... }; }; system = { moduleB = { ... }; }; } - - mapModules ./hosts (host: mkHostCustomFunction myArg host) - => { hostA = { ... }; hostB = { ... }; } - ``` - */ - mapModules = - # (Path) Root directory on which should the recursive mapping be applied - dir: - # (Path -> AttrSet a) Function that transforms node paths to their custom attrsets - fn: - mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/main/lib/options.nix b/templates/main/lib/options.nix deleted file mode 100644 index e4c67ee..0000000 --- a/templates/main/lib/options.nix +++ /dev/null @@ -1,16 +0,0 @@ -# --- lib/options.nix -_: { - # Example function - # ----------------- - # /* - # Creates an enableOption (ie `mkEnableOption`), however, already - # preenabled. - # - # *Type*: `String -> Option` - # */ - # mkAlreadyEnabledOption = description: - # (mkEnableOption description) - # // { - # default = true; - # }; -} diff --git a/templates/main/lib/strings.nix b/templates/main/lib/strings.nix deleted file mode 100644 index 35b51b0..0000000 --- a/templates/main/lib/strings.nix +++ /dev/null @@ -1,20 +0,0 @@ -# --- lib/strings.nix -_: { - # Example function - # ----------------- - # /* - # Given an absolute path to a file, return the dirname of that file. - - # *Type*: `dirnameFromPath :: Path -> Path` - - # Example: - # ```nix title="Example" linenums="1" - # dirnameFromPath "/etc/myDir/file.nix" - # => "/etc/myDir" - # ``` - # */ - # dirnameFromPath = - # # (Path) Absolute path to a given file - # dir: - # trivial.pipe dir [toString (strings.splitString "/") lists.last]; -} diff --git a/templates/main/lib/types.nix b/templates/main/lib/types.nix deleted file mode 100644 index e7b9c94..0000000 --- a/templates/main/lib/types.nix +++ /dev/null @@ -1,8 +0,0 @@ -# --- lib/types.nix -_: { - # Example email type - # ------------------ - # email = - # addCheck str - # (str: match "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}" str != null); -} diff --git a/templates/main/parts/.gitignore b/templates/main/parts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/parts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/parts/hosts/.gitignore b/templates/main/parts/hosts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/parts/hosts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/parts/hosts/default.nix b/templates/main/parts/hosts/default.nix deleted file mode 100644 index 8c72870..0000000 --- a/templates/main/parts/hosts/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -# --- parts/hosts/default.nix -# { -# lib, -# inputs, -# projectPath, -# withSystem, -# ... -# }: let -# mkHost = args: hostName: { -# extraSpecialArgs ? {}, -# extraModules ? [], -# extraOverlays ? [], -# }: -# lib.nixosSystem { -# inherit (args) system; -# specialArgs = -# { -# inherit (args) system self' inputs'; -# inherit inputs lib hostName projectPath; -# } -# // extraSpecialArgs; -# modules = -# [ -# { -# nixpkgs.overlays = extraOverlays; -# nixpkgs.config.allowUnfree = true; -# networking.hostName = hostName; -# } -# ./${hostName} -# ] -# ++ extraModules; -# }; -# in { -# flake.nixosConfigurations = { -# # exampleHost = withSystem "x86_64-linux" (args: mkHost args "exampleHost" {}); -# }; -# } -{ } diff --git a/templates/main/parts/modules/.gitignore b/templates/main/parts/modules/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/parts/modules/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/parts/modules/default.nix b/templates/main/parts/modules/default.nix deleted file mode 100644 index b91bdf3..0000000 --- a/templates/main/parts/modules/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/modules/default.nix -{ inputs, self, ... }: -let - inherit (inputs.flake-parts.lib) importApply; - localFlake = self; -in -{ - flake.nixosModules = { - example-module = importApply ./example-module.nix { inherit localFlake; }; - }; -} diff --git a/templates/main/parts/modules/example-module.nix b/templates/main/parts/modules/example-module.nix deleted file mode 100644 index 3bd9e62..0000000 --- a/templates/main/parts/modules/example-module.nix +++ /dev/null @@ -1,39 +0,0 @@ -# --- parts/modules/example-module.nix -{ localFlake }: -{ - config, - lib, - pkgs, - ... -}: -with builtins; -with lib; -let - inherit (localFlake.lib) mkOverrideAtModuleLevel; - - cfg = config.practicalFlakes.example-module; - _ = mkOverrideAtModuleLevel; -in -{ - options.practicalFlakes.example-module = with types; { - enable = mkEnableOption (mdDoc '' - Enable the NixOS example module that enables neovim and installs git - ''); - }; - - config = mkIf cfg.enable (mkMerge [ - # |----------------------------------------------------------------------| # - { - environment.systemPackages = with pkgs; [ git ]; - - # By using mkOverrideAtModuleLevel we can set a sensible override - # priority that is higher than the /modules priority, however, - # it can still be easily changed by the end user in their host/home - # configurations. - programs.neovim.enable = _ true; - } - # |----------------------------------------------------------------------| # - ]); - - meta.maintainers = with localFlake.lib.maintainers; [ ]; -} diff --git a/templates/main/parts/pkgs/.gitignore b/templates/main/parts/pkgs/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/parts/pkgs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/parts/pkgs/default.nix b/templates/main/parts/pkgs/default.nix deleted file mode 100644 index 9291148..0000000 --- a/templates/main/parts/pkgs/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/pkgs/default.nix -{ lib, ... }: -{ - perSystem = - { pkgs, system, ... }: - { - packages = { - example-package = pkgs.callPackage ./example-package.nix { inherit lib system; }; - }; - }; -} diff --git a/templates/main/parts/pkgs/example-package.nix b/templates/main/parts/pkgs/example-package.nix deleted file mode 100644 index e5f8f24..0000000 --- a/templates/main/parts/pkgs/example-package.nix +++ /dev/null @@ -1,24 +0,0 @@ -# --- parts/pkgs/example-package.nix -{ - lib, - system, - stdenv, - ... -}: -stdenv.mkDerivation rec { - name = "example-pkg"; - version = "v0.1.0"; - - src = ./.; - installPhase = '' - mkdir -p $out - echo "Hello, this is an example package" > $out/example.txt - ''; - - meta = with lib; { - description = "Example package"; - license = licenses.mit; - platforms = [ system ]; - maintainers = [ ]; - }; -} diff --git a/templates/main/parts/shells/.gitignore b/templates/main/parts/shells/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/parts/shells/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/parts/shells/default.nix b/templates/main/parts/shells/default.nix deleted file mode 100644 index 3667714..0000000 --- a/templates/main/parts/shells/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -# --- parts/shells/default.nix -{ inputs, projectPath, ... }: -{ - imports = with inputs; [ devenv.flakeModule ]; - perSystem = - { config, pkgs, ... }: - { - devenv.shells.dev = import ./dev.nix { - inherit pkgs projectPath; - inherit (inputs) devenv-root; - treefmt = config.treefmt.build.wrapper; - }; - }; -} diff --git a/templates/main/parts/shells/dev.nix b/templates/main/parts/shells/dev.nix deleted file mode 100644 index 9c6b1d0..0000000 --- a/templates/main/parts/shells/dev.nix +++ /dev/null @@ -1,136 +0,0 @@ -# --- parts/shells/dev.nix -{ - pkgs, - treefmt, - devenv-root, - ... -}: -{ - # DEVENV: Fast, Declarative, Reproducible, and Composable Developer - # Environments using Nix developed by Cachix. For more information refer to - # - # - https://devenv.sh/ - # - https://github.com/cachix/devenv - - # -------------------------- - # --- ENV & SHELL & PKGS --- - # -------------------------- - packages = with pkgs; [ - # -- NIX UTILS -- - nix-output-monitor # Processes output of Nix commands to show helpful and pretty information - nixfmt-rfc-style # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt # An opinionated formatter for Nix - # alejandra # The Uncompromising Nix Code Formatter - nh # Yet another nix cli helper - - # -- GIT RELATED UTILS -- - # commitizen # Tool to create committing rules for projects, auto bump versions, and generate changelogs - # cz-cli # The commitizen command line utility - # fh # The official FlakeHub CLI - # gh # GitHub CLI tool - - # -- BASE LANG UTILS -- - markdownlint-cli # Command line interface for MarkdownLint - typos # Source code spell checker - treefmt # one CLI to format the code tree - - # -- (YOUR) EXTRA PKGS -- - ]; - - # env = { - # MYUSER = "user"; - # # ... - # }; - - # NOTE If you'd like to automatically load a .env file you can use these - # following expressions - # - # dotenv.enable = true; - # dotenv.filename = ".env.development"; - - enterShell = '' - # Welcome splash text - echo ""; echo -e "\e[1;37;42mWelcome to the practicalFlakes devshell!\e[0m"; echo "" - ''; - - # --------------- - # --- SCRIPTS --- - # --------------- - scripts = { - "rename-project".exec = '' - find $1 \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s/practicalFlakes/$2/g" - ''; - }; - - # ----------------- - # --- LANGUAGES --- - # ----------------- - languages.nix.enable = true; - - # NOTE You can enable additional language support in the following manner - # languages.python.enable = true; - # languages.python.version = "3.11.3"; - - # languages.rust.enable = true; - # languages.rust.channel = "stable"; - - # ---------------------------- - # --- PROCESSES & SERVICES --- - # ---------------------------- - - # ------------------ - # --- CONTAINERS --- - # ------------------ - devcontainer.enable = true; - - # ---------------------- - # --- BINARY CACHING --- - # ---------------------- - # NOTE Here you can configure automatic cachix binary cache pulling & pushing - # to/from a cache named "mycache" - # - # cachix.pull = [ "pre-commit-hooks" ]; - # cachix.push = "mycache"; - - # ------------------------ - # --- PRE-COMMIT HOOKS --- - # ------------------------ - # NOTE All available hooks options are listed at - # https://devenv.sh/reference/options/#pre-commithooks - pre-commit = { - hooks = { - treefmt.enable = true; - # We pass our custom treefmt build from parts/treefmt/treefmt.nix for - # devenv to use. - treefmt.package = treefmt; - - nil.enable = true; # Nix Language server, an incremental analysis assistant for writing in Nix. - editorconfig-checker.enable = true; # A tool to verify that your files are in harmony with your .editorconfig - markdownlint.enable = true; # Markdown lint tool - # typos.enable = true; # Source code spell checker - - # actionlint.enable = true; # GitHub workflows linting - # commitizen.enable = true; # Commitizen is release management tool designed for teams. - }; - }; - - # -------------- - # --- FLAKES --- - # -------------- - devenv.flakesIntegration = true; - - # This is currently needed for devenv to properly run in pure hermetic - # mode while still being able to run processes & services and modify - # (some parts) of the active shell. - devenv.root = - let - devenvRootFileContent = builtins.readFile devenv-root.outPath; - in - pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent; - - # --------------------- - # --- MISCELLANEOUS --- - # --------------------- - difftastic.enable = true; -} diff --git a/templates/main/parts/treefmt/.gitignore b/templates/main/parts/treefmt/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/main/parts/treefmt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/main/parts/treefmt/default.nix b/templates/main/parts/treefmt/default.nix deleted file mode 100644 index 7f3112e..0000000 --- a/templates/main/parts/treefmt/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/treefmt/default.nix -{ projectPath, inputs, ... }: -{ - imports = with inputs; [ treefmt-nix.flakeModule ]; - - perSystem = - { pkgs, ... }: - { - treefmt = import ./treefmt.nix { inherit pkgs projectPath; }; - }; -} diff --git a/templates/main/parts/treefmt/treefmt.nix b/templates/main/parts/treefmt/treefmt.nix deleted file mode 100644 index 13025fb..0000000 --- a/templates/main/parts/treefmt/treefmt.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- parts/treefmt/treefmt.nix -{ pkgs, projectPath, ... }: -{ - # treefmt is a formatting tool that saves you time: it provides - # developers with a universal way to trigger all formatters needed for the - # project in one place. - # For more information refer to - # - # - https://numtide.github.io/treefmt/ - # - https://github.com/numtide/treefmt-nix - - package = pkgs.treefmt; - flakeCheck = true; - flakeFormatter = true; - projectRootFile = projectPath + "/flake.nix"; - - programs = { - deadnix.enable = true; # Find and remove unused code in .nix source files - statix.enable = true; # Lints and suggestions for the nix programming language - nixfmt-rfc-style.enable = true; # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt.enable = true; # An opinionated formatter for Nix - # alejandra.enable = true; # The Uncompromising Nix Code Formatter - - prettier.enable = true; # Prettier is an opinionated code formatter - mdformat.enable = true; # CommonMark compliant Markdown formatter - yamlfmt.enable = true; # An extensible command line tool or library to format yaml files. - jsonfmt.enable = true; # Formatter for JSON files - }; -} diff --git a/templates/minimal/.envrc b/templates/minimal/.envrc deleted file mode 100644 index 6611954..0000000 --- a/templates/minimal/.envrc +++ /dev/null @@ -1,12 +0,0 @@ -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -watch_file flake.nix -watch_file flake.lock -watch_file parts/shells/dev.nix - -if ! use flake .#dev --accept-flake-config --override-input devenv-root "file+file://"<(printf %s "$PWD") -then - echo "devenv could not be built. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 -fi diff --git a/templates/minimal/.github/pull_request_template.md b/templates/minimal/.github/pull_request_template.md deleted file mode 100644 index c3811fd..0000000 --- a/templates/minimal/.github/pull_request_template.md +++ /dev/null @@ -1,42 +0,0 @@ -# TODO: Place a short descriptive PR name here - -## Overview - - - -## Testing - - - -## Dependencies (flake inputs) - - - -## Checklist - - - -- \[ \] I have tested the relevant changes locally. -- \[ \] I have checked that - `nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD")` - passes. -- \[ \] I have ensured my commits follow the project's commits guidelines. -- \[ \] I have checked that the changes follow a linear history. -- \[ \] (If applicable) I have commented any relevant parts of my code. -- \[ \] (If applicable) I have added appropriate unit/feature tests. -- \[ \] (If applicable) I have updated the documentation accordingly (in English). - -## Additional Notes - - diff --git a/templates/minimal/.github/workflows/check-on-merge.yml b/templates/minimal/.github/workflows/check-on-merge.yml deleted file mode 100644 index abfe3a8..0000000 --- a/templates/minimal/.github/workflows/check-on-merge.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: "flake check" -on: - pull_request: - types: [opened, reopened, synchronize] -jobs: - check: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - - name: Check Nix flake Nixpkgs inputs - uses: DeterminateSystems/flake-checker-action@main diff --git a/templates/minimal/.github/workflows/flakehub.yml b/templates/minimal/.github/workflows/flakehub.yml deleted file mode 100644 index 615f9fb..0000000 --- a/templates/minimal/.github/workflows/flakehub.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: "FlakeHub" -on: - push: - branches: - - "main" -jobs: - flakehub-publish: - if: false # NOTE: Comment out this line to enable flakehub - runs-on: "ubuntu-latest" - permissions: - id-token: "write" - contents: "read" - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - uses: DeterminateSystems/flakehub-push@main - with: - name: "organization/repository" # TODO: add info - rolling: true - visibility: "public" diff --git a/templates/minimal/.github/workflows/update-flake-lock.yml b/templates/minimal/.github/workflows/update-flake-lock.yml deleted file mode 100644 index 701d59b..0000000 --- a/templates/minimal/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: update-flake-lock -on: - workflow_dispatch: # allows manual triggering - schedule: - - cron: "0 0 * * 0" # runs weekly on Sunday at 00:00 - -jobs: - lockfile: - # if: false # NOTE: Uncomment this line to disable the workflow - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - pr-title: "Automated action - Update flake.lock" # Title of PR to be created - pr-labels: | # Labels to be set on the PR - dependencies - automated diff --git a/templates/minimal/.gitignore b/templates/minimal/.gitignore deleted file mode 100644 index 2d8df24..0000000 --- a/templates/minimal/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -# OS generated files # -###################### -.DS_Store -.DS_Store? -ehthumbs.db -Icon? -Thumbs.db - -# IDEA Ignores # -################ -*.iml -*.ipr -*.iws -.idea/ -out/ -local.properties - -# Project related # -################ -result/ -build/ - -result -.direnv/ -.devenv/ - -.devcontainer.json -.pre-commit-config.yaml diff --git a/templates/minimal/.gitlab-ci.yml b/templates/minimal/.gitlab-ci.yml deleted file mode 100644 index 2d3fabf..0000000 --- a/templates/minimal/.gitlab-ci.yml +++ /dev/null @@ -1,10 +0,0 @@ -image: nixos/nix:latest -variables: - NIX_CONF_DIR: "/etc/nix" -before_script: - - echo 'experimental-features = nix-command flakes' > $NIX_CONF_DIR/nix.conf -check: - script: - - nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") --show-trace --accept-flake-config - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' diff --git a/templates/minimal/CHANGELOG.md b/templates/minimal/CHANGELOG.md deleted file mode 100644 index 825c32f..0000000 --- a/templates/minimal/CHANGELOG.md +++ /dev/null @@ -1 +0,0 @@ -# Changelog diff --git a/templates/minimal/README.md b/templates/minimal/README.md deleted file mode 100644 index 23a85fe..0000000 --- a/templates/minimal/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# practicalFlakes - -## Description - -This flake has been generated from the -[tsandrini/practical-flakes-template](https://github.com/tsandrini/practical-flakes-template/) -project. The next steps for your development are - -1. **development environment** - - either use [direnv](https://github.com/direnv/direnv) and `direnv allow` - - or explicitly enter the shell via - `nix develop .#dev --override-input devenv-root "file+file://"<(printf %s "$PWD")` -1. **rename the project** - - while not many, there are some places in the code that have a `practicalFlakes` - identifier, you can use the `rename-project` (available in the dev environment) - script to change these - - `rename-project . myCoolNewProject` diff --git a/templates/minimal/flake.lock b/templates/minimal/flake.lock deleted file mode 100644 index d230a0f..0000000 --- a/templates/minimal/flake.lock +++ /dev/null @@ -1,395 +0,0 @@ -{ - "nodes": { - "devenv": { - "inputs": { - "flake-compat": "flake-compat", - "nix": "nix", - "nixpkgs": "nixpkgs", - "pre-commit-hooks": "pre-commit-hooks" - }, - "locked": { - "lastModified": 1706018268, - "narHash": "sha256-d24+re0t8b6HYGzAPZCIJed85n23RUFXQa2yuHoW0uQ=", - "owner": "cachix", - "repo": "devenv", - "rev": "ad0ae333b210e31237e1fc4a7ddab71a01785add", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "devenv", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-parts": { - "inputs": { - "nixpkgs-lib": "nixpkgs-lib" - }, - "locked": { - "lastModified": 1706569497, - "narHash": "sha256-oixb0IDb5eZYw6BaVr/R/1pSoMh4rfJHkVnlgeRIeZs=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "60c614008eed1d0383d21daac177a3e036192ed8", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { - "inputs": { - "systems": "systems_2" - }, - "locked": { - "lastModified": 1694529238, - "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "devenv", - "pre-commit-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1660459072, - "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "lowdown-src": { - "flake": false, - "locked": { - "lastModified": 1633514407, - "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", - "owner": "kristapsdz", - "repo": "lowdown", - "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", - "type": "github" - }, - "original": { - "owner": "kristapsdz", - "repo": "lowdown", - "type": "github" - } - }, - "mk-shell-bin": { - "locked": { - "lastModified": 1677004959, - "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", - "owner": "rrbutani", - "repo": "nix-mk-shell-bin", - "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", - "type": "github" - }, - "original": { - "owner": "rrbutani", - "repo": "nix-mk-shell-bin", - "type": "github" - } - }, - "nix": { - "inputs": { - "lowdown-src": "lowdown-src", - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "nixpkgs-regression": "nixpkgs-regression" - }, - "locked": { - "lastModified": 1676545802, - "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", - "owner": "domenkozar", - "repo": "nix", - "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", - "type": "github" - }, - "original": { - "owner": "domenkozar", - "ref": "relaxed-flakes", - "repo": "nix", - "type": "github" - } - }, - "nix2container": { - "inputs": { - "flake-utils": "flake-utils_2", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1703410130, - "narHash": "sha256-qbJQ8DtdKzFK0fZck7kX64QWkS/3tKefxGjyI+SAQa4=", - "owner": "nlewo", - "repo": "nix2container", - "rev": "6aa8491e73843ac8bf714a3904a45900f356ea44", - "type": "github" - }, - "original": { - "owner": "nlewo", - "repo": "nix2container", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1678875422, - "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-lib": { - "locked": { - "dir": "lib", - "lastModified": 1703961334, - "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", - "type": "github" - }, - "original": { - "dir": "lib", - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs-regression": { - "locked": { - "lastModified": 1643052045, - "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", - "type": "github" - } - }, - "nixpkgs-stable": { - "locked": { - "lastModified": 1685801374, - "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-23.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_2": { - "locked": { - "lastModified": 1706550542, - "narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "97b17f32362e475016f942bbdfda4a4a72a8a652", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { - "locked": { - "lastModified": 1705856552, - "narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "pre-commit-hooks": { - "inputs": { - "flake-compat": [ - "devenv", - "flake-compat" - ], - "flake-utils": "flake-utils", - "gitignore": "gitignore", - "nixpkgs": [ - "devenv", - "nixpkgs" - ], - "nixpkgs-stable": "nixpkgs-stable" - }, - "locked": { - "lastModified": 1704725188, - "narHash": "sha256-qq8NbkhRZF1vVYQFt1s8Mbgo8knj+83+QlL5LBnYGpI=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "ea96f0c05924341c551a797aaba8126334c505d2", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, - "root": { - "inputs": { - "devenv": "devenv", - "flake-parts": "flake-parts", - "mk-shell-bin": "mk-shell-bin", - "nix2container": "nix2container", - "nixpkgs": "nixpkgs_2", - "systems": "systems_3", - "treefmt-nix": "treefmt-nix" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_2": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "systems_3": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - }, - "treefmt-nix": { - "inputs": { - "nixpkgs": "nixpkgs_3" - }, - "locked": { - "lastModified": 1706462057, - "narHash": "sha256-7dG1D4iqqt0bEbBqUWk6lZiSqqwwAO0Hd1L5opVyhNM=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "c6153c2a3ff4c38d231e3ae99af29b87f1df5901", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/templates/minimal/flake.nix b/templates/minimal/flake.nix deleted file mode 100644 index 2897069..0000000 --- a/templates/minimal/flake.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - description = "practicalFlakes - TODO Add a description of your new project"; - - inputs = { - # --- BASE DEPENDENCIES --- - nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - flake-parts.url = "github:hercules-ci/flake-parts"; - systems.url = "github:nix-systems/default"; - - # --- DEV DEPENDENCIES --- - devenv.url = "github:cachix/devenv"; - devenv-root = { - url = "file+file:///dev/null"; - flake = false; - }; - mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin"; - nix2container = { - url = "github:nlewo/nix2container"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - treefmt-nix.url = "github:numtide/treefmt-nix"; - - # --- (NOTE, YOUR) EXTRA DEPENDENCIES --- - }; - - # NOTE Here you can add additional binary cache substituers that you trust. - # There are also some sensible default caches commented out that you - # might consider using. - nixConfig = { - extra-trusted-public-keys = [ - # "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" - # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" - ]; - extra-substituters = [ - # "https://devenv.cachix.org" - # "https://cache.nixos.org" - # "https://nix-community.cachix.org/" - ]; - }; - - outputs = - inputs@{ flake-parts, ... }: - let - inherit (inputs) nixpkgs; - inherit (lib.practicalFlakes) mapModules flatten; - - # You should ideally use relative paths in each individual part from ./parts, - # however, if needed you can use the `projectPath` variable that is passed - # to every flakeModule to properly anchor your absolute paths. - projectPath = ./.; - - # We extend the base library with our own custom helpers as well - # as override any of the nixpkgs default functions that we'd like - # to override. This instance is then passed to every part in ./parts so that - # you can use it in your custom modules - lib = nixpkgs.lib.extend ( - self: _super: { - practicalFlakes = import ./lib { - inherit inputs projectPath; - pkgs = nixpkgs; - lib = self; - }; - } - ); - specialArgs = { - inherit lib projectPath; - }; - in - flake-parts.lib.mkFlake { inherit inputs specialArgs; } { - # We recursively traverse all of the flakeModules in ./parts and import only - # the final modules, meaning that you can have an arbitrary nested structure - # that suffices your needs. For example - # - # - ./parts - # - modules/ - # - nixos/ - # - myNixosModule1.nix - # - myNixosModule2.nix - # - default.nix - # - home-manager/ - # - myHomeModule1.nix - # - myHomeModule2.nix - # - default.nix - # - sharedModules.nix - # - pkgs/ - # - myPackage1.nix - # - myPackage2.nix - # - default.nix - # - mySimpleModule.nix - imports = flatten (mapModules ./parts (x: x)); - - # NOTE We use the default `systems` defined by the `nix-systems` flake, if - # you need any additional systems, simply add them in the following manner - # - # `systems = (import inputs.systems) ++ [ "armv7l-linux" ];` - systems = import inputs.systems; - flake.lib = lib.practicalFlakes; - - # NOTE Since the official flakes output schema is unfortunately very - # limited you can enable the debug mode if you need to inspect certain - # outputs of your flake. Simply - # 1. uncomment the following line - # 2. hop into a repl from the project root - `nix repl` - # 3. load the flake - `:lf .` - # After that you can inspect the flake from the root attribute `debug.flake` - # - # debug = true; - }; -} diff --git a/templates/minimal/lib/.gitignore b/templates/minimal/lib/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/minimal/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/minimal/lib/_bootstrap-lib.nix b/templates/minimal/lib/_bootstrap-lib.nix deleted file mode 100644 index cefa2cd..0000000 --- a/templates/minimal/lib/_bootstrap-lib.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- lib/_bootstrap-lib.nix -{ lib, ... }: -with lib; -with builtins; -rec { - # This file should provide the bare minimum to bootstrap the lib, namely the - # mapModules' function to enable properly loading the library files and its - # functions - - mapFilterAttrs' = - pred: f: attrs: - filterAttrs pred (mapAttrs' f attrs); - - mapModules' = - dir: fn: - mapFilterAttrs' (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules' path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/minimal/lib/attrsets.nix b/templates/minimal/lib/attrsets.nix deleted file mode 100644 index ed0d7f2..0000000 --- a/templates/minimal/lib/attrsets.nix +++ /dev/null @@ -1,65 +0,0 @@ -# --- lib/attrsets.nix -{ lib, ... }: -with lib; -with builtins; -{ - /* - Apply a map to every attribute of an attrset and then filter the resulting - attrset based on a given predicate function. - - *Type*: `mapFilterAttrs :: (AttrSet b -> Bool) -> (AttrSet a -> AttrSet b) -> AttrSet a -> AttrSet b` - */ - mapFilterAttrs = - # (AttrSet b -> Bool) Predicate used for filtering - pred: - # (AttrSet a -> AttrSet b) Function used for transforming the given AttrSets - f: - # (AttrSet a) Initial attrset - attrs: - filterAttrs pred (mapAttrs' f attrs); - - /* - Recursively merges a list of attrsets. - - *Type*: `mergeAttrs :: [AttrSet] -> AttrSet` - - Example: - ```nix title="Example" linenums="1" - mergeAttrs [ - { keyA = 1; keyB = 3; } - { keyB = 10; keyC = "hey"; nestedKey = { A = null; }; } - { nestedKey = { A = 3; B = 4; }; } - ] - => { keyA = 1; keyB = 10; keyC = "hey"; nestedKey = { A = 3; B = 4; };} - ``` - */ - mergeAttrs = - # ([AttrSet]) The list of attrsets - attrs: foldl' (acc: elem: acc // elem) { } attrs; - - /* - Recursively flattens a nested attrset into a list of just its values. - - *Type*: `flatten :: AttrSet a -> [a]` - - Example: - ```nix title="Example" linenums="1" - flatten { - keyA = 10; - keyB = "str20"; - keyC = { - keyD = false; - keyE = { - a = 10; - b = "20"; - c = false; - }; - }; - } - => [ 10 "str20" false 10 "20" false ] - ``` - */ - flatten = - # (AttrSet a) Initial nested attrset - attrs: collect (x: !isAttrs x) attrs; -} diff --git a/templates/minimal/lib/default.nix b/templates/minimal/lib/default.nix deleted file mode 100644 index 8fe4f76..0000000 --- a/templates/minimal/lib/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -# --- lib/default.nix -{ - pkgs, - lib, - inputs, - projectPath ? ./.., - ... -}: -let - inherit (bootstrap) mapModules'; - - bootstrap = import ./_bootstrap-lib.nix { inherit lib; }; - - practicalFlakes = lib.makeExtensible ( - self: - with self; - mapModules' ./. ( - file: - import file { - inherit - pkgs - lib - self - inputs - projectPath - ; - } - ) - ); -in -practicalFlakes.extend (_self: super: lib.foldr (a: b: a // b) { } (lib.attrValues super)) diff --git a/templates/minimal/lib/modules.nix b/templates/minimal/lib/modules.nix deleted file mode 100644 index e44c444..0000000 --- a/templates/minimal/lib/modules.nix +++ /dev/null @@ -1,53 +0,0 @@ -# --- lib/modules.nix -{ lib, self, ... }: -let - inherit (self.attrsets) mapFilterAttrs; -in -with lib; -with builtins; -rec { - /* - Recursively read a directory and apply a provided function to every `.nix` - file. Returns an attrset that reflects the filenames and directory - structure of the root. - - Notes: - - 1. Files and directories starting with the `_` or `.git` prefix will be completely - ignored. - - 2. If a directory with a `myDir/default.nix` file will be encountered, - the function will be applied to the `myDir/default.nix` file - instead of recursively loading `myDir` and applying it to every file. - - *Type*: `mapModules :: Path -> (Path -> AttrSet a) -> { name :: String; value :: AttrSet a; }` - - Example: - ```nix title="Example" linenums="1" - mapModules ./modules import - => { hardware = { moduleA = { ... }; }; system = { moduleB = { ... }; }; } - - mapModules ./hosts (host: mkHostCustomFunction myArg host) - => { hostA = { ... }; hostB = { ... }; } - ``` - */ - mapModules = - # (Path) Root directory on which should the recursive mapping be applied - dir: - # (Path -> AttrSet a) Function that transforms node paths to their custom attrsets - fn: - mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n) && !(hasPrefix ".git" n)) ( - n: v: - let - path = "${toString dir}/${n}"; - in - if v == "directory" && pathExists "${path}/default.nix" then - nameValuePair n (fn path) - else if v == "directory" then - nameValuePair n (mapModules path fn) - else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n then - nameValuePair (removeSuffix ".nix" n) (fn path) - else - nameValuePair "" null - ) (readDir dir); -} diff --git a/templates/minimal/parts/.gitignore b/templates/minimal/parts/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/minimal/parts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/minimal/parts/shells/.gitignore b/templates/minimal/parts/shells/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/minimal/parts/shells/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/minimal/parts/shells/default.nix b/templates/minimal/parts/shells/default.nix deleted file mode 100644 index 3667714..0000000 --- a/templates/minimal/parts/shells/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -# --- parts/shells/default.nix -{ inputs, projectPath, ... }: -{ - imports = with inputs; [ devenv.flakeModule ]; - perSystem = - { config, pkgs, ... }: - { - devenv.shells.dev = import ./dev.nix { - inherit pkgs projectPath; - inherit (inputs) devenv-root; - treefmt = config.treefmt.build.wrapper; - }; - }; -} diff --git a/templates/minimal/parts/treefmt/.gitignore b/templates/minimal/parts/treefmt/.gitignore deleted file mode 100644 index f935021..0000000 --- a/templates/minimal/parts/treefmt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!.gitignore diff --git a/templates/minimal/parts/treefmt/default.nix b/templates/minimal/parts/treefmt/default.nix deleted file mode 100644 index 7f3112e..0000000 --- a/templates/minimal/parts/treefmt/default.nix +++ /dev/null @@ -1,11 +0,0 @@ -# --- parts/treefmt/default.nix -{ projectPath, inputs, ... }: -{ - imports = with inputs; [ treefmt-nix.flakeModule ]; - - perSystem = - { pkgs, ... }: - { - treefmt = import ./treefmt.nix { inherit pkgs projectPath; }; - }; -} diff --git a/templates/minimal/parts/treefmt/treefmt.nix b/templates/minimal/parts/treefmt/treefmt.nix deleted file mode 100644 index 749fb30..0000000 --- a/templates/minimal/parts/treefmt/treefmt.nix +++ /dev/null @@ -1,30 +0,0 @@ -# --- parts/treefmt/treefmt.nix -{ pkgs, projectPath, ... }: -{ - # treefmt is a formatting tool that saves you time: it provides - # developers with a universal way to trigger all formatters needed for the - # project in one place. - # For more information refer to - # - # - https://numtide.github.io/treefmt/ - # - https://github.com/numtide/treefmt-nix - # - package = pkgs.treefmt; - flakeCheck = true; - flakeFormatter = true; - projectRootFile = projectPath + "/flake.nix"; - - programs = { - deadnix.enable = true; # Find and remove unused code in .nix source files - statix.enable = true; # Lints and suggestions for the nix programming language - nixfmt-rfc-style.enable = true; # An opinionated formatter for Nix - # NOTE Choose a different formatter if you'd like to - # nixfmt.enable = true; # An opinionated formatter for Nix - # alejandra.enable = true; # The Uncompromising Nix Code Formatter - - prettier.enable = true; # Prettier is an opinionated code formatter - mdformat.enable = true; # CommonMark compliant Markdown formatter - yamlfmt.enable = true; # An extensible command line tool or library to format yaml files. - jsonfmt.enable = true; # Formatter for JSON files - }; -}