├── .reuse └── dep5 ├── LICENSES └── CC0-1.0.txt ├── README.md ├── flake.lock ├── flake.lock.license ├── flake.nix ├── lib ├── default.nix ├── mkProfile.nix ├── mkTemplates.nix └── pin.nix └── templates ├── default └── flake.nix └── no-flake ├── README.md ├── default.nix ├── gridlock.json └── gridlock.json.license /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: flakey-profile 3 | Upstream-Contact: Jade Lovelace <> 4 | Source: https://github.com/lf-/flakey-profile 5 | 6 | # Sample paragraph, commented out: 7 | # 8 | # Files: src/* 9 | # Copyright: $YEAR $NAME <$CONTACT> 10 | # License: ... 11 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # flakey-profile 8 | 9 | This is a trivial tool to create declarative profiles with Nix flakes. This is 10 | achieved with the same mechanisms as used by home-manager and NixOS: `nix-env 11 | --set`, `nix-env --list-generations`, and `nix-env --rollback`. 12 | 13 | The purpose of this tool is that people stop stubbing their toes on `nix 14 | profile` and `nix-env` for non-declarative uses on non-NixOS systems by 15 | providing a declarative alternative using flakes to pin versions of things. 16 | 17 | ## Non-goals 18 | 19 | - Support `nix profile list` as [complained about 20 | here](https://discourse.nixos.org/t/transitioning-from-imperative-to-declarative-package-management-with-nix-alone/28728#disadvantages-18). 21 | We are in favour of the removal of `nix profile` from the Nix codebase in 22 | lieu of stabilization. 23 | - Compatibility with imperative package management: there is no clear way to 24 | share a profile with an imperative setup. 25 | 26 | We might write a migration script in the future that takes `nix profile list 27 | --json` and converts it into a flake. 28 | - Do similar things to home-manager for services or other things. This is just 29 | a replacement for `nix-env` and `nix profile` and nothing more. 30 | 31 | ## Related work 32 | 33 | - [home-mangler](https://github.com/home-mangler/home-mangler), which uses 34 | a few hundred lines of Rust to wrangle `nix profile` into having exactly the 35 | expected packages installed. Their approach makes `nix profile list` work. By 36 | comparison, this project consists of two lines of shell script that bypass 37 | `nix profile` altogether. 38 | - [nixos-rebuild](https://github.com/nixos/nixpkgs/blob/cc625486c48890c37ced7759727c51dd17d20fd3/pkgs/os-specific/linux/nixos-rebuild/nixos-rebuild.sh#L608), 39 | which uses the same methods to achieve its goals. 40 | - [home-manager](https://github.com/nix-community/home-manager/blob/8765d4e38aa0be53cdeee26f7386173e6c65618d/modules/files.nix#L272) 41 | which is implemented via inexplicable cursed crimes for `nix profile` or the 42 | same method as this otherwise. 43 | - [Flakes as a unified format for profiles](https://discourse.nixos.org/t/flakes-as-a-unified-format-for-profiles/29476) 44 | - [Stop Using nix-env](https://stop-using-nix-env.privatevoid.net/) 45 | 46 | ## Usage 47 | 48 | To use it, see the template in `templates/default`, or included below, or run: 49 | 50 | ``` 51 | nix flake init -t github:lf-/flakey-profile#templates.default 52 | ``` 53 | 54 | Flake example: 55 | 56 | ```nix 57 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 58 | # 59 | # SPDX-License-Identifier: CC0-1.0 60 | 61 | { 62 | description = "Basic usage of flakey-profile"; 63 | 64 | inputs = { 65 | flakey-profile.url = "github:lf-/flakey-profile"; 66 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 67 | flake-utils.url = "github:numtide/flake-utils"; 68 | }; 69 | 70 | outputs = { self, nixpkgs, flake-utils, flakey-profile }: 71 | flake-utils.lib.eachDefaultSystem (system: 72 | let 73 | pkgs = import nixpkgs { 74 | inherit system; 75 | }; 76 | in 77 | { 78 | # Any extra arguments to mkProfile are forwarded directly to pkgs.buildEnv. 79 | # 80 | # Usage: 81 | # Switch to this flake: 82 | # nix run .#profile.switch 83 | # Revert a profile change (note: does not revert pins): 84 | # nix run .#profile.rollback 85 | # Build, without switching: 86 | # nix build .#profile 87 | # Pin nixpkgs in the flake registry and in NIX_PATH, so that 88 | # `nix run nixpkgs#hello` and `nix-shell -p hello --run hello` will 89 | # resolve to the same hello as below [should probably be run as root, see README caveats]: 90 | # sudo nix run .#profile.pin 91 | packages.profile = flakey-profile.lib.mkProfile { 92 | inherit pkgs; 93 | # Specifies things to pin in the flake registry and in NIX_PATH. 94 | pinned = { nixpkgs = toString nixpkgs; }; 95 | paths = with pkgs; [ 96 | hello 97 | ]; 98 | }; 99 | }); 100 | } 101 | ``` 102 | 103 | Then, use the following commands to do things with the new profile: 104 | 105 | ### Build the profile and switch to it 106 | 107 | ``` 108 | nix run .#profile.switch 109 | ``` 110 | 111 | ### Revert a profile change 112 | 113 | > **Warning**: This does not rollback the actions of `profile.pin`. To roll 114 | > that back, revert to the previous version of the profile using a version 115 | > control system and run `profile.pin` again. 116 | 117 | ``` 118 | nix run .#profile.rollback 119 | ``` 120 | 121 | ### Build, without switching 122 | 123 | ``` 124 | nix build .#profile 125 | ``` 126 | 127 | ### Update package versions 128 | 129 | ``` 130 | nix flake lock --update-input nixpkgs 131 | ``` 132 | 133 | or 134 | 135 | ``` 136 | nix flake update 137 | ``` 138 | 139 | then 140 | 141 | ``` 142 | nix run .#profile.switch 143 | ``` 144 | 145 | ### Pin nixpkgs in the [flake registry] and in [`NIX_PATH`][nix_path_proc] 146 | 147 | This makes `nix run nixpkgs#hello` and `nix-shell -p hello --run hello` give 148 | you the same `hello` as if you listed it in your profile. 149 | 150 | > [!IMPORTANT] 151 | > We recommend only running this command as root, since by default the only 152 | > channels used are on root's profile, and are used for `nix upgrade-nix` and 153 | > other uses of nix as root. 154 | 155 | > [!WARNING] 156 | > This does not support revert internally; see below for more 157 | > details. To revert pinning, use source control to get the previous version of 158 | > the profile and run the pinning operation again. 159 | 160 | ``` 161 | nix run .#profile.pin 162 | ``` 163 | 164 | #### Context 165 | 166 | The [flake registry] is used to resolve unqualified flake names such as 167 | `nixpkgs` in `nix run nixpkgs#hello`, and can be overridden on a per-user or 168 | system-wide basis. `NIX_PATH` is used to resolve `` and other 169 | references in angle brackets, and if not present, [this 170 | procedure][nix_path_proc] is used. By running `profile.pin`, both the flake 171 | registry and the channel of the running user will be overridden to point to the 172 | `nixpkgs` you used to build your profile. 173 | 174 | [flake registry]: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-registry.html#registry-format 175 | [nix_path_proc]: https://nixos.org/manual/nix/stable/command-ref/env-common.html#env-NIX_PATH 176 | 177 | > [!NOTE] 178 | > We don't provide an easy way of rolling back a pin, since the Nix 179 | > flake registry is not managed with profiles and the semantics of keeping 180 | > everything in sync when reverting don't really work out. We suggest rolling 181 | > back pins by reverting to the previous version in your preferred version 182 | > control system, then rerunning `pin`. 183 | > 184 | > In a different implementation, we would just use an activation script to 185 | > achieve this the same way as NixOS and home-manager, however, that conflicts 186 | > with the goals of this project. 187 | > 188 | > If it is useful to fixing a system, the things changed are in `~/.config/nix/registry.json` 189 | > (`/etc/nix/registry.json` if run as root), and linked to from 190 | > `~/.nix-defexpr/`. Channels can be rolled back with 191 | > `nix-env --profile $(readlink ~/.nix-defexpr/channels) --rollback` 192 | > or for root, `sudo nix-env --profile $(readlink ~/.nix-defexpr/channels_root) --rollback`. 193 | > The former, not much can be done about, and it's probably easiest to just 194 | > delete the `registry.json` if it's broken. 195 | 196 | 197 | ## Common problems 198 | 199 | It seems that often people run into an issue where 200 | `/nix/var/nix/profiles/per-user/$USER` does not exist. If this is the case, you 201 | can simply `sudo mkdir -p /nix/var/nix/profiles/per-user/$USER && sudo chown 202 | $USER /nix/var/nix/profiles/per-user/$USER`. Or, alternatively, `nix-env -f 203 | '' -iA hello` might fix it, but if it does not, try the other one. 204 | 205 | This has so far been observed on macOS, however we are unsure if this is a Mac 206 | only bug. 207 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "root": {} 4 | }, 5 | "root": "root", 6 | "version": 7 7 | } 8 | -------------------------------------------------------------------------------- /flake.lock.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | 3 | SPDX-License-Identifier: CC0-1.0 4 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | { 6 | description = "Declaratively manage your installed software with flakes"; 7 | 8 | outputs = { self }: 9 | { 10 | lib = import ./lib; 11 | templates = import ./lib/mkTemplates.nix [ 12 | ./templates/default 13 | ./templates/no-flake 14 | ]; 15 | }; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /lib/default.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | { 6 | mkProfile = import ./mkProfile.nix; 7 | } 8 | -------------------------------------------------------------------------------- /lib/mkProfile.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | # Creates a profile. Arguments are forwarded to pkgs.buildEnv. 6 | # 7 | # The following attributes are available: 8 | # - .switch: switches to the profile 9 | # - .rollback: rolls back to the previous version of the profile 10 | args @ { 11 | # nixpkgs to use 12 | pkgs 13 | , # Name of the profile, which appears in the Nix store path of the result 14 | name ? "flake-profile" 15 | , # Items to pin in the flake registry and NIX_PATH, such that they're seen by 16 | # `nix run nixpkgs#hello` and `nix-shell -p hello --run hello`. 17 | pinned ? { } 18 | , # Extra arguments given when switching profiles (n.b. not shell escaped). 19 | extraSwitchArgs ? [ ] 20 | , ... 21 | }: 22 | let 23 | args' = builtins.removeAttrs args [ "pkgs" "pinned" "extraSwitchArgs" ]; 24 | pins = import ./pin.nix { inherit pkgs pinned; }; 25 | 26 | env = pkgs.buildEnv (args' // { 27 | inherit name; 28 | }); 29 | in 30 | env // { 31 | switch = pkgs.writeShellScriptBin "switch" '' 32 | nix-env --set ${env} ${toString extraSwitchArgs} "$@" 33 | ''; 34 | rollback = pkgs.writeShellScriptBin "rollback" '' 35 | nix-env --rollback ${toString extraSwitchArgs} "$@" 36 | ''; 37 | 38 | # pass through pins, so you can e.g. nix build .#profile.pins.channels 39 | inherit pins; 40 | # This script pins any of the items in "pinned" in both the flake registry 41 | # and the nix channels, such that `nix run nixpkgs#hello` and 42 | # `nix-shell -p hello --run hello` will hit the same nixpkgs as is used in 43 | # the declarative profile. 44 | # 45 | # It is not really possible to cleanly roll this back in terms of the flake 46 | # registry, so we suggest just reverting with git in that case. 47 | pin = pkgs.writeShellScriptBin "pin" '' 48 | if [[ $UID == 0 ]]; then 49 | ${pins.pinFlakes { isRoot = true; }} 50 | else 51 | ${pins.pinFlakes { isRoot = false; }} 52 | fi 53 | nix-env --profile /nix/var/nix/profiles/per-user/$USER/channels --set ${pins.channels} 54 | ''; 55 | } 56 | -------------------------------------------------------------------------------- /lib/mkTemplates.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | templates: 6 | builtins.listToAttrs ( 7 | builtins.map 8 | (template: 9 | let flakePath = template + "/flake.nix"; 10 | in 11 | { 12 | name = builtins.baseNameOf template; 13 | value = 14 | { 15 | path = template; 16 | description = if builtins.pathExists flakePath then (import flakePath).description else "(no flake file)"; 17 | }; 18 | }) 19 | templates) 20 | -------------------------------------------------------------------------------- /lib/pin.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | { pkgs, pinned ? { } }: 6 | let 7 | inherit (pkgs) lib; 8 | pathOk = item: builtins.match ".*-source$" (toString item) != null; 9 | pathChecked = name: item: pkgs.lib.assertMsg (pathOk item) '' 10 | Flake registry pin item path must end with -source, due to https://github.com/NixOS/nix/issues/7075. 11 | Name: ${name} 12 | Path: ${toString item} 13 | 14 | Consider pinning nixpkgs with `builtins.fetchTarball` with `name` set to "source". 15 | ''; 16 | 17 | pins = builtins.mapAttrs (name: value: assert pathChecked name value; value) pinned; 18 | in 19 | { 20 | inherit pins; 21 | channels = pkgs.linkFarm "user-environment" pins; 22 | pinFlakes = { isRoot }: 23 | lib.concatMapStringsSep "\n" 24 | (name: "nix registry pin ${lib.optionalString isRoot "--registry /etc/nix/registry.json"} --override-flake ${name} ${pins.${name}} ${name}") 25 | (builtins.attrNames pins); 26 | } 27 | -------------------------------------------------------------------------------- /templates/default/flake.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | { 6 | description = "Basic usage of flakey-profile"; 7 | 8 | inputs = { 9 | flakey-profile.url = "github:lf-/flakey-profile"; 10 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 11 | flake-utils.url = "github:numtide/flake-utils"; 12 | }; 13 | 14 | outputs = { self, nixpkgs, flake-utils, flakey-profile }: 15 | flake-utils.lib.eachDefaultSystem (system: 16 | let 17 | pkgs = import nixpkgs { 18 | inherit system; 19 | }; 20 | in 21 | { 22 | # Any extra arguments to mkProfile are forwarded directly to pkgs.buildEnv. 23 | # 24 | # Usage: 25 | # Switch to this flake: 26 | # nix run .#profile.switch 27 | # Revert a profile change (note: does not revert pins): 28 | # nix run .#profile.rollback 29 | # Build, without switching: 30 | # nix build .#profile 31 | # Pin nixpkgs in the flake registry and in NIX_PATH, so that 32 | # `nix run nixpkgs#hello` and `nix-shell -p hello --run hello` will 33 | # resolve to the same hello as below [should probably be run as root, see README caveats]: 34 | # sudo nix run .#profile.pin 35 | packages.profile = flakey-profile.lib.mkProfile { 36 | inherit pkgs; 37 | # Specifies things to pin in the flake registry and in NIX_PATH. 38 | pinned = { nixpkgs = toString nixpkgs; }; 39 | paths = with pkgs; [ 40 | hello 41 | ]; 42 | }; 43 | }); 44 | } 45 | -------------------------------------------------------------------------------- /templates/no-flake/README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # flakey-profile, without flakes?! 8 | 9 | Who needs flakes anyway! You just need a nixpkgs and a way of running stuff 10 | with `nix run`, both of which work fine without flakes. 11 | 12 | The point of flakes is to provide a mechanism of pinning inputs, a standardized 13 | schema for tooling to work with outputs, evaluating in a pure mode by 14 | default, caching *some* evaluation, and, to avoid random junk messing up 15 | evaluation caching, copying files listed in the git index into the Nix store 16 | before evaluating. 17 | 18 | Most of this doesn't matter for profiles, and we could pin inputs just fine 19 | before flakes, so let's demonstrate simply doing that. 20 | 21 | ## Usage 22 | 23 | For some fitting irony, copy this template into your directory with 24 | `nix flake init -t github:lf-/flakey-profile#no-flake`. 25 | 26 | 27 | ### To switch to this profile: 28 | 29 | ``` 30 | nix run -f . profile.switch 31 | ``` 32 | ### To revert a profile change: 33 | 34 | > **Warning**: This does not rollback the actions of `profile.pin`. To roll 35 | > that back, revert to the previous version of the profile using a version 36 | > control system and run `profile.pin` again. 37 | 38 | ``` 39 | nix run -f . profile.rollback 40 | ``` 41 | 42 | ### To build, without switching: 43 | 44 | ``` 45 | nix build -f . profile 46 | ``` 47 | 48 | ### To pin nixpkgs in `NIX_PATH` and the flake registry: 49 | 50 | This makes `nix run nixpkgs#hello` and `nix-shell -p hello --run hello` give 51 | you the same `hello` as if you listed it in your profile. 52 | 53 | We recommend only running this command as root, since by default the only 54 | channels used are on root's profile, and are used for `nix upgrade-nix` among 55 | other things. 56 | 57 | > **Warning**: This does not support revert internally; see the main README for 58 | > more details. To revert pinning, use source control to get the previous 59 | > version of the profile and run the pinning operation again. 60 | 61 | ``` 62 | nix run -f . profile.pin 63 | ``` 64 | 65 | ### To manage your version of nixpkgs 66 | 67 | Read `default.nix` and pick how you want to manage your dependencies. Three 68 | examples are given: 69 | 70 | - Simply `fetchTarball` some pinned commit ID. 71 | - Simply `fetchTarball` some commit ID, but the commit ID and hash are in a 72 | JSON file that can be updated for you with [`gridlock`][gridlock]. 73 | - Use `` such that `nix-channel` manages your version of nixpkgs. 74 | 75 | [gridlock]: https://github.com/lf-/gridlock 76 | 77 | We support pinning `nixpkgs` system-wide on the basis of the version specified 78 | here using `sudo nix run -f . profile.pin`. 79 | 80 | ## Note: the old CLI 81 | 82 | We use the experimental CLI here because it is simply nicer. The old CLI is 83 | legitimately pretty terrible, but if you have to use it, consider passing 84 | `--log-format bar-with-logs` to get the new build progress display. More to the 85 | point, there is no `nix run` equivalent for the old CLI. 86 | 87 | Where `nix run -f . some.attrpath` is written, replace it in your head with: 88 | 89 | ``` 90 | "$(nix-build --no-out-link --log-format bar-with-logs . -A some.attrpath)"/bin/attrpath 91 | ``` 92 | 93 | if that is helpful or illustrative. For example: 94 | 95 | ``` 96 | "$(nix-build --no-out-link --log-format bar-with-logs . -A profile.switch)"/bin/switch 97 | ``` 98 | -------------------------------------------------------------------------------- /templates/no-flake/default.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | let 6 | sources = { 7 | # If you want to update these manually, update the commit ID then set sha256 8 | # to an empty string and then update the hash to whatever the error gives 9 | # you. 10 | # 11 | # I generated these from what a program I wrote which amounts to a 12 | # wrapper around `git ls-remote` plus `nix-prefetch-url`. 13 | flakey-profile = builtins.fetchTarball { 14 | # https://github.com/lf-/flakey-profile/tree/main 15 | url = "https://github.com/lf-/flakey-profile/archive/cb9c69766c032a791dd008fad59f3e8908ee4179.tar.gz"; 16 | sha256 = "sha256-vPhr78oH3mguXRfcQXWWEoJjfGAK8DrdZnDelTtY7hA="; 17 | name = "source"; 18 | }; 19 | 20 | nixpkgs = builtins.fetchTarball { 21 | # https://github.com/nixos/nixpkgs/tree/nixos-unstable 22 | url = "https://github.com/nixos/nixpkgs/archive/85f1ba3e51676fa8cc604a3d863d729026a6b8eb.tar.gz"; 23 | sha256 = "sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU="; 24 | name = "source"; 25 | }; 26 | }; 27 | 28 | # If updating hashes and git commits manually is bothersome, you could use 29 | # niv or my tool gridlock (which amounts to a wrapper around `git ls-remote` 30 | # and a from-scratch implementation of nix-prefetch-url). 31 | # Both niv and gridlock are available in nixpkgs as their respective names. 32 | # 33 | # Below is an example of using gridlock. To use it, comment out or delete 34 | # `sources` above in this file. It was created by the following commands: 35 | # gridlock --lockfile gridlock.json init 36 | # gridlock --lockfile gridlock.json add lf-/flakey-profile 37 | # gridlock --lockfile gridlock.json add --branch nixos-unstable nixos/nixpkgs 38 | # 39 | # You can update versions of things with: 40 | # gridlock --lockfile gridlock.json update 41 | # 42 | # You can look at how new/old your stuff is with: 43 | # gridlock --lockfile gridlock.json show 44 | /* 45 | sourcesRaw = builtins.fromJSON (builtins.readFile ./gridlock.json); 46 | # For every attribute in `.packages` in gridlock.json, map it to a fetched 47 | # tarball. 48 | 49 | sources = builtins.mapAttrs 50 | (name: value: builtins.fetchTarball { 51 | url = value.url; 52 | sha256 = value.sha256; 53 | name = "source"; 54 | }) 55 | sourcesRaw.packages; 56 | */ 57 | 58 | 59 | # simplest way of getting nixpkgs: use nix-channel to manage versions 60 | /* 61 | pkgs = import { }; 62 | */ 63 | 64 | # mildly less convenient, but pinned: 65 | pkgs = import sources.nixpkgs { }; 66 | 67 | flakey-profile = import (sources.flakey-profile + "/lib"); 68 | in 69 | { 70 | profile = flakey-profile.mkProfile { 71 | # Usage: 72 | # Switch to this profile: 73 | # nix run -f . profile.switch 74 | # Revert a profile change: 75 | # nix run -f . profile.rollback 76 | # Build, without switching: 77 | # nix build -f . profile 78 | inherit pkgs; 79 | pinned = { inherit (sources) nixpkgs; }; 80 | paths = with pkgs; [ 81 | hello 82 | ]; 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /templates/no-flake/gridlock.json: -------------------------------------------------------------------------------- 1 | {"packages":{"flakey-profile":{"branch":"main","owner":"lf-","repo":"flakey-profile","rev":"cb9c69766c032a791dd008fad59f3e8908ee4179","sha256":"sha256-vPhr78oH3mguXRfcQXWWEoJjfGAK8DrdZnDelTtY7hA=","last_updated":1699908905,"url":"https://github.com/lf-/flakey-profile/archive/cb9c69766c032a791dd008fad59f3e8908ee4179.tar.gz"},"nixpkgs":{"branch":"nixos-unstable","owner":"nixos","repo":"nixpkgs","rev":"85f1ba3e51676fa8cc604a3d863d729026a6b8eb","sha256":"sha256-X09iKJ27mGsGambGfkKzqvw5esP1L/Rf8H3u3fCqIiU=","last_updated":1699908928,"url":"https://github.com/nixos/nixpkgs/archive/85f1ba3e51676fa8cc604a3d863d729026a6b8eb.tar.gz"}},"version":0} -------------------------------------------------------------------------------- /templates/no-flake/gridlock.json.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2023 Jade Lovelace 2 | 3 | SPDX-License-Identifier: CC0-1.0 4 | --------------------------------------------------------------------------------