├── .editorconfig ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── renovate.json └── workflows │ ├── check-nix-format.yml │ ├── pr.yml │ └── update.yml ├── .gitignore ├── LICENSE ├── README.md ├── bin └── nur ├── bors.toml ├── ci ├── flake.lock ├── flake.nix ├── lib │ └── setup-git.sh ├── nur.nix ├── nur │ ├── __init__.py │ ├── combine.py │ ├── error.py │ ├── eval.py │ ├── fileutils.py │ ├── format_manifest.py │ ├── index.py │ ├── manifest.py │ ├── path.py │ ├── prefetch.py │ └── update.py ├── pyproject.toml ├── setup.py ├── test.sh ├── update-nur-combined.sh ├── update-nur-search.sh └── update-nur.sh ├── default.nix ├── flake.lock ├── flake.nix ├── lib ├── evalRepo.nix └── repoSource.nix ├── repos.json └── repos.json.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig configuration for nixpkgs 2 | # http://EditorConfig.org 3 | 4 | # Top-most EditorConfig file 5 | root = true 6 | 7 | # Unix-style newlines with a newline ending every file, utf-8 charset 8 | [*] 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | charset = utf-8 13 | 14 | # Match json/python files, set indent to spaces with width of two 15 | [*.{json,py}] 16 | indent_style = space 17 | indent_size = 4 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | The following points apply when adding a new repository to repos.json 2 | 3 | - [ ] I ran `./bin/nur format-manifest` after updating `repos.json` (We will use the same script in github actions to make sure we keep the format consistent) 4 | - [ ] By including this repository in NUR, I confirm that any copyrightable content in the repository (other than built derivations or patches, if applicable) is licensed under the MIT license 5 | - [ ] I confirm that `meta.license` and `meta.sourceProvenance` have been set correctly for any derivations for unfree or not built from source packages 6 | 7 | Additionally, the following points are recommended: 8 | 9 | - [ ] All applicable `meta` fields have been filled out. See https://nixos.org/manual/nixpkgs/stable/#sec-standard-meta-attributes for more information. The following fields are particularly helpful and can always be filled out: 10 | - [ ] `meta.description`, so consumers can confirm that that your package is what they're looking for 11 | - [ ] `meta.license`, even for free packages 12 | - [ ] `meta.homepage`, for tracking and deduplication 13 | - [ ] `meta.mainProgram`, so that `nix run` works correctly 14 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:best-practices", 5 | ":disableDependencyDashboard" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.github/workflows/check-nix-format.yml: -------------------------------------------------------------------------------- 1 | # This file was mostly copied from nixpkgs's check-nix-format.yml, 2 | # which itself wsa mostly copied from nixpkgs's check-maintainers-sorted.yaml. 3 | 4 | name: Check that Nix files are formatted 5 | 6 | on: 7 | pull_request: 8 | types: [opened, synchronize, reopened] 9 | push: 10 | branches: 11 | - main 12 | - 'push-action/**' 13 | merge_group: 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | nixos: 19 | name: nixfmt-check 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 23 | with: 24 | fetch-depth: 2 25 | - name: Calculate changed files 26 | id: changed-files 27 | run: echo "changed_files=$(git diff --name-only -r HEAD^1 HEAD | xargs)" >> $GITHUB_OUTPUT 28 | - uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 29 | with: 30 | extra_nix_config: sandbox = true 31 | nix_path: nixpkgs=channel:nixpkgs-unstable 32 | - name: Install nixfmt 33 | run: "nix-env -f '' -iAP nixfmt-rfc-style" 34 | - name: Check that Nix files are formatted according to the RFC style 35 | run: | 36 | # List of changed files 37 | changed_files="${{ steps.changed-files.outputs.changed_files }}" 38 | 39 | # Convert the string of changed files into an array 40 | IFS=' ' read -r -a files <<< "$changed_files" 41 | 42 | # A variable to track failures 43 | failure=0 44 | 45 | # Function to check the file and run nixfmt 46 | check_file() { 47 | local file="$1" 48 | if [[ -f "$file" ]]; then 49 | if ! nixfmt --check "$file"; then 50 | echo "::error file=$file::Formatting check failed for $file" >&2 51 | failure=1 52 | fi 53 | else 54 | echo "File does not exist: $file" >&2 55 | fi 56 | } 57 | 58 | # Export the function and failure variable for parallel execution 59 | export -f check_file 60 | export failure 61 | 62 | # Run the checks in parallel 63 | printf "%s\n" "${files[@]}" | xargs -n 1 -P "$(nproc)" -I {} bash -c 'check_file "$@"' _ {} 64 | 65 | # Exit with a status of 1 if any checks failed 66 | if [[ $failure -eq 1 ]]; then 67 | exit 1 68 | fi 69 | -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: "Test" 2 | on: 3 | pull_request: 4 | merge_group: 5 | # For bors 6 | push: 7 | branches: 8 | - staging 9 | jobs: 10 | tests: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 14 | - uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 15 | with: 16 | nix_path: nixpkgs=channel:nixos-unstable 17 | extra_nix_config: | 18 | experimental-features = nix-command flakes 19 | - run: ./ci/test.sh 20 | -------------------------------------------------------------------------------- /.github/workflows/update.yml: -------------------------------------------------------------------------------- 1 | name: "Update" 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | # chosen by fair dice rolling 6 | - cron: '40 * * * *' 7 | push: 8 | branches: 9 | - main 10 | concurrency: 11 | group: update 12 | cancel-in-progress: false 13 | jobs: 14 | update_nur: 15 | runs-on: ubuntu-latest 16 | # Don't trigger when the last push was done by a bot 17 | if: github.event_name != 'push' || !endsWith(github.actor, '[bot]') 18 | steps: 19 | - id: get_workflow_token 20 | uses: peter-murray/workflow-application-token-action@d17e3a9a36850ea89f35db16c1067dd2b68ee343 # v4.0.1 21 | with: 22 | application_id: '${{ secrets.GH_APPLICATION_ID }}' 23 | application_private_key: '${{ secrets.GH_APPLICATION_PRIVATE_KEY }}' 24 | permissions: "contents:write" 25 | revoke_token: true 26 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 27 | - uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31 28 | with: 29 | nix_path: nixpkgs=channel:nixos-unstable 30 | extra_nix_config: | 31 | experimental-features = nix-command flakes 32 | - name: update nur / nur-combined 33 | run: ./ci/update-nur.sh 34 | env: 35 | API_TOKEN_GITHUB: '${{ steps.get_workflow_token.outputs.token }}' 36 | - name: rebase # TODO: fix upstream push-protected to retry when push fails 37 | run: | 38 | source ./ci/lib/setup-git.sh 39 | git fetch origin ${{ github.event.repository.default_branch }} 40 | git pull --rebase origin ${{ github.event.repository.default_branch }} 41 | env: 42 | GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }} 43 | - uses: CasperWA/push-protected@74d25b8aa10e0c29024138735d32f3c0b75f9279 # v2 44 | with: 45 | token: ${{ steps.get_workflow_token.outputs.token }} 46 | branch: ${{ github.event.repository.default_branch }} 47 | - name: Dispatch NUR-combined update 48 | uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 49 | with: 50 | token: ${{ steps.get_workflow_token.outputs.token }} 51 | repository: nix-community/nur-combined 52 | event-type: nur_update 53 | - name: Dispatch NUR-search update 54 | uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 55 | with: 56 | token: ${{ steps.get_workflow_token.outputs.token }} 57 | repository: nix-community/nur-search 58 | event-type: nur_update 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # mypy 7 | .mypy_cache/ 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jörg Thalheim and the NUR contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # NUR 4 | 5 | Current maintainer: [Pandapip1](https://github.com/Pandapip1) 6 | Original creator: NUR was started by [@Mic92](https://github.com/Mic92) in 2018. 7 | 8 | The Nix User Repository (NUR) is a community-driven meta repository for Nix packages. 9 | It provides access to user repositories that contain package descriptions (Nix 10 | expressions) and allows you to install packages by referencing them via attributes. 11 | In contrast to [Nixpkgs](https://github.com/NixOS/nixpkgs/), packages are built 12 | from source and **are not reviewed by any Nixpkgs member**. 13 | 14 | The NUR was created to share new packages from the community in a faster and 15 | more decentralized way. 16 | 17 | NUR automatically checks its list of repositories and performs evaluation checks 18 | before it propagates the updates. 19 | 20 | ## Installation 21 | 22 | ### Using flakes 23 | 24 | Include NUR in your `flake.nix`: 25 | 26 | ```nix 27 | { 28 | inputs = { 29 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 30 | nur = { 31 | url = "github:nix-community/NUR"; 32 | inputs.nixpkgs.follows = "nixpkgs"; 33 | }; 34 | }; 35 | }; 36 | ``` 37 | 38 | Then, either the overlay (`overlays.default`) or `legacyPackages.` can be used. 39 | 40 | ### Using `packageOverrides` 41 | 42 | First include NUR in your `packageOverrides`: 43 | 44 | To make NUR accessible for your login user, add the following to `~/.config/nixpkgs/config.nix`: 45 | 46 | ```nix 47 | { 48 | packageOverrides = pkgs: { 49 | nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") { 50 | inherit pkgs; 51 | }; 52 | }; 53 | } 54 | ``` 55 | 56 | For NixOS add the following to your `/etc/nixos/configuration.nix` 57 | Notice: If you want to use NUR in nix-env, home-manager or in nix-shell you also need NUR in `~/.config/nixpkgs/config.nix` 58 | as shown above! 59 | 60 | ```nix 61 | { 62 | nixpkgs.config.packageOverrides = pkgs: { 63 | nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") { 64 | inherit pkgs; 65 | }; 66 | }; 67 | } 68 | ``` 69 | 70 | ### Pinning 71 | 72 | Using `builtins.fetchTarball` without a sha256 will only cache the download for 1 hour by default, so you need internet access almost every time you build something. You can pin the version if you don't want that: 73 | 74 | ```nix 75 | builtins.fetchTarball { 76 | # Get the revision by choosing a version from https://github.com/nix-community/NUR/commits/main 77 | url = "https://github.com/nix-community/NUR/archive/3a6a6f4da737da41e27922ce2cfacf68a109ebce.tar.gz"; 78 | # Get the hash by running `nix-prefetch-url --unpack ` on the above url 79 | sha256 = "04387gzgl8y555b3lkz9aiw9xsldfg4zmzp930m62qw8zbrvrshd"; 80 | } 81 | ``` 82 | 83 | ## How to use 84 | 85 | Then packages can be used or installed from the NUR namespace. 86 | 87 | ```console 88 | $ nix-shell -p nur.repos.mic92.hello-nur 89 | nix-shell> hello 90 | Hello, NUR! 91 | ``` 92 | 93 | or 94 | 95 | ```console 96 | $ nix-env -f '' -iA nur.repos.mic92.hello-nur 97 | ``` 98 | 99 | or 100 | 101 | ```console 102 | # configuration.nix 103 | environment.systemPackages = with pkgs; [ 104 | nur.repos.mic92.hello-nur 105 | ]; 106 | ``` 107 | 108 | Each contributor can register their repository under a name and is responsible 109 | for its content. 110 | 111 | ***NUR does not check the repository for malicious content on a regular basis 112 | and it is recommended to check expressions before installing them.*** 113 | 114 | ### Using a single package in a devshell 115 | 116 | This simple example demostrates how to add a single package from nur to a devshell defined in a flake.nix. 117 | 118 | ```nix 119 | { 120 | inputs = { 121 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 122 | flake-utils.url = "github:numtide/flake-utils"; 123 | nur = { 124 | url = "github:nix-community/NUR"; 125 | inputs.nixpkgs.follows = "nixpkgs"; 126 | }; 127 | }; 128 | 129 | outputs = { self, nixpkgs, flake-utils, nur }: 130 | flake-utils.lib.eachDefaultSystem (system: 131 | let 132 | pkgs = import nixpkgs { 133 | inherit system; 134 | overlays = [ nur.overlay ]; 135 | }; 136 | in 137 | { 138 | devShells.default = pkgs.mkShell { 139 | packages = [ pkgs.nur.repos.mic92.hello-nur ]; 140 | }; 141 | } 142 | ); 143 | } 144 | ``` 145 | 146 | ### Using the flake in NixOS 147 | 148 | Using overlays and modules from NUR in your configuration is fairly straightforward. 149 | 150 | ```nix 151 | { 152 | inputs = { 153 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 154 | flake-utils.url = "github:numtide/flake-utils"; 155 | nur = { 156 | url = "github:nix-community/NUR"; 157 | inputs.nixpkgs.follows = "nixpkgs"; 158 | }; 159 | }; 160 | 161 | outputs = { self, nixpkgs, nur }: { 162 | nixosConfigurations.myConfig = nixpkgs.lib.nixosSystem { 163 | # ... 164 | modules = [ 165 | # Adds the NUR overlay 166 | nur.modules.nixos.default 167 | # NUR modules to import 168 | nur.legacyPackages."${system}".repos.iopq.modules.xraya 169 | # This adds the NUR nixpkgs overlay. 170 | # Example: 171 | # ({ pkgs, ... }: { 172 | # environment.systemPackages = [ pkgs.nur.repos.mic92.hello-nur ]; 173 | # }) 174 | ]; 175 | }; 176 | }; 177 | } 178 | ``` 179 | 180 | ### Integrating with Home Manager 181 | 182 | Integrating with [Home Manager](https://github.com/rycee/home-manager) can be done by adding your modules to the `imports` attribute. 183 | You can then configure your services like usual. 184 | 185 | ```nix 186 | let 187 | nur-no-pkgs = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") {}; 188 | in 189 | { 190 | imports = lib.attrValues nur-no-pkgs.repos.moredhel.hmModules.rawModules; 191 | 192 | services.unison = { 193 | enable = true; 194 | profiles = { 195 | org = { 196 | src = "/home/moredhel/org"; 197 | dest = "/home/moredhel/org.backup"; 198 | extraArgs = "-batch -watch -ui text -repeat 60 -fat"; 199 | }; 200 | }; 201 | }; 202 | } 203 | ``` 204 | 205 | ## Finding packages 206 | 207 | You can find all packages using 208 | [Packages search for NUR](https://nur.nix-community.org/) 209 | or search our 210 | [nur-combined](https://github.com/nix-community/nur-combined) 211 | repository, which contains all nix expressions from all users, via 212 | [github](https://github.com/nix-community/nur-combined/search). 213 | 214 | ## How to add your own repository. 215 | 216 | First, create a repository that contains a `default.nix` in its top-level directory. 217 | We also provide a [repository template](https://github.com/nix-community/nur-packages-template) that contains 218 | a prepared directory structure. 219 | 220 | DO NOT import packages for example `with import {};`. 221 | Instead take all dependency you want to import from Nixpkgs from the given `pkgs` argument. 222 | Each repository should return a set of Nix derivations: 223 | 224 | ```nix 225 | { pkgs }: 226 | { 227 | hello-nur = pkgs.callPackage ./hello-nur {}; 228 | } 229 | ``` 230 | 231 | In this example `hello-nur` would be a directory containing a `default.nix`: 232 | 233 | ```nix 234 | { stdenv, fetchurl, lib }: 235 | 236 | stdenv.mkDerivation rec { 237 | pname = "hello"; 238 | version = "2.10"; 239 | 240 | src = fetchurl { 241 | url = "mirror://gnu/hello/${pname}-${version}.tar.gz"; 242 | sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i"; 243 | }; 244 | 245 | postPatch = '' 246 | sed -i -e 's/Hello, world!/Hello, NUR!/' src/hello.c 247 | ''; 248 | 249 | # fails due to patch 250 | doCheck = false; 251 | 252 | meta = with lib; { 253 | description = "A program that produces a familiar, friendly greeting"; 254 | longDescription = '' 255 | GNU Hello is a program that prints "Hello, world!" when you run it. 256 | It is fully customizable. 257 | ''; 258 | homepage = https://www.gnu.org/software/hello/manual/; 259 | changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}"; 260 | license = licenses.gpl3Plus; 261 | maintainers = [ maintainers.eelco ]; 262 | platforms = platforms.all; 263 | }; 264 | } 265 | ``` 266 | 267 | You can use `nix-shell` or `nix-build` to build your packages: 268 | 269 | ```console 270 | $ nix-shell --arg pkgs 'import {}' -A hello-nur 271 | nix-shell> hello 272 | nix-shell> find $buildInputs 273 | ``` 274 | 275 | ```console 276 | $ nix-build --arg pkgs 'import {}' -A hello-nur 277 | ``` 278 | 279 | For development convenience, you can also set a default value for the pkgs argument: 280 | 281 | ```nix 282 | { pkgs ? import {} }: 283 | { 284 | hello-nur = pkgs.callPackage ./hello-nur {}; 285 | } 286 | ``` 287 | 288 | ```console 289 | $ nix-build -A hello-nur 290 | ``` 291 | 292 | Add your own repository to the `repos.json` of NUR: 293 | 294 | ```console 295 | $ git clone --depth 1 https://github.com/nix-community/NUR 296 | $ cd NUR 297 | ``` 298 | 299 | edit the file `repos.json`: 300 | 301 | ```json 302 | { 303 | "repos": { 304 | "mic92": { 305 | "url": "https://github.com/Mic92/nur-packages" 306 | }, 307 | "": { 308 | "url": "https://github.com//" 309 | } 310 | } 311 | } 312 | ``` 313 | 314 | At the moment, each URL must point to a git repository. By running `bin/nur update` 315 | the corresponding `repos.json.lock` is updated and the repository is tested. This will 316 | also perform an evaluation check, which must be passed for your repository. Commit the changed 317 | `repos.json` but NOT `repos.json.lock` 318 | 319 | ``` 320 | $ ./bin/nur format-manifest # ensure repos.json is sorted alphabetically 321 | $ git add repos.json 322 | $ git commit -m "add repository" 323 | $ git push 324 | ``` 325 | 326 | and open a pull request towards [https://github.com/nix-community/NUR](https://github.com/nix-community/NUR). 327 | 328 | At the moment repositories should be buildable on Nixpkgs unstable. Later we 329 | will add options to also provide branches for other Nixpkgs channels. 330 | 331 | ### Use a different nix file as root expression 332 | 333 | To use a different file instead of `default.nix` to load packages from, set the `file` 334 | option to a path relative to the repository root: 335 | 336 | ```json 337 | { 338 | "repos": { 339 | "mic92": { 340 | "url": "https://github.com/Mic92/nur-packages", 341 | "file": "subdirectory/default.nix" 342 | } 343 | } 344 | } 345 | ``` 346 | 347 | ### Update NUR's lock file after updating your repository 348 | 349 | By default, we only check for repository updates once a day with an automatic 350 | github action to update our lock file `repos.json.lock`. 351 | To update NUR faster, you can use our service at https://nur-update.nix-community.org/ 352 | after you have pushed an update to your repository, e.g.: 353 | 354 | ```console 355 | curl -XPOST https://nur-update.nix-community.org/update?repo=mic92 356 | ``` 357 | 358 | Check out the [github page](https://github.com/nix-community/nur-update#nur-update-endpoint) for further details 359 | 360 | ### Why are my NUR packages not updating? 361 | 362 | With every build triggered via the URL hook, all repositories will be evaluated. The repository revision for the user is only updated if the evaluation does not contain any errors. Typical evaluation errors include: 363 | 364 | * Using a wrong license attribute in the metadata. 365 | * Using a builtin fetcher because it will cause access to external URLs during evaluation. Use pkgs.fetch* instead (i.e. instead of `builtins.fetchGit` use `pkgs.fetchgit`) 366 | 367 | You can find out if your evaluation succeeded by checking the [latest build job](https://github.com/nix-community/NUR/actions). 368 | 369 | #### Local evaluation check 370 | 371 | In your `nur-packages/` folder, run the [check evaluation](https://github.com/nix-community/nur-packages-template/blob/main/.github/workflows/build.yml) task 372 | 373 | ```sh 374 | nix-env -f . -qa \* --meta \ 375 | --allowed-uris https://static.rust-lang.org \ 376 | --option restrict-eval true \ 377 | --option allow-import-from-derivation true \ 378 | --drv-path --show-trace \ 379 | -I nixpkgs=$(nix-instantiate --find-file nixpkgs) \ 380 | -I ./ \ 381 | --json | jq -r 'values | .[].name' 382 | ``` 383 | 384 | On success, this shows a list of your packages 385 | 386 | ### Git submodules 387 | 388 | To fetch git submodules in repositories set `submodules`: 389 | 390 | ```json 391 | { 392 | "repos": { 393 | "mic92": { 394 | "url": "https://github.com/Mic92/nur-packages", 395 | "submodules": true 396 | } 397 | } 398 | } 399 | ``` 400 | 401 | ### NixOS modules, overlays and library function support 402 | 403 | It is also possible to define more than just packages. In fact any Nix expression can be used. 404 | 405 | To make NixOS modules, overlays and library functions more discoverable, 406 | they must be put them in their own namespace within the repository. 407 | 408 | #### Providing NixOS modules 409 | 410 | NixOS modules should be placed in the `modules` attribute: 411 | 412 | ```nix 413 | { pkgs }: { 414 | modules = import ./modules; 415 | } 416 | ``` 417 | 418 | ```nix 419 | # modules/default.nix 420 | { 421 | example-module = ./example-module.nix; 422 | } 423 | ``` 424 | 425 | An example can be found [here](https://github.com/Mic92/nur-packages/tree/master/modules). 426 | Modules should be defined as paths, not functions, to avoid conflicts if imported from multiple locations. 427 | 428 | A module with no [_class](https://nixos.org/manual/nixpkgs/stable/index.html#module-system-lib-evalModules-param-class) will be assumed to be both a NixOS and Home Manager module. If a module is NixOS or Home Manager specific, the `_class` attribute should be set to `"nixos"` or [`"home-manager"`](https://github.com/nix-community/home-manager/commit/26e72d85e6fbda36bf2266f1447215501ec376fd). 429 | 430 | #### Providing Overlays 431 | 432 | For overlays, use the `overlays` attribute: 433 | 434 | ```nix 435 | # default.nix 436 | { 437 | overlays = { 438 | hello-overlay = import ./hello-overlay; 439 | }; 440 | } 441 | ``` 442 | 443 | ```nix 444 | # hello-overlay/default.nix 445 | self: super: { 446 | hello = super.hello.overrideAttrs (old: { 447 | separateDebugInfo = true; 448 | }); 449 | } 450 | ``` 451 | 452 | #### Providing library functions 453 | 454 | Put reusable nix functions that are intend for public use in the `lib` attribute: 455 | 456 | ```nix 457 | { pkgs }: 458 | with pkgs.lib; 459 | { 460 | lib = { 461 | hexint = x: hexvals.${toLower x}; 462 | 463 | hexvals = listToAttrs (imap (i: c: { name = c; value = i - 1; }) 464 | (stringToCharacters "0123456789abcdef")); 465 | }; 466 | } 467 | ``` 468 | 469 | ## Overriding repositories 470 | 471 | You can override repositories using `repoOverrides` argument. 472 | This allows to test changes before publishing. 473 | 474 | ```nix 475 | { 476 | packageOverrides = pkgs: { 477 | nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/main.tar.gz") { 478 | inherit pkgs; 479 | repoOverrides = { 480 | mic92 = import ../nur-packages { inherit pkgs; }; 481 | ## remote locations are also possible: 482 | # mic92 = import (builtins.fetchTarball "https://github.com/your-user/nur-packages/archive/main.tar.gz") { inherit pkgs; }; 483 | }; 484 | }; 485 | }; 486 | } 487 | ``` 488 | 489 | The repo must be a valid package repo, i.e. its root contains a `default.nix` file. 490 | 491 | ### Overriding repositories with Flake 492 | 493 | **Experimental** Note that flake support is still experimental and might change in future in a backwards incompatible way. 494 | 495 | You can override repositories in two ways: 496 | 497 | - With packageOverrides 498 | ```nix 499 | { 500 | inputs.nur.url = "github:nix-community/NUR"; 501 | inputs.paul.url = "path:/some_path/nur-paul"; # example: a local nur.repos.paul for development 502 | 503 | outputs = {self, nixpkgs, nur, paul }: { 504 | 505 | system = "x86_64-linux"; 506 | 507 | nurpkgs = import nixpkgs { inherit system; }; 508 | 509 | ... 510 | modules = [ 511 | { 512 | nixpkgs.config.packageOverrides = pkgs: { 513 | nur = import nur { 514 | inherit pkgs nurpkgs; 515 | repoOverrides = { paul = import paul { inherit pkgs; }; }; 516 | }; 517 | }; 518 | } 519 | ]; 520 | ... 521 | } 522 | ``` 523 | - With overlay 524 | ```nix 525 | { 526 | modules = [ 527 | { 528 | nixpkgs.overlays = [ 529 | (final: prev: { 530 | nur = import nur { 531 | nurpkgs = prev; 532 | pkgs = prev; 533 | repoOverrides = { paul = import paul { pkgs = prev; }; }; 534 | }; 535 | }) 536 | ]; 537 | } 538 | ... 539 | ]; 540 | } 541 | ``` 542 | 543 | The repo must contain a `flake.nix` file in addition to a `default.nix`: [flake.nix example](https://github.com/Mic92/nur-packages/blob/master/flake.nix) 544 | 545 | ## Contribution guidelines 546 | 547 | - When adding packages to your repository make sure they build and set 548 | `meta.broken` attribute to true otherwise. 549 | - Supply meta attributes as described in the [Nixpkgs manual](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes), so 550 | packages can be found by users. 551 | - Keep your repositories slim - they are downloaded by users and our evaluator 552 | and needs to be hashed. 553 | - Reuse packages from Nixpkgs when applicable, so the binary cache can be 554 | leveraged 555 | 556 | Examples for packages that could be in NUR: 557 | 558 | - Packages that are only interesting for a small audience 559 | - Pre-releases 560 | - Old versions of packages that are no longer in Nixpkgs, but needed for legacy reason (i.e. old versions of GCC/LLVM) 561 | - Automatic generated package sets (i.e. generate packages sets from PyPi or CPAN) 562 | - Software with opinionated patches 563 | - Experiments 564 | 565 | ## Contact 566 | 567 | We have a matrix channel on [#nur:nixos.org](https://matrix.to/#/#nur:nixos.org). 568 | Apart from that we also read posts on [https://discourse.nixos.org](https://discourse.nixos.org/). 569 | -------------------------------------------------------------------------------- /bin/nur: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nix-shell 2 | #!nix-shell -p python3 -p nix-prefetch-git -p nix -i python3 -p python3Packages.distutils 3 | import sys 4 | import os 5 | 6 | sys.path.insert(0, os.path.join( 7 | os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "ci")) 8 | 9 | from nur import main 10 | 11 | if __name__ == "__main__": 12 | main() 13 | -------------------------------------------------------------------------------- /bors.toml: -------------------------------------------------------------------------------- 1 | cut_body_after = "" # don't include text from the PR body in the merge commit message 2 | status = [ "tests" ] 3 | -------------------------------------------------------------------------------- /ci/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1681202837, 9 | "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "cfacdce06f30d2b68473a46042957675eebb3401", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1682900373, 24 | "narHash": "sha256-+ckiCxbGFSs1/wHKCXAZnvb37Htf6k5nmQE3T0Y7hK8=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "8b3bc690e201c8d3cbd14633dbf3462a820e73f2", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixpkgs-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /ci/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Internal flake for ci tasks of NUR"; 3 | 4 | inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 5 | inputs.flake-utils.url = "github:numtide/flake-utils"; 6 | 7 | outputs = 8 | { 9 | self, 10 | nixpkgs, 11 | flake-utils, 12 | }: 13 | flake-utils.lib.eachDefaultSystem (system: { 14 | packages.nur = nixpkgs.legacyPackages.${system}.python3.pkgs.callPackage ./nur.nix { }; 15 | defaultPackage = self.packages.${system}.nur; 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /ci/lib/setup-git.sh: -------------------------------------------------------------------------------- 1 | # only source this file 2 | # ================================================== 3 | 4 | export GIT_AUTHOR_NAME="Nur a bot" 5 | export GIT_AUTHOR_EMAIL="198656834+nur-a-bot[bot]@users.noreply.github.com" 6 | export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME 7 | export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL 8 | -------------------------------------------------------------------------------- /ci/nur.nix: -------------------------------------------------------------------------------- 1 | { 2 | buildPythonApplication, 3 | lib, 4 | nix-prefetch-git, 5 | git, 6 | nix, 7 | glibcLocales, 8 | }: 9 | 10 | buildPythonApplication { 11 | name = "nur"; 12 | src = ./.; 13 | 14 | doCheck = false; 15 | 16 | makeWrapperArgs = [ 17 | "--prefix" 18 | "PATH" 19 | ":" 20 | "${lib.makeBinPath [ 21 | nix-prefetch-git 22 | git 23 | nix 24 | ]}" 25 | "--set" 26 | "LOCALE_ARCHIVE" 27 | "${glibcLocales}/lib/locale/locale-archive" 28 | ]; 29 | } 30 | -------------------------------------------------------------------------------- /ci/nur/__init__.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import logging 3 | import sys 4 | from typing import List 5 | 6 | from .combine import combine_command 7 | from .eval import eval_command 8 | from .format_manifest import format_manifest_command 9 | from .index import index_command 10 | from .path import ROOT 11 | from .update import update_command 12 | 13 | LOG_LEVELS = dict( 14 | debug=logging.DEBUG, 15 | info=logging.INFO, 16 | error=logging.ERROR, 17 | critical=logging.CRITICAL, 18 | ) 19 | 20 | 21 | def parse_arguments(argv: List[str]) -> argparse.Namespace: 22 | parser = argparse.ArgumentParser( 23 | prog=argv[0], description="nur management commands" 24 | ) 25 | parser.add_argument( 26 | "--log-level", type=str, default="debug", choices=list(LOG_LEVELS.keys()) 27 | ) 28 | 29 | subparsers = parser.add_subparsers(description="subcommands") 30 | 31 | combine = subparsers.add_parser("combine") 32 | combine.add_argument("directory") 33 | combine.set_defaults(func=combine_command) 34 | 35 | format_manifest = subparsers.add_parser("format-manifest") 36 | format_manifest.set_defaults(func=format_manifest_command) 37 | 38 | update = subparsers.add_parser("update") 39 | update.set_defaults(func=update_command) 40 | 41 | eval = subparsers.add_parser("eval") 42 | eval.add_argument("directory", default=".") 43 | eval.set_defaults(func=eval_command) 44 | 45 | index = subparsers.add_parser("index") 46 | index.add_argument("directory", default=ROOT) 47 | index.set_defaults(func=index_command) 48 | 49 | args = parser.parse_args(argv[1:]) 50 | 51 | if not hasattr(args, "func"): 52 | print("subcommand is missing", file=sys.stderr) 53 | parser.print_help(sys.stderr) 54 | sys.exit(1) 55 | 56 | return args 57 | 58 | 59 | def main() -> None: 60 | args = parse_arguments(sys.argv) 61 | logging.basicConfig(level=LOG_LEVELS[args.log_level]) 62 | 63 | args.func(args) 64 | -------------------------------------------------------------------------------- /ci/nur/combine.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import shutil 4 | import subprocess 5 | from argparse import Namespace 6 | from distutils.dir_util import copy_tree 7 | from pathlib import Path 8 | from tempfile import TemporaryDirectory 9 | from typing import Dict, List, Optional 10 | 11 | from .fileutils import chdir, write_json_file 12 | from .manifest import Repo, load_manifest, update_lock_file 13 | from .path import LOCK_PATH, MANIFEST_PATH, ROOT 14 | 15 | logger = logging.getLogger(__name__) 16 | 17 | 18 | def load_combined_repos(path: Path) -> Dict[str, Repo]: 19 | combined_manifest = load_manifest( 20 | path.joinpath("repos.json"), path.joinpath("repos.json.lock") 21 | ) 22 | repos = {} 23 | for repo in combined_manifest.repos: 24 | repos[repo.name] = repo 25 | return repos 26 | 27 | 28 | def repo_source(name: str) -> str: 29 | cmd = ["nix-build", str(ROOT), "--no-out-link", "-A", f"repo-sources.{name}"] 30 | out = subprocess.check_output(cmd) 31 | return out.strip().decode("utf-8") 32 | 33 | 34 | def repo_changed() -> bool: 35 | diff_cmd = subprocess.Popen(["git", "diff", "--staged", "--exit-code"]) 36 | return diff_cmd.wait() == 1 37 | 38 | 39 | def commit_files(files: List[str], message: str) -> None: 40 | cmd = ["git", "add"] 41 | cmd.extend(files) 42 | subprocess.check_call(cmd) 43 | if repo_changed(): 44 | subprocess.check_call(["git", "commit", "-m", message]) 45 | 46 | 47 | def commit_repo(repo: Repo, message: str, path: Path) -> Repo: 48 | repo_path = path.joinpath(repo.name).resolve() 49 | 50 | tmp: Optional[TemporaryDirectory] = TemporaryDirectory(prefix=str(repo_path.parent)) 51 | assert tmp is not None 52 | 53 | try: 54 | copy_tree(repo_source(repo.name), tmp.name, preserve_symlinks=1) 55 | shutil.rmtree(repo_path, ignore_errors=True) 56 | os.rename(tmp.name, repo_path) 57 | tmp = None 58 | finally: 59 | if tmp is not None: 60 | tmp.cleanup() 61 | 62 | with chdir(str(path)): 63 | commit_files([str(repo_path)], message) 64 | 65 | return repo 66 | 67 | 68 | def repo_link(path: Path) -> str: 69 | commit = subprocess.check_output(["git", "-C", path, "rev-parse", "HEAD"]) 70 | rev = commit.decode("utf-8").strip()[:10] 71 | return f"https://github.com/nix-community/nur-combined/commit/{rev}" 72 | 73 | 74 | def update_combined_repo( 75 | combined_repo: Optional[Repo], repo: Repo, path: Path 76 | ) -> Optional[Repo]: 77 | if repo.locked_version is None: 78 | return None 79 | 80 | new_rev = repo.locked_version.rev 81 | if combined_repo is None: 82 | message = f"{repo.name}: init at {new_rev[:10]} ({repo_link(path)})" 83 | repo = commit_repo(repo, message, path) 84 | return repo 85 | 86 | assert combined_repo.locked_version is not None 87 | old_rev = combined_repo.locked_version.rev 88 | 89 | if combined_repo.locked_version == repo.locked_version: 90 | return repo 91 | 92 | if new_rev != old_rev: 93 | message = f"{repo.name}: {old_rev[:10]} -> {new_rev[:10]}" 94 | else: 95 | message = f"{repo.name}: update" 96 | 97 | repo = commit_repo(repo, message, path) 98 | return repo 99 | 100 | 101 | def remove_repo(repo: Repo, path: Path) -> None: 102 | repo_path = path.joinpath("repos", repo.name).resolve() 103 | if repo_path.exists(): 104 | shutil.rmtree(repo_path) 105 | with chdir(path): 106 | commit_files([str(repo_path)], f"{repo.name}: remove") 107 | 108 | 109 | def update_manifest(repos: List[Repo], path: Path) -> None: 110 | d = {} 111 | 112 | for repo in repos: 113 | d[repo.name] = repo.as_json() 114 | write_json_file(dict(repos=d), path) 115 | 116 | 117 | def update_combined(path: Path) -> None: 118 | manifest = load_manifest(MANIFEST_PATH, LOCK_PATH) 119 | 120 | combined_repos = load_combined_repos(path) 121 | 122 | repos_path = path.joinpath("repos") 123 | os.makedirs(repos_path, exist_ok=True) 124 | 125 | updated_repos = [] 126 | 127 | for repo in manifest.repos: 128 | combined_repo = None 129 | if repo.name in combined_repos: 130 | combined_repo = combined_repos[repo.name] 131 | del combined_repos[repo.name] 132 | try: 133 | new_repo = update_combined_repo(combined_repo, repo, repos_path) 134 | except Exception: 135 | logger.exception(f"Failed to updated repository {repo.name}") 136 | continue 137 | 138 | if new_repo is not None: 139 | updated_repos.append(new_repo) 140 | 141 | for combined_repo in combined_repos.values(): 142 | remove_repo(combined_repo, path) 143 | 144 | update_manifest(updated_repos, path.joinpath("repos.json")) 145 | 146 | update_lock_file(updated_repos, path.joinpath("repos.json.lock")) 147 | 148 | with chdir(path): 149 | commit_files(["repos.json", "repos.json.lock"], "update repos.json + lock") 150 | 151 | 152 | def setup_combined() -> None: 153 | manifest_path = "repos.json" 154 | 155 | if not Path(".git").exists(): 156 | cmd = ["git", "init", "."] 157 | subprocess.check_call(cmd) 158 | 159 | if not os.path.exists(manifest_path): 160 | write_json_file(dict(repos={}), manifest_path) 161 | 162 | manifest_lib = "lib" 163 | copy_tree(str(ROOT.joinpath("lib")), manifest_lib, preserve_symlinks=1) 164 | default_nix = "default.nix" 165 | shutil.copy(ROOT.joinpath("default.nix"), default_nix) 166 | 167 | vcs_files = [manifest_path, manifest_lib, default_nix] 168 | 169 | commit_files(vcs_files, "update code") 170 | 171 | 172 | def combine_command(args: Namespace) -> None: 173 | combined_path = Path(args.directory) 174 | 175 | with chdir(combined_path): 176 | setup_combined() 177 | update_combined(combined_path) 178 | -------------------------------------------------------------------------------- /ci/nur/error.py: -------------------------------------------------------------------------------- 1 | class NurError(Exception): 2 | pass 3 | 4 | 5 | class EvalError(NurError): 6 | pass 7 | -------------------------------------------------------------------------------- /ci/nur/eval.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import subprocess 4 | import tempfile 5 | from argparse import Namespace 6 | from pathlib import Path 7 | from urllib.parse import urlparse 8 | 9 | from .error import EvalError 10 | from .manifest import Repo 11 | from .path import EVALREPO_PATH, nixpkgs_path 12 | 13 | logger = logging.getLogger(__name__) 14 | 15 | 16 | def eval_repo(repo: Repo, repo_path: Path) -> None: 17 | with tempfile.TemporaryDirectory() as d: 18 | eval_path = Path(d).joinpath("default.nix") 19 | with open(eval_path, "w") as f: 20 | f.write( 21 | f""" 22 | with import {{}}; 23 | import {EVALREPO_PATH} {{ 24 | name = "{repo.name}"; 25 | url = "{repo.url}"; 26 | src = {repo_path.joinpath(repo.file)}; 27 | inherit pkgs lib; 28 | }} 29 | """ 30 | ) 31 | 32 | canonicalized_eval_path = eval_path.resolve() 33 | # fmt: off 34 | cmd = [ 35 | "nix-env", 36 | "-f", str(canonicalized_eval_path), 37 | "-qa", "*", 38 | "--meta", 39 | "--xml", 40 | "--allowed-uris", "https://static.rust-lang.org", 41 | "--option", "restrict-eval", "true", 42 | "--option", "allow-import-from-derivation", "true", 43 | "--drv-path", 44 | "--show-trace", 45 | "-I", f"nixpkgs={nixpkgs_path()}", 46 | "-I", str(repo_path), 47 | "-I", str(canonicalized_eval_path), 48 | "-I", str(EVALREPO_PATH), 49 | ] 50 | # fmt: on 51 | 52 | logger.info(f"Evaluate repository {repo.name}") 53 | env = dict(PATH=os.environ["PATH"], NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM="1") 54 | proc = subprocess.Popen(cmd, env=env, stdout=subprocess.DEVNULL) 55 | try: 56 | res = proc.wait(15) 57 | except subprocess.TimeoutExpired: 58 | raise EvalError(f"evaluation for {repo.name} timed out of after 15 seconds") 59 | if res != 0: 60 | raise EvalError(f"{repo.name} does not evaluate:\n$ {' '.join(cmd)}") 61 | 62 | 63 | def eval_command(args: Namespace) -> None: 64 | logging.basicConfig(level=logging.INFO) 65 | 66 | repo_path = Path(args.directory) 67 | name = repo_path.name 68 | repo = Repo( 69 | name, 70 | urlparse("localhost"), 71 | False, 72 | None, 73 | None, 74 | None, 75 | None, 76 | ) 77 | eval_repo(repo, repo_path) 78 | print("OK") 79 | -------------------------------------------------------------------------------- /ci/nur/fileutils.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import shutil 4 | from contextlib import contextmanager 5 | from pathlib import Path 6 | from tempfile import NamedTemporaryFile 7 | from typing import Any, Generator, Union 8 | 9 | PathType = Union[str, Path] 10 | 11 | 12 | def to_path(path: PathType) -> Path: 13 | if isinstance(path, Path): 14 | return path 15 | else: 16 | return Path(path) 17 | 18 | 19 | def write_json_file(data: Any, path: PathType) -> None: 20 | path = to_path(path) 21 | f = NamedTemporaryFile(mode="w+", prefix=path.name, dir=str(path.parent)) 22 | with f as tmp_file: 23 | json.dump(data, tmp_file, indent=4, sort_keys=True) 24 | shutil.move(tmp_file.name, path) 25 | # NamedTemporaryFile tries to delete the file and fails otherwise 26 | open(tmp_file.name, "a").close() 27 | 28 | 29 | @contextmanager 30 | def chdir(dest: PathType) -> Generator[None, None, None]: 31 | previous = os.getcwd() 32 | os.chdir(dest) 33 | try: 34 | yield 35 | finally: 36 | os.chdir(previous) 37 | -------------------------------------------------------------------------------- /ci/nur/format_manifest.py: -------------------------------------------------------------------------------- 1 | import json 2 | import shutil 3 | import sys 4 | from argparse import Namespace 5 | 6 | from .path import ROOT 7 | 8 | 9 | def format_manifest_command(args: Namespace) -> None: 10 | path = ROOT.joinpath("repos.json") 11 | manifest = json.load(open(path)) 12 | for name, repo in manifest.get("repos", []).items(): 13 | if "url" not in repo: 14 | print(f"{name} has no url", file=sys.stderr) 15 | sys.exit(1) 16 | 17 | if "github-contact" not in repo: 18 | print(f"{name} has no github contact", file=sys.stderr) 19 | sys.exit(1) 20 | 21 | tmp_path = str(path) + ".tmp" 22 | with open(tmp_path, "w+") as tmp: 23 | json.dump(manifest, tmp, indent=4, sort_keys=True) 24 | tmp.write("\n") 25 | shutil.move(tmp_path, path) 26 | -------------------------------------------------------------------------------- /ci/nur/index.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import subprocess 4 | import sys 5 | from argparse import Namespace 6 | from pathlib import Path 7 | from tempfile import NamedTemporaryFile 8 | from typing import Any, Dict 9 | 10 | 11 | def resolve_source(pkg: Dict, repo: str, url: str) -> str: 12 | # TODO commit hash 13 | prefix = f"https://github.com/nix-community/nur-combined/tree/main/repos/{repo}" 14 | position = pkg["meta"].get("position", None) 15 | 16 | if position is not None and position.startswith("/nix/store"): 17 | path_str, line = position.rsplit(":", 1) 18 | path = Path(path_str) 19 | # I've decided to just take these 2 repositories, 20 | # update this whenever someone decided to use a recipe source other than 21 | # NUR or nixpkgs to override packages on. right now this is about as accurate as 22 | # `nix edit` is 23 | # TODO find commit hash 24 | prefixes = { 25 | "nixpkgs": "https://github.com/nixos/nixpkgs/tree/master/", 26 | "nur": "https://github.com/nix-community/nur-combined/tree/main/", 27 | } 28 | stripped = path.parts[4:] 29 | if path.parts[3].endswith("source"): 30 | canonical_url = url 31 | # if we want to add the option of specifying branches, we have to update this 32 | if "github" in url: 33 | canonical_url += "/blob/HEAD/" 34 | elif "gitlab" in url: 35 | canonical_url += "/-/blob/HEAD/" 36 | attr_path = "/".join(stripped) 37 | location = f"{canonical_url}{attr_path}" 38 | return f"{location}#L{line}" 39 | elif stripped[0] not in prefixes: 40 | print(path, file=sys.stderr) 41 | print( 42 | f"we could not find {stripped} , you can file an issue at https://github.com/nix-community/NUR/issues to the indexing file if you think this is a mistake", 43 | file=sys.stderr, 44 | ) 45 | return prefix 46 | else: 47 | attr_path = "/".join(stripped[1:]) 48 | location = f"{prefixes[stripped[0]]}{attr_path}" 49 | return f"{location}#L{line}" 50 | elif position is not None and "nur-combined" in position: 51 | path_str, line = position.rsplit(":", 1) 52 | stripped = path_str.partition(f"nur-combined/repos/{repo}")[2] 53 | return f"{prefix}{stripped}#L{line}" 54 | else: 55 | return prefix 56 | 57 | 58 | def index_repo( 59 | directory: Path, repo: str, expression_file: str, url: str 60 | ) -> Dict[str, Any]: 61 | default_nix = directory.joinpath("default.nix").resolve() 62 | expr = """ 63 | with import {}; 64 | let 65 | nur = import %s { nurpkgs = pkgs; inherit pkgs; }; 66 | in 67 | callPackage (nur.repo-sources."%s" + "/%s") {} 68 | """ % ( 69 | default_nix, 70 | repo, 71 | expression_file, 72 | ) 73 | 74 | with NamedTemporaryFile(mode="w") as f: 75 | f.write(expr) 76 | f.flush() 77 | env = os.environ.copy() 78 | env.update(NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM="1") 79 | query_cmd = ["nix-env", "-qa", "*", "--meta", "--json", "-f", str(f.name)] 80 | try: 81 | out = subprocess.check_output(query_cmd, env=env) 82 | except subprocess.CalledProcessError: 83 | print(f"failed to evaluate {repo}", file=sys.stderr) 84 | return {} 85 | 86 | raw_pkgs = json.loads(out) 87 | pkgs = {} 88 | for name, pkg in raw_pkgs.items(): 89 | pkg["_attr"] = name 90 | pkg["_repo"] = repo 91 | pkg["meta"]["position"] = resolve_source(pkg, repo, url) 92 | pkgs[f"nur.repos.{repo}.{name}"] = pkg 93 | 94 | return pkgs 95 | 96 | 97 | def index_command(args: Namespace) -> None: 98 | directory = Path(args.directory) 99 | manifest_path = directory.joinpath("repos.json") 100 | with open(manifest_path) as f: 101 | manifest = json.load(f) 102 | repos = manifest.get("repos", []) 103 | pkgs: Dict[str, Any] = {} 104 | 105 | for repo, data in repos.items(): 106 | repo_pkgs = index_repo( 107 | directory, 108 | repo, 109 | data.get("file", "default.nix"), 110 | data.get("url", "https://github.com/nixos/nixpkgs"), 111 | ) 112 | pkgs.update(repo_pkgs) 113 | 114 | json.dump(pkgs, sys.stdout, indent=4) 115 | -------------------------------------------------------------------------------- /ci/nur/manifest.py: -------------------------------------------------------------------------------- 1 | import json 2 | from enum import Enum, auto 3 | from pathlib import Path 4 | from typing import Any, Dict, List, Optional 5 | from urllib.parse import ParseResult, urlparse 6 | 7 | from .fileutils import PathType, to_path, write_json_file 8 | 9 | Url = ParseResult 10 | 11 | 12 | class LockedVersion: 13 | def __init__( 14 | self, url: Url, rev: str, sha256: str, submodules: bool = False 15 | ) -> None: 16 | self.url = url 17 | self.rev = rev 18 | self.sha256 = sha256 19 | self.submodules = submodules 20 | 21 | def __eq__(self, other: Any) -> bool: 22 | if type(other) is type(self): 23 | return self.__dict__ == other.__dict__ 24 | return False 25 | 26 | def as_json(self) -> Dict[str, Any]: 27 | d = dict( 28 | url=self.url.geturl(), rev=self.rev, sha256=self.sha256 29 | ) # type: Dict[str, Any] 30 | if self.submodules: 31 | d["submodules"] = self.submodules 32 | return d 33 | 34 | 35 | class RepoType(Enum): 36 | GITHUB = auto() 37 | GITLAB = auto() 38 | GIT = auto() 39 | 40 | @staticmethod 41 | def from_repo(repo: "Repo", type_: Optional[str]) -> "RepoType": 42 | if repo.submodules: 43 | return RepoType.GIT 44 | if repo.url.hostname == "github.com": 45 | return RepoType.GITHUB 46 | if repo.url.hostname == "gitlab.com" or type_ == "gitlab": 47 | return RepoType.GITLAB 48 | else: 49 | return RepoType.GIT 50 | 51 | 52 | class Repo: 53 | def __init__( 54 | self, 55 | name: str, 56 | url: Url, 57 | submodules: bool, 58 | supplied_type: Optional[str], 59 | file_: Optional[str], 60 | branch: Optional[str], 61 | locked_version: Optional[LockedVersion], 62 | ) -> None: 63 | self.name = name 64 | self.url = url 65 | self.submodules = submodules 66 | if file_ is None: 67 | self.file = "default.nix" 68 | else: 69 | self.file = file_ 70 | self.branch = branch 71 | self.locked_version = None 72 | 73 | if ( 74 | locked_version is not None 75 | and locked_version.url != url.geturl() 76 | and locked_version.submodules == submodules 77 | ): 78 | self.locked_version = locked_version 79 | 80 | self.supplied_type = supplied_type 81 | self.computed_type = RepoType.from_repo(self, supplied_type) 82 | 83 | @property 84 | def type(self) -> RepoType: 85 | return self.computed_type 86 | 87 | def __repr__(self) -> str: 88 | return f"<{self.__class__.__name__} {self.name}>" 89 | 90 | def as_json(self) -> Dict[str, Any]: 91 | d = dict(url=self.url.geturl()) # type: Dict[str, Any] 92 | 93 | if self.submodules: 94 | d["submodules"] = self.submodules 95 | 96 | if self.supplied_type is not None: 97 | d["type"] = self.supplied_type 98 | 99 | if self.file is not None and self.file != "default.nix": 100 | d["file"] = self.file 101 | 102 | return d 103 | 104 | 105 | class Manifest: 106 | def __init__(self, repos: List[Repo]) -> None: 107 | self.repos = repos 108 | 109 | def __repr__(self) -> str: 110 | return f"<{self.__class__.__name__} {repr(self.repos)}>" 111 | 112 | 113 | def _load_locked_versions(path: PathType) -> Dict[str, LockedVersion]: 114 | with open(path) as f: 115 | data = json.load(f) 116 | 117 | locked_versions = {} 118 | 119 | for name, repo in data["repos"].items(): 120 | url = urlparse(repo["url"]) 121 | rev = repo["rev"] 122 | sha256 = repo["sha256"] 123 | submodules = repo.get("submodules", False) 124 | locked_versions[name] = LockedVersion(url, rev, sha256, submodules) 125 | 126 | return locked_versions 127 | 128 | 129 | def load_locked_versions(path: Path) -> Dict[str, LockedVersion]: 130 | if path.exists(): 131 | return _load_locked_versions(path) 132 | else: 133 | return {} 134 | 135 | 136 | def update_lock_file(repos: List[Repo], path: Path) -> None: 137 | locked_repos = {} 138 | for repo in repos: 139 | if repo.locked_version: 140 | locked_repos[repo.name] = repo.locked_version.as_json() 141 | 142 | write_json_file(dict(repos=locked_repos), path) 143 | 144 | 145 | def load_manifest(manifest_path: PathType, lock_path: PathType) -> Manifest: 146 | locked_versions = load_locked_versions(to_path(lock_path)) 147 | 148 | with open(manifest_path) as f: 149 | data = json.load(f) 150 | 151 | repos = [] 152 | for name, repo in data["repos"].items(): 153 | url = urlparse(repo["url"]) 154 | submodules = repo.get("submodules", False) 155 | branch_ = repo.get("branch") 156 | file_ = repo.get("file", "default.nix") 157 | type_ = repo.get("type", None) 158 | locked_version = locked_versions.get(name) 159 | repos.append(Repo(name, url, submodules, type_, file_, branch_, locked_version)) 160 | 161 | return Manifest(repos) 162 | -------------------------------------------------------------------------------- /ci/nur/path.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from pathlib import Path 4 | 5 | from .error import NurError 6 | 7 | 8 | def _is_repo(path: Path) -> bool: 9 | return path.joinpath("lib/evalRepo.nix").exists() 10 | 11 | 12 | def _find_root() -> Path: 13 | source_root = Path(__file__).parent.parent.resolve() 14 | if _is_repo(source_root): 15 | # if it was not build with release.nix 16 | return source_root 17 | else: 18 | root = Path(os.getcwd()).resolve() 19 | 20 | while True: 21 | if _is_repo(root): 22 | return root 23 | new_root = root.parent.resolve() 24 | if new_root == root: 25 | if _is_repo(new_root): 26 | return new_root 27 | else: 28 | raise NurError("NUR repository not found in current directory") 29 | root = new_root 30 | 31 | 32 | ROOT = _find_root() 33 | LOCK_PATH = ROOT.joinpath("repos.json.lock") 34 | MANIFEST_PATH = ROOT.joinpath("repos.json") 35 | EVALREPO_PATH = ROOT.joinpath("lib/evalRepo.nix") 36 | 37 | _NIXPKGS_PATH = None 38 | 39 | 40 | def nixpkgs_path() -> str: 41 | global _NIXPKGS_PATH 42 | if _NIXPKGS_PATH is not None: 43 | return _NIXPKGS_PATH 44 | cmd = ["nix-instantiate", "--find-file", "nixpkgs"] 45 | path = subprocess.check_output(cmd).decode("utf-8").strip() 46 | _NIXPKGS_PATH = str(Path(path).resolve()) 47 | 48 | return _NIXPKGS_PATH 49 | -------------------------------------------------------------------------------- /ci/nur/prefetch.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import re 4 | import subprocess 5 | from pathlib import Path 6 | from typing import Optional, Tuple 7 | from urllib.parse import ParseResult 8 | 9 | from .error import NurError 10 | from .manifest import LockedVersion, Repo, RepoType 11 | 12 | Url = ParseResult 13 | 14 | 15 | def nix_prefetch_zip(url: str) -> Tuple[str, Path]: 16 | data = subprocess.check_output( 17 | ["nix-prefetch-url", "--name", "source", "--unpack", "--print-path", url] 18 | ) 19 | sha256, path = data.decode().strip().split("\n") 20 | return sha256, Path(path) 21 | 22 | 23 | class GitPrefetcher: 24 | def __init__(self, repo: Repo) -> None: 25 | self.repo = repo 26 | 27 | def latest_commit(self) -> str: 28 | data = subprocess.check_output( 29 | ["git", "ls-remote", self.repo.url.geturl(), self.repo.branch or "HEAD"], 30 | env={**os.environ, "GIT_ASKPASS": "", "GIT_TERMINAL_PROMPT": "0"}, 31 | ) 32 | return data.decode().split(maxsplit=1)[0] 33 | 34 | def prefetch(self, ref: str) -> Tuple[str, Path]: 35 | cmd = ["nix-prefetch-git"] 36 | if self.repo.submodules: 37 | cmd += ["--fetch-submodules"] 38 | if self.repo.branch: 39 | cmd += ["--rev", f"refs/heads/{self.repo.branch}"] 40 | cmd += [self.repo.url.geturl()] 41 | proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 42 | try: 43 | stdout, stderr = proc.communicate(timeout=30) 44 | except subprocess.TimeoutExpired: 45 | proc.kill() 46 | raise NurError( 47 | f"Timeout expired while prefetching git repository {self. repo.url.geturl()}" 48 | ) 49 | 50 | if proc.returncode != 0: 51 | raise NurError( 52 | f"Failed to prefetch git repository {self.repo.url.geturl()}: {stderr.decode('utf-8')}" 53 | ) 54 | 55 | metadata = json.loads(stdout) 56 | lines = stderr.decode("utf-8").split("\n") 57 | repo_path = re.search("path is (.+)", lines[-5]) 58 | assert repo_path is not None 59 | path = Path(repo_path.group(1)) 60 | sha256 = metadata["sha256"] 61 | return sha256, path 62 | 63 | 64 | class GithubPrefetcher(GitPrefetcher): 65 | def prefetch(self, ref: str) -> Tuple[str, Path]: 66 | return nix_prefetch_zip(f"{self.repo.url.geturl()}/archive/{ref}.tar.gz") 67 | 68 | 69 | class GitlabPrefetcher(GitPrefetcher): 70 | def prefetch(self, ref: str) -> Tuple[str, Path]: 71 | hostname = self.repo.url.hostname 72 | assert ( 73 | hostname is not None 74 | ), f"Expect a hostname for Gitlab repo: {self.repo.name}" 75 | path = Path(self.repo.url.path) 76 | escaped_path = "%2F".join(path.parts[1:]) 77 | url = f"https://{hostname}/api/v4/projects/{escaped_path}/repository/archive.tar.gz?sha={ref}" 78 | return nix_prefetch_zip(url) 79 | 80 | 81 | def prefetch(repo: Repo) -> Tuple[Repo, LockedVersion, Optional[Path]]: 82 | prefetcher: GitPrefetcher 83 | if repo.type == RepoType.GITHUB: 84 | prefetcher = GithubPrefetcher(repo) 85 | elif repo.type == RepoType.GITLAB: 86 | prefetcher = GitlabPrefetcher(repo) 87 | else: 88 | prefetcher = GitPrefetcher(repo) 89 | 90 | commit = prefetcher.latest_commit() 91 | locked_version = repo.locked_version 92 | if locked_version is not None: 93 | if locked_version.rev == commit: 94 | return repo, locked_version, None 95 | 96 | sha256, path = prefetcher.prefetch(commit) 97 | return repo, LockedVersion(repo.url, commit, sha256, repo.submodules), path 98 | -------------------------------------------------------------------------------- /ci/nur/update.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from argparse import Namespace 3 | from concurrent.futures import ThreadPoolExecutor, as_completed 4 | 5 | from .eval import EvalError, eval_repo 6 | from .manifest import Repo, load_manifest, update_lock_file 7 | from .path import LOCK_PATH, MANIFEST_PATH 8 | from .prefetch import prefetch 9 | 10 | logger = logging.getLogger(__name__) 11 | 12 | 13 | def update(repo: Repo) -> Repo: 14 | repo, locked_version, repo_path = prefetch(repo) 15 | 16 | if repo_path: 17 | eval_repo(repo, repo_path) 18 | 19 | repo.locked_version = locked_version 20 | return repo 21 | 22 | 23 | def update_command(args: Namespace) -> None: 24 | logging.basicConfig(level=logging.INFO) 25 | 26 | manifest = load_manifest(MANIFEST_PATH, LOCK_PATH) 27 | 28 | if getattr(args, "debug", False): 29 | for repo in manifest.repos: 30 | try: 31 | update(repo) 32 | except EvalError as err: 33 | if repo.locked_version is None: 34 | logger.error( 35 | f"repository {repo.name} failed to evaluate: {err}. This repo is not yet in our lock file!!!!" 36 | ) 37 | raise 38 | logger.error(f"repository {repo.name} failed to evaluate: {err}") 39 | except Exception: 40 | logger.exception(f"Failed to update repository {repo.name}") 41 | else: 42 | with ThreadPoolExecutor() as executor: 43 | future_to_repo = { 44 | executor.submit(update, repo): repo for repo in manifest.repos 45 | } 46 | 47 | for future in as_completed(future_to_repo): 48 | repo = future_to_repo[future] 49 | try: 50 | future.result() 51 | except EvalError as err: 52 | if repo.locked_version is None: 53 | logger.error( 54 | f"repository {repo.name} failed to evaluate: {err}. This repo is not yet in our lock file!!!!" 55 | ) 56 | raise 57 | logger.error(f"repository {repo.name} failed to evaluate: {err}") 58 | except Exception: 59 | logger.exception(f"Failed to update repository {repo.name}") 60 | 61 | update_lock_file(manifest.repos, LOCK_PATH) 62 | -------------------------------------------------------------------------------- /ci/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.ruff] 2 | target-version = "py311" 3 | line-length = 88 4 | 5 | lint.select = ["E", "F", "I"] 6 | lint.ignore = ["E501"] 7 | 8 | [tool.black] 9 | line-length = 88 10 | include = '\.pyi?$' 11 | exclude = ''' 12 | /( 13 | \.git 14 | | \.mypy_cache 15 | )/ 16 | ''' 17 | 18 | [tool.mypy] 19 | python_version = "3.11" 20 | warn_redundant_casts = true 21 | disallow_untyped_calls = true 22 | disallow_untyped_defs = true 23 | no_implicit_optional = true 24 | 25 | [[tool.mypy.overrides]] 26 | module = "setuptools.*" 27 | ignore_missing_imports = true 28 | 29 | [[tool.mypy.overrides]] 30 | module = "pytest.*" 31 | ignore_missing_imports = true 32 | -------------------------------------------------------------------------------- /ci/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | 4 | from setuptools import find_packages, setup 5 | 6 | assert sys.version_info >= (3, 6, 0), "nur requires Python 3.6+" 7 | 8 | setup( 9 | name="nur", 10 | version="0.0.1", 11 | description="Tooling to maintain NUR", 12 | author="Jörg Thalheim", 13 | author_email="joerg@thalheim.io", 14 | url="https://github.com/nix-community/nur", 15 | license="MIT", 16 | packages=find_packages(), 17 | entry_points={"console_scripts": ["nur = nur:main"]}, 18 | extras_require={ 19 | "dev": ["mypy", "flake8", "black"], 20 | }, 21 | classifiers=[ 22 | "Development Status :: 5 - Production/Stable", 23 | "Environment :: Console", 24 | "Topic :: Utilities", 25 | "Intended Audience :: Developers", 26 | "Programming Language :: Python :: 3.6", 27 | ], 28 | ) 29 | -------------------------------------------------------------------------------- /ci/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nix-shell 2 | #!nix-shell -p bash -i bash -p mypy -p black -p ruff -p nix 3 | 4 | set -eux -o pipefail # Exit with nonzero exit code if anything fails 5 | 6 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 7 | 8 | cd "${DIR}" 9 | # Type checker 10 | mypy nur 11 | # Format checker 12 | black --check . 13 | # Linter 14 | ruff check . 15 | 16 | cd "${DIR}/.." 17 | nix run "${DIR}#" -- format-manifest 18 | if [ -n "$(git diff --exit-code repos.json)" ]; then 19 | echo "repos.json was not formatted before committing repos.json:" >&2 20 | git diff --exit-code repos.json 21 | echo "Please run ./bin/nur/format-manifest.py and updates repos.json accordingly!" >&2 22 | exit 1 23 | fi 24 | 25 | nix run "${DIR}#" -- update 26 | nix-build 27 | -------------------------------------------------------------------------------- /ci/update-nur-combined.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nix-shell 2 | #!nix-shell -p git -p nix -p bash -i bash 3 | 4 | set -eu -o pipefail # Exit with nonzero exit code if anything fails 5 | 6 | 7 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 8 | 9 | source ${DIR}/lib/setup-git.sh 10 | set -x 11 | 12 | cd "${DIR}/.." 13 | 14 | nix run "${DIR}#" -- combine nur-combined 15 | -------------------------------------------------------------------------------- /ci/update-nur-search.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nix-shell 2 | #!nix-shell -p git -p nix -p bash -i bash 3 | 4 | set -eu -o pipefail # Exit with nonzero exit code if anything fails 5 | 6 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 7 | 8 | source ${DIR}/lib/setup-git.sh 9 | set -x 10 | 11 | 12 | # build package.json for nur-search 13 | # --------------------------------- 14 | 15 | nix build "${DIR}#" 16 | 17 | cd "${DIR}/.." 18 | 19 | nix run "${DIR}#" -- index nur-combined > nur-search/data/packages.json 20 | 21 | # rebuild and publish nur-search repository 22 | # ----------------------------------------- 23 | 24 | cd nur-search 25 | if [[ ! -z "$(git diff --exit-code)" ]]; then 26 | git add ./data/packages.json 27 | git commit -m "automatic update package.json" 28 | else 29 | echo "nothings changed will not commit anything" 30 | fi 31 | -------------------------------------------------------------------------------- /ci/update-nur.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env nix-shell 2 | #!nix-shell -p git -p nix -p bash -i bash 3 | 4 | set -eu -o pipefail # Exit with nonzero exit code if anything fails 5 | 6 | 7 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" 8 | 9 | source ${DIR}/lib/setup-git.sh 10 | set -x 11 | 12 | nix run "${DIR}#" -- update 13 | 14 | cd ${DIR}/.. 15 | 16 | nix flake update nixpkgs 17 | 18 | if [[ -z "$(git diff --exit-code)" ]]; then 19 | echo "No changes to the output on this push; exiting." 20 | else 21 | git add --all repos.json* flake.lock 22 | git commit -m "automatic update" 23 | fi 24 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { 2 | nurpkgs ? import { }, # For nixpkgs dependencies used by NUR itself 3 | # Dependencies to call NUR repos with 4 | # The override handles the case where NUR is installed via standalone channel or channel + override 5 | pkgs ? ( 6 | import { 7 | overrides = [ 8 | (final: prev: if prev ? nur then prev else { nur = ./. { pkgs = final; }; }) 9 | ]; 10 | } 11 | ), 12 | repoOverrides ? { }, 13 | }: 14 | 15 | let 16 | manifest = (builtins.fromJSON (builtins.readFile ./repos.json)).repos; 17 | lockedRevisions = (builtins.fromJSON (builtins.readFile ./repos.json.lock)).repos; 18 | 19 | inherit (nurpkgs) lib; 20 | 21 | repoSource = 22 | name: attr: 23 | import ./lib/repoSource.nix { 24 | inherit 25 | name 26 | attr 27 | manifest 28 | lockedRevisions 29 | lib 30 | ; 31 | inherit (nurpkgs) fetchgit fetchzip; 32 | }; 33 | 34 | createRepo = 35 | name: attr: 36 | import ./lib/evalRepo.nix { 37 | inherit name pkgs lib; 38 | inherit (attr) url; 39 | src = repoSource name attr + ("/" + (attr.file or "")); 40 | }; 41 | 42 | in 43 | { 44 | repos = (lib.mapAttrs createRepo manifest) // repoOverrides; 45 | repo-sources = lib.mapAttrs repoSource manifest; 46 | } 47 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": [ 6 | "nixpkgs" 7 | ] 8 | }, 9 | "locked": { 10 | "lastModified": 1733312601, 11 | "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", 12 | "owner": "hercules-ci", 13 | "repo": "flake-parts", 14 | "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", 15 | "type": "github" 16 | }, 17 | "original": { 18 | "owner": "hercules-ci", 19 | "repo": "flake-parts", 20 | "type": "github" 21 | } 22 | }, 23 | "nixpkgs": { 24 | "locked": { 25 | "lastModified": 1748693115, 26 | "narHash": "sha256-StSrWhklmDuXT93yc3GrTlb0cKSS0agTAxMGjLKAsY8=", 27 | "owner": "nixos", 28 | "repo": "nixpkgs", 29 | "rev": "910796cabe436259a29a72e8d3f5e180fc6dfacc", 30 | "type": "github" 31 | }, 32 | "original": { 33 | "owner": "nixos", 34 | "ref": "nixos-unstable", 35 | "repo": "nixpkgs", 36 | "type": "github" 37 | } 38 | }, 39 | "root": { 40 | "inputs": { 41 | "flake-parts": "flake-parts", 42 | "nixpkgs": "nixpkgs", 43 | "treefmt-nix": "treefmt-nix" 44 | } 45 | }, 46 | "treefmt-nix": { 47 | "inputs": { 48 | "nixpkgs": [ 49 | "nixpkgs" 50 | ] 51 | }, 52 | "locked": { 53 | "lastModified": 1733222881, 54 | "narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=", 55 | "owner": "numtide", 56 | "repo": "treefmt-nix", 57 | "rev": "49717b5af6f80172275d47a418c9719a31a78b53", 58 | "type": "github" 59 | }, 60 | "original": { 61 | "owner": "numtide", 62 | "repo": "treefmt-nix", 63 | "type": "github" 64 | } 65 | } 66 | }, 67 | "root": "root", 68 | "version": 7 69 | } 70 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Nix User Repository"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; 6 | flake-parts = { 7 | url = "github:hercules-ci/flake-parts"; 8 | inputs.nixpkgs-lib.follows = "nixpkgs"; 9 | }; 10 | treefmt-nix = { 11 | url = "github:numtide/treefmt-nix"; 12 | inputs.nixpkgs.follows = "nixpkgs"; 13 | }; 14 | }; 15 | 16 | outputs = 17 | inputs@{ flake-parts, nixpkgs, ... }: 18 | let 19 | inherit (nixpkgs) lib; 20 | manifest = (builtins.fromJSON (builtins.readFile ./repos.json)).repos; 21 | overlay = final: prev: { 22 | nur = import ./default.nix { 23 | nurpkgs = prev; 24 | pkgs = prev; 25 | }; 26 | }; 27 | in 28 | flake-parts.lib.mkFlake { inherit inputs; } { 29 | systems = builtins.filter ( 30 | system: builtins.hasAttr system nixpkgs.legacyPackages 31 | ) nixpkgs.lib.platforms.all; 32 | flake = { 33 | overlay = lib.warn "nur.overlay has been replaced by nur.overlays.default" overlay; # Added 2024-12-06 34 | nixosModules.nur = builtins.throw "nur.nixosModules.nur has been replaced by nur.modules.nixos.default"; # Added 2024-12-06 35 | hmModules.nur = builtins.throw "nur.hmModules.nur has been replaced by nur.modules.homeManager.default"; # Added 2024-12-06 36 | 37 | overlays = { 38 | default = overlay; 39 | }; 40 | modules = lib.genAttrs [ "nixos" "homeManager" "darwin" ] (_: { 41 | default = { 42 | nixpkgs.overlays = [ overlay ]; 43 | }; 44 | }); 45 | }; 46 | imports = [ 47 | inputs.flake-parts.flakeModules.modules 48 | inputs.treefmt-nix.flakeModule 49 | ]; 50 | perSystem = 51 | { pkgs, ... }: 52 | { 53 | treefmt.programs.nixfmt.enable = true; 54 | # legacyPackages is used because nur is a package set 55 | # This trick with the overlay is used because it allows NUR packages to depend on other NUR packages 56 | legacyPackages = (pkgs.extend overlay).nur; 57 | }; 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /lib/evalRepo.nix: -------------------------------------------------------------------------------- 1 | { 2 | name, 3 | url, 4 | src, 5 | pkgs, # Do not use this for anything other than passing it along as an argument to the repository 6 | lib, 7 | }: 8 | let 9 | 10 | prettyName = "${name}"; 11 | 12 | # Arguments passed to each repositories default.nix 13 | passedArgs = { 14 | pkgs = 15 | if pkgs != null then 16 | pkgs 17 | else 18 | throw '' 19 | NUR import call didn't receive a pkgs argument, but the evaluation of NUR's ${prettyName} repository requires it. 20 | 21 | This is either because 22 | - You're trying to use a package from that repository, but didn't pass a `pkgs` argument to the NUR import. 23 | In that case, refer to the installation instructions at https://github.com/nix-community/nur#installation on how to properly import NUR 24 | 25 | - You're trying to use a module/overlay from that repository, but it didn't properly declare their module. 26 | In that case, inform the maintainer of the repository: ${url} 27 | ''; 28 | }; 29 | 30 | expr = import src; 31 | args = builtins.functionArgs expr; 32 | # True if not all arguments are either passed by default (e.g. pkgs) or defaulted (e.g. foo ? 10) 33 | usesCallPackage = 34 | !lib.all (arg: lib.elem arg (lib.attrNames passedArgs) || args.${arg}) (lib.attrNames args); 35 | 36 | in 37 | if usesCallPackage then 38 | throw '' 39 | NUR repository ${prettyName} is using the deprecated callPackage syntax which 40 | might result in infinite recursion when used with NixOS modules. 41 | '' 42 | else 43 | expr (builtins.intersectAttrs args passedArgs) 44 | -------------------------------------------------------------------------------- /lib/repoSource.nix: -------------------------------------------------------------------------------- 1 | { 2 | name, 3 | attr, 4 | fetchgit, 5 | fetchzip, 6 | lib, 7 | manifest, 8 | lockedRevisions, 9 | }: 10 | 11 | let 12 | parseGitlabUrl = 13 | url: 14 | with builtins; 15 | let 16 | parts = lib.splitString "/" url; 17 | len = length parts; 18 | in 19 | { 20 | domain = elemAt parts 2; 21 | # Allow for deeper hierarchies than owner/repo (GL has groups and subgroups) 22 | path = lib.drop 3 parts; 23 | }; 24 | 25 | revision = lockedRevisions.${name}; 26 | submodules = attr.submodules or false; 27 | type = attr.type or null; 28 | 29 | localPath = ../repos + "/${name}"; 30 | in 31 | if lib.pathExists localPath then 32 | localPath 33 | else if lib.hasPrefix "https://github.com" attr.url && !submodules then 34 | fetchzip { 35 | url = "${attr.url}/archive/${revision.rev}.zip"; 36 | inherit (revision) sha256; 37 | } 38 | else if (lib.hasPrefix "https://gitlab.com" attr.url || type == "gitlab") && !submodules then 39 | let 40 | gitlab = parseGitlabUrl attr.url; 41 | escapedPath = builtins.concatStringsSep "%2F" gitlab.path; 42 | in 43 | fetchzip { 44 | url = "https://${gitlab.domain}/api/v4/projects/${escapedPath}/repository/archive.tar.gz?sha=${revision.rev}"; 45 | inherit (revision) sha256; 46 | } 47 | else 48 | fetchgit { 49 | inherit (attr) url; 50 | inherit (revision) rev sha256; 51 | fetchSubmodules = submodules; 52 | } 53 | -------------------------------------------------------------------------------- /repos.json: -------------------------------------------------------------------------------- 1 | { 2 | "repos": { 3 | "0komo": { 4 | "github-contact": "0komo", 5 | "url": "https://github.com/0komo/nurpkgs" 6 | }, 7 | "0x4A6F": { 8 | "github-contact": "0x4A6F", 9 | "url": "https://github.com/0x4A6F/nur-packages" 10 | }, 11 | "1235467": { 12 | "github-contact": "1235467", 13 | "url": "https://github.com/1235467/nurpkgs" 14 | }, 15 | "12Boti": { 16 | "github-contact": "12Boti", 17 | "url": "https://github.com/12Boti/nur" 18 | }, 19 | "7mind": { 20 | "github-contact": "7mind", 21 | "url": "https://github.com/7mind/7mind-nix" 22 | }, 23 | "999eagle": { 24 | "github-contact": "999eagle", 25 | "type": "gitlab", 26 | "url": "https://git.catgirl.cloud/999eagle/nur-packages" 27 | }, 28 | "9glenda": { 29 | "github-contact": "9glenda", 30 | "url": "https://github.com/9glenda/nur-packages" 31 | }, 32 | "Adamekka": { 33 | "github-contact": "Adamekka", 34 | "url": "https://github.com/Adamekka/nur-packages" 35 | }, 36 | "AndrewKvalheim": { 37 | "file": "nur.nix", 38 | "github-contact": "AndrewKvalheim", 39 | "url": "https://codeberg.org/AndrewKvalheim/configuration" 40 | }, 41 | "AsterisMono": { 42 | "github-contact": "AsterisMono", 43 | "url": "https://github.com/AsterisMono/nur-packages" 44 | }, 45 | "DanNixon": { 46 | "github-contact": "DanNixon", 47 | "url": "https://github.com/DanNixon/nur-packages" 48 | }, 49 | "Dev380": { 50 | "github-contact": "Dev380", 51 | "url": "https://github.com/Dev380/nur-repo" 52 | }, 53 | "DimitarNestorov": { 54 | "github-contact": "DimitarNestorov", 55 | "url": "https://github.com/DimitarNestorov/Nix-user-repository-packages" 56 | }, 57 | "Educorreia932": { 58 | "github-contact": "Educorreia932", 59 | "url": "https://github.com/Educorreia932/nur-packages" 60 | }, 61 | "Emin017": { 62 | "github-contact": "Emin017", 63 | "url": "https://github.com/Emin017/nur-packages" 64 | }, 65 | "Ex-32": { 66 | "github-contact": "Ex-32", 67 | "url": "https://github.com/Ex-32/nur-packages" 68 | }, 69 | "Freed-Wu": { 70 | "github-contact": "Freed-Wu", 71 | "url": "https://github.com/Freed-Wu/nur-packages" 72 | }, 73 | "GNUqb114514": { 74 | "github-contact": "GNUqb114514", 75 | "url": "https://github.com/GNUqb114514/nur-packages" 76 | }, 77 | "HeyImKyu": { 78 | "github-contact": "HeyImKyu", 79 | "url": "https://github.com/HeyImKyu/nur-packages" 80 | }, 81 | "INFO4-19": { 82 | "github-contact": "Cosciad", 83 | "type": "gitlab", 84 | "url": "https://gricad-gitlab.univ-grenoble-alpes.fr/Projets-INFO4/18-19/19/code" 85 | }, 86 | "LuisChDev": { 87 | "github-contact": "LuisChDev", 88 | "url": "https://github.com/LuisChDev/nur-packages" 89 | }, 90 | "MH0386": { 91 | "github-contact": "MH0386", 92 | "url": "https://github.com/MH0386/nurpkgs" 93 | }, 94 | "MtFBella109": { 95 | "github-contact": "MtFBella109", 96 | "url": "https://github.com/MtFBella109/nur-packages" 97 | }, 98 | "Nick1296": { 99 | "github-contact": "Nick1296", 100 | "url": "https://github.com/Nick1296/nur-packages" 101 | }, 102 | "NotBalds": { 103 | "github-contact": "NotBalds", 104 | "url": "https://github.com/NotBalds/nurpkgs" 105 | }, 106 | "NotEvenANeko": { 107 | "github-contact": "NotEvenANeko", 108 | "url": "https://github.com/NotEvenANeko/nur-pkgs" 109 | }, 110 | "ProducerMatt": { 111 | "github-contact": "ProducerMatt", 112 | "url": "https://github.com/ProducerMatt/my-nur-pkgs" 113 | }, 114 | "Redrield": { 115 | "github-contact": "Redrield", 116 | "url": "https://github.com/Redrield/nurpkgs" 117 | }, 118 | "Rhys-T": { 119 | "github-contact": "Rhys-T", 120 | "url": "https://github.com/Rhys-T/nur-packages" 121 | }, 122 | "Samuel-Martineau": { 123 | "github-contact": "Samuel-Martineau", 124 | "url": "https://github.com/Samuel-Martineau/nur-packages" 125 | }, 126 | "Sittymin": { 127 | "github-contact": "Sittymin", 128 | "url": "https://github.com/Sittymin/NUR" 129 | }, 130 | "SuperKenVery": { 131 | "github-contact": "SuperKenVery", 132 | "url": "https://github.com/SuperKenVery/nix-user-packages/" 133 | }, 134 | "Vortriz": { 135 | "github-contact": "Vortriz", 136 | "url": "https://github.com/Vortriz/nur-packages" 137 | }, 138 | "YisuiMilena": { 139 | "github-contact": "YisuiDenghua", 140 | "url": "https://github.com/YisuiDenghua/nur-apps" 141 | }, 142 | "Zoneshiyi": { 143 | "github-contact": "Zoneshiyi", 144 | "url": "https://github.com/Zoneshiyi/nur-pkgs" 145 | }, 146 | "aaqaishtyaq": { 147 | "github-contact": "aaqaishtyaq", 148 | "url": "https://github.com/aaqaishtyaq/nur-packages" 149 | }, 150 | "aasg": { 151 | "github-contact": "AluisioASG", 152 | "url": "https://git.sr.ht/~aasg/nixexprs" 153 | }, 154 | "abszero": { 155 | "file": "nur.nix", 156 | "github-contact": "Weathercold", 157 | "url": "https://github.com/Weathercold/nixfiles" 158 | }, 159 | "afreakk": { 160 | "github-contact": "afreakk", 161 | "url": "https://github.com/afreakk/mynixrepo" 162 | }, 163 | "agaia": { 164 | "github-contact": "adam-gaia", 165 | "url": "https://github.com/adam-gaia/nur-packages" 166 | }, 167 | "alanpearce": { 168 | "github-contact": "alanpearce", 169 | "url": "https://git.alanpearce.eu/nix-packages" 170 | }, 171 | "alarsyo": { 172 | "file": "pkgs/default.nix", 173 | "github-contact": "alarsyo", 174 | "url": "https://github.com/alarsyo/nixos-config" 175 | }, 176 | "aleksana": { 177 | "github-contact": "Aleksanaa", 178 | "url": "https://github.com/Aleksanaa/NUR-Aleksana" 179 | }, 180 | "alexnortung": { 181 | "github-contact": "alexnortung", 182 | "url": "https://github.com/alexnortung/nur-alexnortung" 183 | }, 184 | "alwinb": { 185 | "github-contact": "alwinber", 186 | "url": "https://gitlab.com/AlwinB/nur-packages" 187 | }, 188 | "ambroisie": { 189 | "file": "pkgs/default.nix", 190 | "github-contact": "ambroisie", 191 | "url": "https://github.com/ambroisie/nix-config" 192 | }, 193 | "amesgen": { 194 | "github-contact": "amesgen", 195 | "url": "https://github.com/amesgen/nur-packages" 196 | }, 197 | "andreasrid": { 198 | "github-contact": "andreasrid", 199 | "url": "https://github.com/andreasrid/nur-packages" 200 | }, 201 | "angr": { 202 | "github-contact": "Pamplemousse", 203 | "url": "https://github.com/angr/nixpkgs" 204 | }, 205 | "anntnzrb": { 206 | "github-contact": "anntnzrb", 207 | "url": "https://github.com/anntnzrb/nurpkgs" 208 | }, 209 | "anthonyroussel": { 210 | "github-contact": "anthonyroussel", 211 | "url": "https://github.com/anthonyroussel/nur-packages" 212 | }, 213 | "aprilthepink": { 214 | "github-contact": "CutestNekoAqua", 215 | "url": "https://github.com/CutestNekoAqua/nur-repo" 216 | }, 217 | "arc": { 218 | "file": "nur.nix", 219 | "github-contact": "arcnmx", 220 | "url": "https://github.com/arcnmx/nixexprs" 221 | }, 222 | "armaria": { 223 | "github-contact": "JonathanHope", 224 | "url": "https://github.com/JonathanHope/nur-armaria" 225 | }, 226 | "arteneko": { 227 | "github-contact": "Arteneko", 228 | "type": "sourcehut", 229 | "url": "https://git.sr.ht/~artemis/artenekoverlay" 230 | }, 231 | "artturin": { 232 | "github-contact": "artturin", 233 | "url": "https://github.com/Artturin/artturin-nur" 234 | }, 235 | "ataraxiasjel": { 236 | "file": "pkgs/default.nix", 237 | "github-contact": "AtaraxiaSjel", 238 | "url": "https://github.com/AtaraxiaSjel/nur" 239 | }, 240 | "avrahambenaram": { 241 | "github-contact": "avrahambenaram", 242 | "url": "https://github.com/avrahambenaram/nur-packages" 243 | }, 244 | "awl-fcarza": { 245 | "github-contact": "francescocarzaniga", 246 | "url": "https://github.com/francescocarzaniga/awl-fcarza" 247 | }, 248 | "aymanbagabas": { 249 | "github-contact": "aymanbagabas", 250 | "url": "https://github.com/aymanbagabas/nur" 251 | }, 252 | "babariviere": { 253 | "github-contact": "babariviere", 254 | "url": "https://github.com/babariviere/nur-packages" 255 | }, 256 | "badele": { 257 | "github-contact": "badele", 258 | "url": "https://github.com/badele/nur-packages" 259 | }, 260 | "balsoft": { 261 | "github-contact": "balsoft", 262 | "url": "https://github.com/balsoft/nur-packages" 263 | }, 264 | "bandithedoge": { 265 | "github-contact": "bandithedoge", 266 | "url": "https://github.com/bandithedoge/nur-packages" 267 | }, 268 | "bb010g": { 269 | "github-contact": "bb010g", 270 | "url": "https://github.com/bb010g/nur-packages" 271 | }, 272 | "bbjubjub": { 273 | "github-contact": "bbjubjub2494", 274 | "url": "https://github.com/bbjubjub2494/nur-expressions" 275 | }, 276 | "bd-g": { 277 | "github-contact": "bd-g", 278 | "url": "https://github.com/bd-g/nur-packages" 279 | }, 280 | "beam": { 281 | "github-contact": "jechol", 282 | "url": "https://github.com/jechol/nix-beam" 283 | }, 284 | "behoof4mind": { 285 | "github-contact": "behoof4mind", 286 | "url": "https://github.com/behoof4mind/packages" 287 | }, 288 | "bendlas": { 289 | "github-contact": "bendlas", 290 | "url": "https://github.com/bendlas/nur-packages" 291 | }, 292 | "berbiche": { 293 | "github-contact": "berbiche", 294 | "url": "https://github.com/berbiche/nur-packages" 295 | }, 296 | "berryp": { 297 | "github-contact": "berryp", 298 | "url": "https://github.com/berryp/nur-packages" 299 | }, 300 | "bhasherbel": { 301 | "github-contact": "BhasherBEL", 302 | "url": "https://github.com/bhasherbel/nur-packages" 303 | }, 304 | "bhipple": { 305 | "github-contact": "bhipple", 306 | "url": "https://github.com/bhipple/nur-packages" 307 | }, 308 | "binarycat": { 309 | "github-contact": "lolbinarycat", 310 | "url": "https://github.com/lolbinarycat/nur-packages" 311 | }, 312 | "blakat360": { 313 | "github-contact": "blakat360", 314 | "submodules": true, 315 | "url": "https://github.com/blakat360/nur-packages" 316 | }, 317 | "bot-wxt1221": { 318 | "github-contact": "bot-wxt1221", 319 | "url": "https://github.com/Bot-wxt1221/Bot-wxt1221-nur" 320 | }, 321 | "breakingtv": { 322 | "github-contact": "breakingtv", 323 | "url": "https://github.com/BreakingTV/nur-packages" 324 | }, 325 | "brpaz": { 326 | "github-contact": "brpaz", 327 | "url": "https://github.com/brpaz/nur-packages" 328 | }, 329 | "c0deaddict": { 330 | "github-contact": "c0deaddict", 331 | "url": "https://github.com/c0deaddict/nur-packages" 332 | }, 333 | "c2vi": { 334 | "file": "nur.nix", 335 | "github-contact": "c2vi", 336 | "url": "https://github.com/c2vi/nixos" 337 | }, 338 | "caarlos0": { 339 | "github-contact": "caarlos0", 340 | "url": "https://github.com/caarlos0/nur" 341 | }, 342 | "chagra": { 343 | "github-contact": "chagra", 344 | "url": "https://github.com/ihebchagra/nur-packages" 345 | }, 346 | "chap9": { 347 | "github-contact": "chap9", 348 | "url": "https://github.com/chap9/chap9-nur" 349 | }, 350 | "charmbracelet": { 351 | "github-contact": "caarlos0", 352 | "url": "https://github.com/charmbracelet/nur" 353 | }, 354 | "chen": { 355 | "github-contact": "cu1ch3n", 356 | "url": "https://github.com/cu1ch3n/nur-packages" 357 | }, 358 | "cherrypiejam": { 359 | "github-contact": "cherrypiejam", 360 | "url": "https://github.com/cherrypiejam/nur-packages" 361 | }, 362 | "chigyutendies": { 363 | "github-contact": "pillowtrucker", 364 | "url": "https://github.com/pillowtrucker/tooo000oooot" 365 | }, 366 | "chillcicada": { 367 | "github-contact": "chillcicada", 368 | "url": "https://github.com/chillcicada/nurpkgs" 369 | }, 370 | "chisui": { 371 | "github-contact": "chisui", 372 | "url": "https://github.com/chisui/nur-pkgs" 373 | }, 374 | "chordtoll": { 375 | "github-contact": "chordtoll", 376 | "url": "https://github.com/chordtoll/nur-packages" 377 | }, 378 | "chrisoboe": { 379 | "github-contact": "ChrisOboe", 380 | "url": "https://github.com/ChrisOboe/nurrepo" 381 | }, 382 | "clefru": { 383 | "github-contact": "clefru", 384 | "url": "https://github.com/clefru/nur-packages" 385 | }, 386 | "codgician": { 387 | "github-contact": "codgician", 388 | "url": "https://github.com/codgician/nur-packages" 389 | }, 390 | "colinsane": { 391 | "file": "integrations/nur/default.nix", 392 | "github-contact": "uninsane", 393 | "type": "gitea", 394 | "url": "https://git.uninsane.org/colin/nix-files" 395 | }, 396 | "colorman": { 397 | "github-contact": "TheColorman", 398 | "url": "https://github.com/TheColorman/nurpkgs" 399 | }, 400 | "congee": { 401 | "github-contact": "congee", 402 | "url": "https://github.com/congee/nur" 403 | }, 404 | "cransom": { 405 | "github-contact": "cransom", 406 | "url": "https://github.com/cransom/nur-packages" 407 | }, 408 | "crazazy": { 409 | "file": "pkgs/default.nix", 410 | "github-contact": "crazazy", 411 | "url": "https://github.com/crazazy/nixos-config" 412 | }, 413 | "crazedprogrammer": { 414 | "file": "pkgs/nur-packages.nix", 415 | "github-contact": "crazedprogrammer", 416 | "url": "https://github.com/CrazedProgrammer/nix" 417 | }, 418 | "crtified": { 419 | "github-contact": "CRTified", 420 | "url": "https://github.com/CRTified/nur-packages" 421 | }, 422 | "cryolitia": { 423 | "github-contact": "Cryolitia", 424 | "url": "https://github.com/Cryolitia/nur-packages" 425 | }, 426 | "cvtx": { 427 | "github-contact": "cvtx", 428 | "url": "https://github.com/Cvtx/nur-packages" 429 | }, 430 | "cwyc": { 431 | "github-contact": "cwyc", 432 | "submodules": true, 433 | "url": "https://github.com/cwyc/nur-packages" 434 | }, 435 | "cyberleagueaustria": { 436 | "github-contact": "sencrash", 437 | "url": "https://github.com/CyberLeagueAustria/nur-packages" 438 | }, 439 | "dagger": { 440 | "github-contact": "dagger", 441 | "url": "https://github.com/dagger/nix" 442 | }, 443 | "dan4ik605743": { 444 | "github-contact": "dan4ik605743", 445 | "url": "https://github.com/dan4ik605743/nur" 446 | }, 447 | "dandellion": { 448 | "github-contact": "dali99", 449 | "url": "https://git.dodsorf.as/Dandellion/NUR" 450 | }, 451 | "darkkirb": { 452 | "github-contact": "DarkKirb", 453 | "url": "https://git.chir.rs/darkkirb/nix-packages" 454 | }, 455 | "dawidsowa": { 456 | "github-contact": "dawidsowa", 457 | "url": "https://github.com/dawidsowa/nur-packages" 458 | }, 459 | "dcsunset": { 460 | "github-contact": "DCsunset", 461 | "url": "https://github.com/DCsunset/nur-packages" 462 | }, 463 | "deeunderscore": { 464 | "github-contact": "DeeUnderscore", 465 | "url": "https://github.com/DeeUnderscore/nur-packages" 466 | }, 467 | "definfo": { 468 | "github-contact": "definfo", 469 | "url": "https://github.com/definfo/nur-packages" 470 | }, 471 | "demivan": { 472 | "github-contact": "demivan", 473 | "url": "https://github.com/demivan/nur-packages" 474 | }, 475 | "demyanrogozhin": { 476 | "github-contact": "demyanrogozhin", 477 | "url": "https://github.com/demyanrogozhin/nur-packages" 478 | }, 479 | "detegr": { 480 | "github-contact": "Detegr", 481 | "url": "https://github.com/Detegr/nur" 482 | }, 483 | "devins2518": { 484 | "github-contact": "devins2518", 485 | "url": "https://github.com/devins2518/nur" 486 | }, 487 | "devmegablaster": { 488 | "github-contact": "devmegablaster", 489 | "url": "https://github.com/devmegablaster/nur" 490 | }, 491 | "dezgeg": { 492 | "github-contact": "dezgeg", 493 | "url": "https://github.com/dezgeg/nur-packages" 494 | }, 495 | "dguibert": { 496 | "github-contact": "dguibert", 497 | "url": "https://github.com/dguibert/nur-packages" 498 | }, 499 | "divanorama": { 500 | "github-contact": "divanorama", 501 | "url": "https://github.com/divanorama/nur-packages" 502 | }, 503 | "dmayle": { 504 | "github-contact": "dmayle", 505 | "url": "https://github.com/dmayle/nur-packages" 506 | }, 507 | "draftea": { 508 | "github-contact": "dateay", 509 | "url": "https://github.com/Drafteame/nur-packages" 510 | }, 511 | "drewrisinger": { 512 | "github-contact": "drewrisinger", 513 | "url": "https://github.com/drewrisinger/nur-packages" 514 | }, 515 | "dschrempf": { 516 | "github-contact": "dschrempf", 517 | "url": "https://github.com/dschrempf/nur-packages" 518 | }, 519 | "dsuetin": { 520 | "github-contact": "dani0854", 521 | "url": "https://github.com/dani0854/nur-packages" 522 | }, 523 | "dtn7": { 524 | "github-contact": "dtn7", 525 | "url": "https://github.com/dtn7/nur-packages" 526 | }, 527 | "dtomvan": { 528 | "github-contact": "dtomvan", 529 | "url": "https://github.com/dtomvan/nur-packages" 530 | }, 531 | "dtz": { 532 | "github-contact": "dtz", 533 | "url": "https://github.com/dtzWill/nur-packages" 534 | }, 535 | "dukzcry": { 536 | "github-contact": "dukzcry", 537 | "type": "gitlab", 538 | "url": "https://gitlab.com/repos-holder/nur-packages" 539 | }, 540 | "dur": { 541 | "github-contact": "paladhammika", 542 | "url": "https://github.com/paladhammika/dur" 543 | }, 544 | "dustinblackman": { 545 | "github-contact": "dustinblackman", 546 | "url": "https://github.com/dustinblackman/nur-packages" 547 | }, 548 | "dywedir": { 549 | "github-contact": "dywedir", 550 | "url": "https://github.com/dywedir/nur-packages" 551 | }, 552 | "eeva": { 553 | "github-contact": "jpotier", 554 | "type": "gitea", 555 | "url": "https://git.marvid.fr/eeva/nur-packages" 556 | }, 557 | "eggflaw": { 558 | "github-contact": "Eggflaw", 559 | "url": "https://github.com/Eggflaw/nur-packages" 560 | }, 561 | "eh5": { 562 | "branch": "main", 563 | "github-contact": "EHfive", 564 | "url": "https://github.com/EHfive/flakes" 565 | }, 566 | "emiller88": { 567 | "github-contact": "emiller88", 568 | "url": "https://github.com/emiller88/nur-packages" 569 | }, 570 | "endle": { 571 | "github-contact": "Endle", 572 | "url": "https://github.com/Endle/nur-packages" 573 | }, 574 | "eownerdead": { 575 | "github-contact": "eownerdead", 576 | "url": "https://codeberg.org/eownerdead/flakes" 577 | }, 578 | "ethancedwards8": { 579 | "github-contact": "ethancedwards8", 580 | "url": "https://github.com/ethancedwards8/ethancedwards8-nur" 581 | }, 582 | "etu": { 583 | "github-contact": "etu", 584 | "url": "https://github.com/etu/nur-packages" 585 | }, 586 | "extends": { 587 | "github-contact": "ImExtends", 588 | "url": "https://github.com/ImExtends/nur-packages-template" 589 | }, 590 | "falconprogrammer": { 591 | "github-contact": "JonBoyleCoding", 592 | "url": "https://github.com/JonBoyleCoding/falconprogrammer-nur" 593 | }, 594 | "fanbb2333": { 595 | "github-contact": "FanBB2333", 596 | "url": "https://github.com/FanBB2333/nur-packages" 597 | }, 598 | "federicoschonborn": { 599 | "github-contact": "FedericoSchonborn", 600 | "url": "https://codeberg.org/FedericoSchonborn/nur-packages" 601 | }, 602 | "fedx": { 603 | "github-contact": "fedx-sudo", 604 | "url": "https://github.com/FedX-sudo/Nixpkgs_testing_NUR" 605 | }, 606 | "fendse": { 607 | "github-contact": "fendse", 608 | "url": "https://github.com/fendse/nur" 609 | }, 610 | "fgaz": { 611 | "github-contact": "fgaz", 612 | "url": "https://github.com/fgaz/nur-packages" 613 | }, 614 | "fius": { 615 | "github-contact": "neumantm", 616 | "url": "https://github.com/Fius/nur-packages" 617 | }, 618 | "fliegendewurst": { 619 | "github-contact": "FliegendeWurst", 620 | "url": "https://github.com/FliegendeWurst/nur-packages/" 621 | }, 622 | "fooker": { 623 | "github-contact": "fooker", 624 | "url": "https://github.com/fooker/nur-packages" 625 | }, 626 | "foolnotion": { 627 | "github-contact": "foolnotion", 628 | "url": "https://github.com/foolnotion/nur-pkg" 629 | }, 630 | "foresense": { 631 | "github-contact": "foresense", 632 | "url": "https://github.com/foresense/nur-packages" 633 | }, 634 | "fortuneteller2k": { 635 | "github-contact": "fortuneteller2k", 636 | "url": "https://github.com/fortuneteller2k/nur" 637 | }, 638 | "frankoslaw": { 639 | "github-contact": "Frankoslaw", 640 | "url": "https://github.com/Frankoslaw/nur-packages" 641 | }, 642 | "friedow": { 643 | "github-contact": "friedow", 644 | "url": "https://github.com/friedow/nur-packages" 645 | }, 646 | "friendsofshopware": { 647 | "github-contact": "shyim", 648 | "url": "https://github.com/FriendsOfShopware/nur-packages/" 649 | }, 650 | "ftbwiki": { 651 | "github-contact": "tomodachi94", 652 | "url": "https://github.com/tomodachi94/nur-ftbwiki" 653 | }, 654 | "fuyu-no-nur": { 655 | "github-contact": "TahlonBrahic", 656 | "url": "https://github.com/TahlonBrahic/fuyu-no-nur" 657 | }, 658 | "gabr1sr": { 659 | "github-contact": "gabr1sr", 660 | "url": "https://github.com/gabr1sr/nur-packages" 661 | }, 662 | "gbytedev": { 663 | "github-contact": "gbytedev", 664 | "url": "https://github.com/gbytedev/nur-packages" 665 | }, 666 | "genesis": { 667 | "github-contact": "bignaux", 668 | "url": "https://github.com/bignaux/nur-packages" 669 | }, 670 | "geonix": { 671 | "github-contact": "imincik", 672 | "url": "https://github.com/imincik/geonix" 673 | }, 674 | "gepbird": { 675 | "github-contact": "gepbird", 676 | "url": "https://github.com/gepbird/nur-packages" 677 | }, 678 | "ggemre": { 679 | "github-contact": "ggemre", 680 | "url": "https://github.com/ggemre/nur-packages" 681 | }, 682 | "gigamonster256": { 683 | "github-contact": "gigamonster256", 684 | "url": "https://github.com/gigamonster256/nur-packages" 685 | }, 686 | "glostis": { 687 | "github-contact": "glostis", 688 | "url": "https://github.com/glostis/nur-packages" 689 | }, 690 | "goreleaser": { 691 | "github-contact": "caarlos0", 692 | "url": "https://github.com/goreleaser/nur" 693 | }, 694 | "grafcube": { 695 | "github-contact": "Grafcube", 696 | "url": "https://github.com/Grafcube/nur-packages" 697 | }, 698 | "graham33": { 699 | "github-contact": "graham33", 700 | "url": "https://github.com/graham33/nur-packages" 701 | }, 702 | "gricad": { 703 | "github-contact": "gricad", 704 | "url": "https://github.com/Gricad/nur-packages" 705 | }, 706 | "guanran928": { 707 | "github-contact": "Guanran928", 708 | "url": "https://github.com/Guanran928/nur-packages" 709 | }, 710 | "guoard": { 711 | "github-contact": "guoard", 712 | "url": "https://github.com/guoard/nur" 713 | }, 714 | "harukafractus": { 715 | "file": "nur-everything/default.nix", 716 | "github-contact": "harukafractus", 717 | "url": "https://github.com/harukafractus/nix" 718 | }, 719 | "heph2": { 720 | "github-contact": "heph2", 721 | "url": "https://github.com/heph2/nur-packages" 722 | }, 723 | "hhr2020": { 724 | "github-contact": "hhr2020", 725 | "url": "https://github.com/hhr2020/nur-packages" 726 | }, 727 | "htr": { 728 | "github-contact": "htr", 729 | "url": "https://github.com/htr/nur-packages" 730 | }, 731 | "hujw77": { 732 | "github-contact": "hujw77", 733 | "url": "https://github.com/hujw77/nur-packages" 734 | }, 735 | "humxc": { 736 | "github-contact": "HumXC", 737 | "url": "https://github.com/HumXC/nur-packages" 738 | }, 739 | "hutzdog": { 740 | "github-contact": "enderger", 741 | "type": "sourcehut", 742 | "url": "https://git.sr.ht/~hutzdog/NUR" 743 | }, 744 | "iagocq": { 745 | "file": "nur.nix", 746 | "github-contact": "iagocq", 747 | "url": "https://github.com/iagocq/nix" 748 | }, 749 | "ianmurphy1": { 750 | "github-contact": "ianmurphy1", 751 | "url": "https://github.com/ianmurphy1/nurpkgs" 752 | }, 753 | "ifd3f": { 754 | "github-contact": "ifd3f", 755 | "url": "https://github.com/ifd3f/nur-packages" 756 | }, 757 | "ihaveamac": { 758 | "github-contact": "ihaveamac", 759 | "url": "https://github.com/ihaveamac/nur-packages" 760 | }, 761 | "ijohanne": { 762 | "github-contact": "ijohanne", 763 | "url": "https://github.com/ijohanne/nur-packages" 764 | }, 765 | "ilya-fedin": { 766 | "github-contact": "ilya-fedin", 767 | "url": "https://github.com/ilya-fedin/nur-repository" 768 | }, 769 | "immae": { 770 | "github-contact": "immae", 771 | "url": "https://git.immae.eu/perso/Immae/Config/Nix/NUR.git" 772 | }, 773 | "instantos": { 774 | "github-contact": "con-f-use", 775 | "url": "https://github.com/instantOS/nix" 776 | }, 777 | "ionutnechita": { 778 | "github-contact": "ionutnechita", 779 | "url": "https://github.com/ionutnechita/ionutnechita-nur-packages" 780 | }, 781 | "iopq": { 782 | "github-contact": "iopq", 783 | "url": "https://github.com/iopq/nur-packages" 784 | }, 785 | "iuricarras": { 786 | "github-contact": "iuricarras", 787 | "url": "https://github.com/iuricarras/nur-packages" 788 | }, 789 | "ivar": { 790 | "github-contact": "IvarWithoutBones", 791 | "url": "https://github.com/IvarWithoutBones/NUR" 792 | }, 793 | "ixhbinphoenix": { 794 | "github-contact": "ixhbinphoenix", 795 | "url": "https://github.com/ixhbinphoenix/nur-packages" 796 | }, 797 | "izorkin": { 798 | "github-contact": "Izorkin", 799 | "url": "https://github.com/Izorkin/nur-packages" 800 | }, 801 | "j-k": { 802 | "github-contact": "06kellyjac", 803 | "url": "https://github.com/06kellyjac/nur-packages" 804 | }, 805 | "j4ger": { 806 | "github-contact": "j4ger", 807 | "url": "https://github.com/j4ger/nix-packages" 808 | }, 809 | "jakobrs": { 810 | "github-contact": "jakobrs", 811 | "url": "https://github.com/jakobrs/nur-packages" 812 | }, 813 | "javimerino": { 814 | "github-contact": "javimerino", 815 | "url": "https://github.com/JaviMerino/nur-packages" 816 | }, 817 | "jbarthelmes": { 818 | "github-contact": "jbarthelmes", 819 | "url": "https://github.com/jbarthelmes/nur-packages" 820 | }, 821 | "jcs090218": { 822 | "github-contact": "jcs090218", 823 | "url": "https://github.com/jcs090218/nur" 824 | }, 825 | "jdpkgs": { 826 | "github-contact": "jdev082", 827 | "url": "https://github.com/jdev082/jdpkgs" 828 | }, 829 | "jeffguorg": { 830 | "github-contact": "jeffguorg", 831 | "url": "https://github.com/jeffguorg/nur-packages" 832 | }, 833 | "jerrita": { 834 | "github-contact": "jerrita", 835 | "url": "https://github.com/jerrita/nur" 836 | }, 837 | "jitterbug": { 838 | "github-contact": "JuniorIsAJitterbug", 839 | "url": "https://github.com/JuniorIsAJitterbug/nur-packages" 840 | }, 841 | "jj": { 842 | "github-contact": "htngr", 843 | "type": "gitlab", 844 | "url": "https://gitlab.com/jjhr/nur" 845 | }, 846 | "jjjollyjim": { 847 | "github-contact": "jjjollyjim", 848 | "url": "https://github.com/jjjollyjim/nur-repo" 849 | }, 850 | "jleightcap": { 851 | "github-contact": "jleightcap", 852 | "type": "sourcehut", 853 | "url": "https://git.sr.ht/~jleightcap/nur-packages" 854 | }, 855 | "jo1gi": { 856 | "github-contact": "jo1gi", 857 | "url": "https://github.com/jo1gi/nur-packages" 858 | }, 859 | "johnazoidberg": { 860 | "github-contact": "JohnAZoidberg", 861 | "url": "https://github.com/JohnAZoidberg/nur-packages" 862 | }, 863 | "jomik": { 864 | "github-contact": "Jomik", 865 | "url": "https://gitlab.com/jomik/nur-expressions" 866 | }, 867 | "jorsn": { 868 | "github-contact": "jorsn", 869 | "url": "https://github.com/jorsn/nur-packages" 870 | }, 871 | "josh": { 872 | "github-contact": "josh", 873 | "url": "https://github.com/josh/nurpkgs" 874 | }, 875 | "jpts": { 876 | "github-contact": "jpts", 877 | "url": "https://github.com/jpts/nur" 878 | }, 879 | "jpyke3": { 880 | "github-contact": "jpyke3", 881 | "url": "https://github.com/JPyke3/JPyke3-Nur" 882 | }, 883 | "k0ral": { 884 | "github-contact": "k0ral", 885 | "url": "https://github.com/k0ral/nur-packages" 886 | }, 887 | "k3a": { 888 | "github-contact": "k3a", 889 | "url": "https://github.com/k3a/nurpkgs" 890 | }, 891 | "kakkun61": { 892 | "github-contact": "kakkun61", 893 | "url": "https://github.com/kakkun61/nur-packages" 894 | }, 895 | "kalbasit": { 896 | "github-contact": "kalbasit", 897 | "url": "https://github.com/kalbasit/nur-packages" 898 | }, 899 | "kapack": { 900 | "file": "nur.nix", 901 | "github-contact": "augu5te", 902 | "url": "https://github.com/oar-team/nur-kapack" 903 | }, 904 | "kf5grd": { 905 | "github-contact": "kf5grd", 906 | "url": "https://github.com/kf5grd/nur-packages" 907 | }, 908 | "kinzokudev": { 909 | "github-contact": "kinzoku-dev", 910 | "url": "https://github.com/kinzoku-dev/nur-kinzoku" 911 | }, 912 | "kira-bruneau": { 913 | "github-contact": "kira-bruneau", 914 | "url": "https://gitlab.com/kira-bruneau/nur-packages" 915 | }, 916 | "kokakiwi": { 917 | "github-contact": "KokaKiwi", 918 | "url": "https://github.com/KokaKiwi/nur-packages" 919 | }, 920 | "kolloch": { 921 | "github-contact": "kolloch", 922 | "url": "https://github.com/kolloch/nur-packages" 923 | }, 924 | "kongjian520": { 925 | "github-contact": "KongJian520", 926 | "url": "https://github.com/KongJian520/NUR" 927 | }, 928 | "krebs": { 929 | "github-contact": "Lassulus", 930 | "submodules": true, 931 | "url": "https://github.com/krebs/nur-packages" 932 | }, 933 | "kreisys": { 934 | "github-contact": "kreisys", 935 | "submodules": true, 936 | "url": "https://github.com/kreisys/nur-packages" 937 | }, 938 | "kuflierl": { 939 | "github-contact": "kuflierl", 940 | "url": "https://github.com/kuflierl/NUR" 941 | }, 942 | "kugland": { 943 | "github-contact": "kugland", 944 | "submodules": true, 945 | "url": "https://github.com/kugland/nur-packages" 946 | }, 947 | "lambdadog": { 948 | "file": "nur.nix", 949 | "github-contact": "lambdadog", 950 | "url": "https://github.com/lambdadog/nix-extra" 951 | }, 952 | "lcx12901": { 953 | "github-contact": "lcx12901", 954 | "url": "https://github.com/lcx12901/nur-nixpkgs" 955 | }, 956 | "lennis-dev": { 957 | "github-contact": "lennis-dev", 958 | "url": "https://github.com/lennis-dev/nur-packages" 959 | }, 960 | "lheckemann": { 961 | "github-contact": "lheckemann", 962 | "url": "https://github.com/lheckemann/nixwip" 963 | }, 964 | "lightquantum": { 965 | "github-contact": "PhotonQuantum", 966 | "url": "https://github.com/PhotonQuantum/nur-packages" 967 | }, 968 | "linyinfeng": { 969 | "github-contact": "linyinfeng", 970 | "url": "https://github.com/linyinfeng/nur-packages" 971 | }, 972 | "liyangau": { 973 | "github-contact": "liyangau", 974 | "url": "https://github.com/liyangau/nur-packages" 975 | }, 976 | "lschuermann": { 977 | "github-contact": "lschuermann", 978 | "url": "https://github.com/lschuermann/nur-packages" 979 | }, 980 | "lucasew": { 981 | "file": "nur.nix", 982 | "github-contact": "lucasew", 983 | "url": "https://github.com/lucasew/nixcfg" 984 | }, 985 | "lunik1": { 986 | "github-contact": "lunik1", 987 | "url": "https://github.com/lunik1/nur-packages" 988 | }, 989 | "lykos153": { 990 | "github-contact": "Lykos153", 991 | "url": "https://github.com/Lykos153/nur-packages" 992 | }, 993 | "m15a": { 994 | "github-contact": "m15a", 995 | "submodules": true, 996 | "url": "https://github.com/m15a/nur-packages" 997 | }, 998 | "make-42": { 999 | "github-contact": "make-42", 1000 | "url": "https://github.com/make-42/NUR" 1001 | }, 1002 | "makefu": { 1003 | "file": "nur.nix", 1004 | "github-contact": "makefu", 1005 | "url": "https://github.com/makefu/nur-packages" 1006 | }, 1007 | "marsupialgutz": { 1008 | "github-contact": "marsupialgutz", 1009 | "url": "https://github.com/marsupialgutz/nur-pkgs" 1010 | }, 1011 | "marven11": { 1012 | "github-contact": "Marven11", 1013 | "url": "https://github.com/Marven11/nur-packages" 1014 | }, 1015 | "marzipankaiser": { 1016 | "github-contact": "marzipankaiser", 1017 | "url": "https://github.com/marzipankaiser/nur-packages" 1018 | }, 1019 | "materus": { 1020 | "github-contact": "materusPL", 1021 | "url": "https://github.com/materusPL/Nixerus" 1022 | }, 1023 | "matthewbauer": { 1024 | "github-contact": "matthewbauer", 1025 | "url": "https://github.com/matthewbauer/nur-packages" 1026 | }, 1027 | "mcaju": { 1028 | "github-contact": "CajuM", 1029 | "url": "https://github.com/CajuM/nur-packages" 1030 | }, 1031 | "meain": { 1032 | "github-contact": "meain", 1033 | "url": "https://github.com/meain/nur-packages" 1034 | }, 1035 | "mgord9518": { 1036 | "github-contact": "mgord9518", 1037 | "url": "https://github.com/mgord9518/nur" 1038 | }, 1039 | "mhuesch": { 1040 | "github-contact": "mhuesch", 1041 | "url": "https://github.com/mhuesch/nur-packages" 1042 | }, 1043 | "mic92": { 1044 | "github-contact": "Mic92", 1045 | "url": "https://github.com/Mic92/nur-packages" 1046 | }, 1047 | "mich-adams": { 1048 | "github-contact": "mich-adams", 1049 | "url": "https://github.com/mich-adams/nix-packages" 1050 | }, 1051 | "michaelglass": { 1052 | "github-contact": "michaelglass", 1053 | "url": "https://github.com/michaelglass/nur-packages" 1054 | }, 1055 | "mikaelfangel-nur": { 1056 | "github-contact": "MikaelFangel", 1057 | "url": "https://github.com/MikaelFangel/NUR" 1058 | }, 1059 | "mikilio": { 1060 | "github-contact": "Mikilio", 1061 | "url": "https://github.com/Mikilio/nur-packages" 1062 | }, 1063 | "milahu": { 1064 | "github-contact": "milahu", 1065 | "submodules": true, 1066 | "url": "https://github.com/milahu/nur-packages" 1067 | }, 1068 | "minegameYTB": { 1069 | "github-contact": "minegameYTB", 1070 | "url": "https://github.com/minegameYTB/nurpkgs-repo" 1071 | }, 1072 | "minion3665": { 1073 | "github-contact": "minion3665", 1074 | "url": "https://github.com/minion3665/nurpkgs" 1075 | }, 1076 | "misterio": { 1077 | "github-contact": "misterio77", 1078 | "type": "sourcehut", 1079 | "url": "https://git.sr.ht/~misterio/nix-config" 1080 | }, 1081 | "mloeper": { 1082 | "github-contact": "MartinLoeper", 1083 | "url": "https://github.com/MartinLoeper/nur" 1084 | }, 1085 | "mmilata": { 1086 | "github-contact": "mmilata", 1087 | "url": "https://github.com/mmilata/nur-packages" 1088 | }, 1089 | "moaxcp": { 1090 | "github-contact": "moaxcp", 1091 | "url": "https://github.com/moaxcp/nur" 1092 | }, 1093 | "moosingin3space": { 1094 | "github-contact": "moosingin3space", 1095 | "url": "https://github.com/moosingin3space/nur-packages" 1096 | }, 1097 | "moraxyc": { 1098 | "github-contact": "Moraxyc", 1099 | "url": "https://github.com/moraxyc/nur-packages" 1100 | }, 1101 | "moredhel": { 1102 | "github-contact": "moredhel", 1103 | "url": "https://github.com/moredhel/nur-packages" 1104 | }, 1105 | "moredread": { 1106 | "github-contact": "moredread", 1107 | "url": "https://github.com/Moredread/nur-packages" 1108 | }, 1109 | "mozilla": { 1110 | "file": "package-set.nix", 1111 | "github-contact": "tilpner", 1112 | "url": "https://github.com/mozilla/nixpkgs-mozilla" 1113 | }, 1114 | "mpickering": { 1115 | "github-contact": "mpickering", 1116 | "submodules": true, 1117 | "url": "https://github.com/mpickering/nur-packages" 1118 | }, 1119 | "mrVanDalo": { 1120 | "github-contact": "mrVanDalo", 1121 | "url": "https://github.com/mrVanDalo/nur-packages" 1122 | }, 1123 | "mrcpkgs": { 1124 | "github-contact": "mrcjkb", 1125 | "url": "https://github.com/mrcjkb/nur-packages" 1126 | }, 1127 | "mrene": { 1128 | "github-contact": "mrene", 1129 | "url": "https://github.com/mrene/nur-packages" 1130 | }, 1131 | "mrtnvgr": { 1132 | "github-contact": "mrtnvgr", 1133 | "url": "https://github.com/mrtnvgr/nurpkgs" 1134 | }, 1135 | "mur": { 1136 | "github-contact": "duvetfall", 1137 | "url": "https://github.com/duvetfall/mur" 1138 | }, 1139 | "mweinelt": { 1140 | "github-contact": "mweinelt", 1141 | "url": "https://github.com/mweinelt/nur-packages" 1142 | }, 1143 | "n1kolasM": { 1144 | "github-contact": "n1kolasM", 1145 | "url": "https://github.com/n1kolasM/nur-packages" 1146 | }, 1147 | "nagy": { 1148 | "github-contact": "nagy", 1149 | "url": "https://github.com/nagy/nur-packages" 1150 | }, 1151 | "nanamiiiii": { 1152 | "github-contact": "Nanamiiiii", 1153 | "url": "https://github.com/Nanamiiiii/nur" 1154 | }, 1155 | "nasirhm": { 1156 | "github-contact": "nasirhm", 1157 | "url": "https://github.com/nasirhm/nasirhmpkgs" 1158 | }, 1159 | "natsukium": { 1160 | "github-contact": "natsukium", 1161 | "url": "https://github.com/natsukium/nur-packages" 1162 | }, 1163 | "nelonn": { 1164 | "github-contact": "Nelonn", 1165 | "url": "https://github.com/Nelonn/nur-packages" 1166 | }, 1167 | "neumantm": { 1168 | "github-contact": "neumantm", 1169 | "url": "https://github.com/neumantm/nur-packages" 1170 | }, 1171 | "nexromancers": { 1172 | "github-contact": "neXromancers", 1173 | "url": "https://github.com/neXromancers/nixromancers" 1174 | }, 1175 | "nginx": { 1176 | "github-contact": "lucacome", 1177 | "url": "https://github.com/nginxinc/nur" 1178 | }, 1179 | "nikolaizombie1": { 1180 | "github-contact": "nikolaizombie1", 1181 | "url": "https://github.com/nikolaizombie1/nur-packages" 1182 | }, 1183 | "nikpkgs": { 1184 | "github-contact": "nikp123", 1185 | "url": "https://github.com/nikp123/nur-packages" 1186 | }, 1187 | "nim65s": { 1188 | "github-contact": "nim65s", 1189 | "url": "https://github.com/nim65s/nur-packages" 1190 | }, 1191 | "nishimara": { 1192 | "github-contact": "Nishimara", 1193 | "url": "https://github.com/Nishimara/nurpkgs" 1194 | }, 1195 | "nix-data": { 1196 | "github-contact": "Jake-Gillberg", 1197 | "url": "https://github.com/Jake-Gillberg/nix-data" 1198 | }, 1199 | "nix-geht": { 1200 | "github-contact": "vifino", 1201 | "url": "https://github.com/vifino/nix-geht" 1202 | }, 1203 | "nix-swift-packages": { 1204 | "github-contact": "dduan", 1205 | "url": "https://github.com/dduan/nix-swift-packages" 1206 | }, 1207 | "nltch": { 1208 | "github-contact": "nltch", 1209 | "url": "https://github.com/nl-tch/nur-packages" 1210 | }, 1211 | "nnb": { 1212 | "github-contact": "NNBnh", 1213 | "url": "https://github.com/NNBnh/nur-packages" 1214 | }, 1215 | "nolith": { 1216 | "github-contact": "nolith", 1217 | "url": "https://github.com/nolith/nur-packages" 1218 | }, 1219 | "noneucat": { 1220 | "github-contact": "noneucat", 1221 | "url": "https://git.sr.ht/~noneucat/nur-packages" 1222 | }, 1223 | "nousefreak": { 1224 | "github-contact": "NoUseFreak", 1225 | "url": "https://github.com/NoUseFreak/nix-packages" 1226 | }, 1227 | "novafacing": { 1228 | "github-contact": "novafacing", 1229 | "url": "https://github.com/novafacing/nur-packages" 1230 | }, 1231 | "novel2430": { 1232 | "github-contact": "novel2430", 1233 | "url": "https://github.com/novel2430/MyNUR" 1234 | }, 1235 | "npkgs": { 1236 | "github-contact": "NerdyPepper", 1237 | "url": "https://github.com/nerdypepper/npkgs" 1238 | }, 1239 | "nprindle": { 1240 | "github-contact": "nprindle", 1241 | "url": "https://github.com/nprindle/nur-packages" 1242 | }, 1243 | "nuclear06": { 1244 | "github-contact": "nuclear06", 1245 | "url": "https://github.com/nuclear06/NUR" 1246 | }, 1247 | "nukdokplex": { 1248 | "github-contact": "nukdokplex", 1249 | "url": "https://github.com/nukdokplex/nix-packages" 1250 | }, 1251 | "nykma": { 1252 | "github-contact": "nykma", 1253 | "url": "https://github.com/nykma/nur-packages" 1254 | }, 1255 | "ocfox": { 1256 | "github-contact": "ocfox", 1257 | "url": "https://github.com/ocfox/nur-pkgs" 1258 | }, 1259 | "ohheyrj": { 1260 | "github-contact": "ohheyrj", 1261 | "url": "https://github.com/ohheyrj/nur" 1262 | }, 1263 | "oluceps": { 1264 | "github-contact": "oluceps", 1265 | "url": "https://github.com/oluceps/nixos-config" 1266 | }, 1267 | "ondt": { 1268 | "github-contact": "ondt", 1269 | "url": "https://github.com/ondt/nur-packages" 1270 | }, 1271 | "onemoresuza": { 1272 | "github-contact": "onemoresuza", 1273 | "url": "https://github.com/onemoresuza/nur-packages" 1274 | }, 1275 | "onny": { 1276 | "github-contact": "onny", 1277 | "url": "https://git.project-insanity.org/onny/nur-packages" 1278 | }, 1279 | "ossareh": { 1280 | "github-contact": "ossareh", 1281 | "url": "https://github.com/ossareh/nur-packages" 1282 | }, 1283 | "otevrenamesta": { 1284 | "github-contact": "otevrenamesta", 1285 | "url": "https://github.com/otevrenamesta/nur-packages" 1286 | }, 1287 | "ouzu": { 1288 | "github-contact": "ouzu", 1289 | "url": "https://github.com/ouzu/nur-packages" 1290 | }, 1291 | "p3psi": { 1292 | "github-contact": "p3psi-boo", 1293 | "url": "https://github.com/p3psi-boo/p3psi-nur" 1294 | }, 1295 | "pandapip1": { 1296 | "github-contact": "Pandapip1", 1297 | "url": "https://github.com/Pandapip1/nur-packages" 1298 | }, 1299 | "pascalthesing": { 1300 | "github-contact": "pascalthesing", 1301 | "url": "https://github.com/PascalThesing/NUR" 1302 | }, 1303 | "pborzenkov": { 1304 | "github-contact": "pborzenkov", 1305 | "url": "https://github.com/pborzenkov/nur-packages" 1306 | }, 1307 | "peel": { 1308 | "github-contact": "peel", 1309 | "url": "https://github.com/peel/nur-packages" 1310 | }, 1311 | "petrichor": { 1312 | "github-contact": "jezcope", 1313 | "type": "gitea", 1314 | "url": "https://tildegit.org/petrichor/nixexprs" 1315 | }, 1316 | "phandox": { 1317 | "github-contact": "phandox", 1318 | "url": "https://github.com/phandox/nur-packages" 1319 | }, 1320 | "picokeys-nix": { 1321 | "github-contact": "ViZiD", 1322 | "url": "https://github.com/ViZiD/picokeys-nix" 1323 | }, 1324 | "piegames": { 1325 | "github-contact": "piegamesde", 1326 | "url": "https://github.com/piegamesde/nur-packages" 1327 | }, 1328 | "piensa": { 1329 | "github-contact": "piensa", 1330 | "url": "https://github.com/piensa/nur-packages" 1331 | }, 1332 | "plabadens": { 1333 | "github-contact": "plabadens", 1334 | "url": "https://github.com/plabadens/nur-packages" 1335 | }, 1336 | "pn": { 1337 | "github-contact": "pniedzwiedzinski", 1338 | "url": "https://github.com/pniedzwiedzinski/pnpkgs" 1339 | }, 1340 | "pokon548": { 1341 | "github-contact": "pokon548", 1342 | "url": "https://github.com/pokon548/nur-packages" 1343 | }, 1344 | "presto8": { 1345 | "github-contact": "presto8", 1346 | "url": "https://github.com/presto8/nur-packages" 1347 | }, 1348 | "priegger": { 1349 | "file": "nur.nix", 1350 | "github-contact": "priegger", 1351 | "url": "https://git.sr.ht/~priegger/nur-packages" 1352 | }, 1353 | "progsyn": { 1354 | "github-contact": "mistzzt", 1355 | "url": "https://github.com/mistzzt/program-synthesis-nur" 1356 | }, 1357 | "propheci": { 1358 | "github-contact": "akshettrj", 1359 | "url": "https://github.com/Propheci/NixUR" 1360 | }, 1361 | "ps": { 1362 | "github-contact": "patryk-s", 1363 | "url": "https://github.com/patryk-s/nur-packages" 1364 | }, 1365 | "pschuprikov": { 1366 | "github-contact": "pschuprikov", 1367 | "url": "https://github.com/pschuprikov/nur-packages" 1368 | }, 1369 | "psiquo": { 1370 | "github-contact": "psiquo", 1371 | "url": "https://github.com/psiquo/nur-derivations" 1372 | }, 1373 | "ptival": { 1374 | "github-contact": "Ptival", 1375 | "url": "https://github.com/Ptival/nur-packages" 1376 | }, 1377 | "qchem": { 1378 | "file": "nur.nix", 1379 | "github-contact": "markuskowa", 1380 | "url": "https://github.com/markuskowa/NixOS-QChem" 1381 | }, 1382 | "qenya": { 1383 | "github-contact": "qenya", 1384 | "url": "https://github.com/qenya/nur-packages" 1385 | }, 1386 | "qwbarch": { 1387 | "github-contact": "qwbarch", 1388 | "url": "https://github.com/qwbarch/nur-packages" 1389 | }, 1390 | "raizyr": { 1391 | "github-contact": "raizyr", 1392 | "url": "https://github.com/raizyr/nur-packages" 1393 | }, 1394 | "rconan": { 1395 | "github-contact": "riconnon", 1396 | "url": "https://gitlab.com/rconan/nix-packages" 1397 | }, 1398 | "redpz": { 1399 | "github-contact": "reDpz", 1400 | "url": "https://github.com/reDpz/nur-packages" 1401 | }, 1402 | "reedrw": { 1403 | "github-contact": "reedrw", 1404 | "url": "https://github.com/reedrw/nur-packages" 1405 | }, 1406 | "rencire": { 1407 | "github-contact": "rencire", 1408 | "submodules": true, 1409 | "url": "https://github.com/rencire/nur-packages" 1410 | }, 1411 | "renesat": { 1412 | "github-contact": "renesat", 1413 | "url": "https://github.com/renesat/nur-renesat" 1414 | }, 1415 | "reward": { 1416 | "github-contact": "rewardenv", 1417 | "url": "https://github.com/rewardenv/nur" 1418 | }, 1419 | "rewine": { 1420 | "github-contact": "rewine", 1421 | "url": "https://github.com/wineee/nur-packages" 1422 | }, 1423 | "robertodr": { 1424 | "github-contact": "robertodr", 1425 | "url": "https://github.com/robertodr/nur-packages" 1426 | }, 1427 | "robinovitch61": { 1428 | "github-contact": "robinovitch61", 1429 | "url": "https://github.com/robinovitch61/nur-packages" 1430 | }, 1431 | "rseops": { 1432 | "github-contact": "vsoch", 1433 | "url": "https://github.com/rse-ops/nix" 1434 | }, 1435 | "ruixi-rebirth": { 1436 | "github-contact": "ruixi-rebirth", 1437 | "url": "https://github.com/Ruixi-rebirth/nur-packages" 1438 | }, 1439 | "rummik": { 1440 | "github-contact": "rummik", 1441 | "url": "https://gitlab.com/rummik/nixos/nur-packages" 1442 | }, 1443 | "running-grass": { 1444 | "github-contact": "running-grass", 1445 | "url": "https://github.com/running-grass/nur-packages" 1446 | }, 1447 | "rutherther": { 1448 | "github-contact": "Rutherther", 1449 | "url": "https://github.com/Rutherther/nur-pkgs" 1450 | }, 1451 | "ryan4yin": { 1452 | "github-contact": "ryan4yin", 1453 | "url": "https://github.com/ryan4yin/nur-packages" 1454 | }, 1455 | "rycee": { 1456 | "github-contact": "rycee", 1457 | "url": "https://gitlab.com/rycee/nur-expressions" 1458 | }, 1459 | "sagikazarmark": { 1460 | "github-contact": "sagikazarmark", 1461 | "url": "https://github.com/sagikazarmark/nur-packages" 1462 | }, 1463 | "schmittlauch": { 1464 | "github-contact": "schmittlauch", 1465 | "url": "https://github.com/schmittlauch/nur-packages" 1466 | }, 1467 | "sebrut": { 1468 | "github-contact": "sebrut", 1469 | "url": "https://github.com/SebRut/personal-nix-packages-repository" 1470 | }, 1471 | "sehqlr": { 1472 | "github-contact": "github", 1473 | "url": "https://github.com/sehqlr/nur-packages" 1474 | }, 1475 | "serpent213": { 1476 | "github-contact": "serpent213", 1477 | "url": "https://github.com/serpent213/nur-packages" 1478 | }, 1479 | "setser": { 1480 | "github-contact": "SeTSeR", 1481 | "url": "https://github.com/SeTSeR/nur-packages" 1482 | }, 1483 | "sgo": { 1484 | "github-contact": "stigtsp", 1485 | "url": "https://github.com/stigtsp/nur" 1486 | }, 1487 | "shackra": { 1488 | "github-contact": "shackra", 1489 | "url": "https://github.com/shackra/nur" 1490 | }, 1491 | "shados": { 1492 | "github-contact": "Shados", 1493 | "url": "https://github.com/Shados/nur-packages" 1494 | }, 1495 | "shadowrz": { 1496 | "github-contact": "ShadowRZ", 1497 | "url": "https://github.com/ShadowRZ/nur-packages" 1498 | }, 1499 | "shamilton": { 1500 | "github-contact": "SCOTT-HAMILTON", 1501 | "url": "https://github.com/SCOTT-HAMILTON/nur-packages" 1502 | }, 1503 | "sigprof": { 1504 | "github-contact": "sigprof", 1505 | "url": "https://github.com/sigprof/nur-packages" 1506 | }, 1507 | "sikmir": { 1508 | "github-contact": "sikmir", 1509 | "url": "https://github.com/sikmir/nur-packages" 1510 | }, 1511 | "skiletro": { 1512 | "github-contact": "skiletro", 1513 | "url": "https://github.com/skiletro/nur-repo" 1514 | }, 1515 | "sky": { 1516 | "github-contact": "SkyLeite", 1517 | "url": "https://github.com/SkyLeite/nix-repository" 1518 | }, 1519 | "slaier": { 1520 | "github-contact": "slaier", 1521 | "url": "https://github.com/slaier/nixos-config" 1522 | }, 1523 | "smaret": { 1524 | "github-contact": "smaret", 1525 | "url": "https://github.com/smaret/nur-packages" 1526 | }, 1527 | "sn0wm1x": { 1528 | "github-contact": "kwaa", 1529 | "url": "https://github.com/sn0wm1x/ur" 1530 | }, 1531 | "some-pkgs": { 1532 | "github-contact": "SomeoneSerge", 1533 | "url": "https://github.com/SomeoneSerge/pkgs" 1534 | }, 1535 | "sondr3": { 1536 | "github-contact": "sondr3", 1537 | "url": "https://github.com/sondr3/nix-expressions" 1538 | }, 1539 | "souxd": { 1540 | "github-contact": "souxd", 1541 | "url": "https://github.com/souxd/souxd-nur" 1542 | }, 1543 | "spitzeqc": { 1544 | "github-contact": "spitzeqc", 1545 | "url": "https://github.com/spitzeqc/nur-packages" 1546 | }, 1547 | "splintah": { 1548 | "github-contact": "SCOTT-HAMILTON", 1549 | "url": "https://github.com/splintah/nurpkgs" 1550 | }, 1551 | "stupremee": { 1552 | "github-contact": "stupremee", 1553 | "url": "https://github.com/Stupremee/nur-packages" 1554 | }, 1555 | "suhr": { 1556 | "github-contact": "suhr", 1557 | "url": "https://github.com/suhr/nur-packages" 1558 | }, 1559 | "syberant": { 1560 | "github-contact": "syberant", 1561 | "url": "https://github.com/syberant/nur-packages" 1562 | }, 1563 | "tarantoj": { 1564 | "github-contact": "tarantoj", 1565 | "url": "https://github.com/tarantoj/nur-packages" 1566 | }, 1567 | "tehplague": { 1568 | "github-contact": "tehplague", 1569 | "url": "https://github.com/tehplague/NUR" 1570 | }, 1571 | "thaumy": { 1572 | "github-contact": "Thaumy", 1573 | "submodules": true, 1574 | "url": "https://github.com/Thaumy/nur-pkgs" 1575 | }, 1576 | "tilpner": { 1577 | "github-contact": "tilpner", 1578 | "url": "https://github.com/tilpner/nur-packages" 1579 | }, 1580 | "timsueberkrueb": { 1581 | "github-contact": "timsueberkrueb", 1582 | "url": "https://github.com/timsueberkrueb/nur-packages" 1583 | }, 1584 | "tinybeachthor": { 1585 | "github-contact": "tinybeachthor", 1586 | "url": "https://github.com/tinybeachthor/nur-packages" 1587 | }, 1588 | "tokudan": { 1589 | "github-contact": "tokudan", 1590 | "url": "https://github.com/tokudan/nur" 1591 | }, 1592 | "tomberek": { 1593 | "github-contact": "tomberek", 1594 | "url": "https://github.com/tomberek/nur-packages" 1595 | }, 1596 | "tonywu20": { 1597 | "github-contact": "TonyWu20", 1598 | "url": "https://github.com/TonyWu20/nur-packages" 1599 | }, 1600 | "toonn": { 1601 | "github-contact": "toonn", 1602 | "url": "https://github.com/toonn/nur-packages" 1603 | }, 1604 | "tox": { 1605 | "github-contact": "suhr", 1606 | "url": "https://github.com/tox-rs/nur-tox" 1607 | }, 1608 | "toyvo": { 1609 | "github-contact": "ToyVo", 1610 | "url": "https://github.com/ToyVo/nur-packages" 1611 | }, 1612 | "trevorriles": { 1613 | "github-contact": "trevorriles", 1614 | "url": "https://github.com/trevorriles/nur-packages" 1615 | }, 1616 | "tuckershea": { 1617 | "github-contact": "NoRePercussions", 1618 | "url": "https://github.com/tuckershea/nur-packages" 1619 | }, 1620 | "twistoy": { 1621 | "github-contact": "TwIStOy", 1622 | "url": "https://github.com/TwIStOy/nur-packages" 1623 | }, 1624 | "twogn": { 1625 | "github-contact": "2gn", 1626 | "url": "https://github.com/2gn/nur-package" 1627 | }, 1628 | "uleenucks": { 1629 | "github-contact": "uleenucks", 1630 | "url": "https://github.com/uleenucks/nurpkgs" 1631 | }, 1632 | "uniquepointer": { 1633 | "github-contact": "uniquepointer", 1634 | "url": "https://github.com/uniquepointer/nur-babies" 1635 | }, 1636 | "utybo": { 1637 | "github-contact": "utybo", 1638 | "url": "https://github.com/utybo/NUR" 1639 | }, 1640 | "vanilla": { 1641 | "github-contact": "VergeDX", 1642 | "url": "https://github.com/VergeDX/nur-packages" 1643 | }, 1644 | "vdemeester": { 1645 | "file": "pkgs/default.nix", 1646 | "github-contact": "vdemeester", 1647 | "url": "https://gitlab.com/vdemeester/home" 1648 | }, 1649 | "vizqq": { 1650 | "github-contact": "ViZiD", 1651 | "url": "https://github.com/ViZiD/nur-vizqq" 1652 | }, 1653 | "vojtechstep": { 1654 | "github-contact": "vojtechstep", 1655 | "url": "https://github.com/VojtechStep/vspkgs" 1656 | }, 1657 | "vroad": { 1658 | "github-contact": "vroad", 1659 | "url": "https://github.com/vroad/nur-packages" 1660 | }, 1661 | "vsoch": { 1662 | "github-contact": "vsoch", 1663 | "url": "https://github.com/vsoch/nix" 1664 | }, 1665 | "wamserma": { 1666 | "github-contact": "wamserma", 1667 | "url": "https://github.com/wamserma/nur-packages" 1668 | }, 1669 | "weirdpkgs": { 1670 | "github-contact": "weirdrock", 1671 | "url": "https://github.com/weirdrock/weirdpkgs" 1672 | }, 1673 | "wenjinnn": { 1674 | "github-contact": "wenjinnn", 1675 | "url": "https://github.com/wenjinnn/nur-packages" 1676 | }, 1677 | "whs": { 1678 | "github-contact": "whs", 1679 | "url": "https://github.com/whs/nix" 1680 | }, 1681 | "willbou1": { 1682 | "github-contact": "willbou1", 1683 | "url": "https://github.com/willbou1/nur-packages" 1684 | }, 1685 | "willpower3309": { 1686 | "github-contact": "willpower3309", 1687 | "url": "https://github.com/WillPower3309/nur-packages" 1688 | }, 1689 | "wingej0": { 1690 | "github-contact": "wingej0", 1691 | "url": "https://github.com/wingej0/nur-packages" 1692 | }, 1693 | "wolfangaukang": { 1694 | "github-contact": "WolfangAukang", 1695 | "url": "https://codeberg.org/wolfangaukang/nix-agordoj.git" 1696 | }, 1697 | "wrvsrx": { 1698 | "github-contact": "wrvsrx", 1699 | "url": "https://github.com/wrvsrx/nur-packages" 1700 | }, 1701 | "wwmoraes": { 1702 | "github-contact": "wwmoraes", 1703 | "url": "https://github.com/wwmoraes/nurpkgs" 1704 | }, 1705 | "wyzdwdz": { 1706 | "github-contact": "wyzdwdz", 1707 | "url": "https://github.com/wyzdwdz/nur-pkgs" 1708 | }, 1709 | "xddxdd": { 1710 | "github-contact": "xddxdd", 1711 | "url": "https://github.com/xddxdd/nur-packages" 1712 | }, 1713 | "xe": { 1714 | "github-contact": "Xe", 1715 | "url": "https://github.com/Xe/xepkgs" 1716 | }, 1717 | "xeals": { 1718 | "github-contact": "xeals", 1719 | "url": "https://github.com/xeals/nur-packages" 1720 | }, 1721 | "xfix": { 1722 | "github-contact": "xfix", 1723 | "url": "https://github.com/xfix/nur-packages" 1724 | }, 1725 | "xonsh-xontribs": { 1726 | "github-contact": "drmikecrowe", 1727 | "url": "https://github.com/drmikecrowe/nur-packages" 1728 | }, 1729 | "xyenon": { 1730 | "github-contact": "XYenon", 1731 | "url": "https://github.com/XYenon/nur-packages" 1732 | }, 1733 | "yellowonion": { 1734 | "github-contact": "yellowonion", 1735 | "url": "https://github.com/yellowonion/nur-bcachefs" 1736 | }, 1737 | "yes": { 1738 | "github-contact": "SamLukeYes", 1739 | "url": "https://github.com/SamLukeYes/nix-custom-packages" 1740 | }, 1741 | "ymstnt": { 1742 | "github-contact": "ymstnt", 1743 | "url": "https://github.com/ymstnt/nur-packages" 1744 | }, 1745 | "ysndr": { 1746 | "github-contact": "ysndr", 1747 | "url": "https://github.com/ysndr/nur-packages" 1748 | }, 1749 | "yyy": { 1750 | "github-contact": "sinofp", 1751 | "url": "https://github.com/sinofp/nur" 1752 | }, 1753 | "zachcoyle": { 1754 | "github-contact": "zachcoyle", 1755 | "url": "https://github.com/zachcoyle/nur-packages" 1756 | }, 1757 | "zeratax": { 1758 | "github-contact": "ZerataX", 1759 | "url": "https://github.com/ZerataX/nur-packages" 1760 | }, 1761 | "zimeg": { 1762 | "github-contact": "zimeg", 1763 | "url": "https://github.com/zimeg/nur-packages" 1764 | }, 1765 | "zsien": { 1766 | "github-contact": "zsien", 1767 | "url": "https://github.com/zsien/nur-packages" 1768 | }, 1769 | "zzzsy": { 1770 | "file": "parts/nur.nix", 1771 | "github-contact": "zzzsyyy", 1772 | "url": "https://github.com/zzzsyyy/flakes" 1773 | } 1774 | } 1775 | } 1776 | --------------------------------------------------------------------------------