├── COPYRIGHT ├── docs ├── legacy-nix-demo.gif └── src │ ├── updateScript │ ├── flake-demo-nix-expert.cast │ └── legacy-nix-demo.cast ├── test ├── outputs │ ├── cowsay-from-global-nixpkgs-shell.nix │ ├── cowsay-from-local-nixpkgs-shell.nix │ ├── cowsay-from-system-nixpkgs-shell.nix │ ├── cowsay-from-user-nixpkgs-shell.nix │ ├── inputs-from-unknown-source-shell.nix │ ├── two-nixpkgs-inputs-shell.nix │ ├── cowsay-from-system-custompkgs-shell.nix │ ├── multiple-repository-sources-shell.nix │ ├── inputs-from-know-and-unknown-sources-shell.nix │ ├── inputs-from-different-registries-shell.nix │ ├── two-build-inputs-and-command-shell.nix │ ├── cowsay-from-local-nixpkgs-flake.nix │ ├── two-nixpkgs-inputs-flake.nix │ ├── cowsay-from-user-nixpkgs-flake.nix │ ├── cowsay-from-global-nixpkgs-flake.nix │ ├── cowsay-from-system-nixpkgs-flake.nix │ ├── inputs-from-unknown-source-flake.nix │ ├── inputs-from-know-and-unknown-sources-flake.nix │ ├── cowsay-from-system-custompkgs-flake.nix │ └── inputs-from-different-registries-flake.nix ├── Spec.hs └── TestHelpers.hs ├── src ├── ShellifyTemplate.hs ├── FlakeTemplate.hs ├── Constants.hs ├── Shellify.hs ├── Options.hs └── TemplateGeneration.hs ├── app └── Main.hs ├── .github └── workflows │ └── cabaltest.yml ├── CONTRIBUTING.md ├── flake.lock ├── CHANGELOG.md ├── flake.nix ├── shellify.cabal ├── README.md └── LICENSE /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Daniel Rolls 2 | -------------------------------------------------------------------------------- /docs/legacy-nix-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielrolls/shellify/HEAD/docs/legacy-nix-demo.gif -------------------------------------------------------------------------------- /test/outputs/cowsay-from-global-nixpkgs-shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | pkgs.cowsay 7 | ]; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-local-nixpkgs-shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | pkgs.cowsay 7 | ]; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-system-nixpkgs-shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | pkgs.cowsay 7 | ]; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-user-nixpkgs-shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | pkgs.cowsay 7 | ]; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/outputs/inputs-from-unknown-source-shell.nix: -------------------------------------------------------------------------------- 1 | { foo, pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | foo.cowsay 7 | ]; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/outputs/two-nixpkgs-inputs-shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | pkgs.cowsay 7 | pkgs.python 8 | ]; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-system-custompkgs-shell.nix: -------------------------------------------------------------------------------- 1 | { custompkgs, pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | custompkgs.cowsay 7 | ]; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /test/outputs/multiple-repository-sources-shell.nix: -------------------------------------------------------------------------------- 1 | { foo, pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | foo.cowsay 7 | pkgs.python 8 | ]; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /test/outputs/inputs-from-know-and-unknown-sources-shell.nix: -------------------------------------------------------------------------------- 1 | { foo, pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | foo.cowsay 7 | pkgs.python 8 | ]; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /docs/src/updateScript: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | aws_res=`aws --version` 6 | res=`echo '{"animals": ["dog"]}' | jq -r '.animals[0]'` 7 | if [ "$res" = "dog" ]; then 8 | echo Update succeeded 9 | fi 10 | -------------------------------------------------------------------------------- /test/outputs/inputs-from-different-registries-shell.nix: -------------------------------------------------------------------------------- 1 | { blender-bin, pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | blender-bin.blender_3_5 7 | pkgs.python 8 | ]; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /test/outputs/two-build-inputs-and-command-shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import {} }: 2 | 3 | pkgs.mkShell { 4 | 5 | buildInputs = [ 6 | pkgs.cowsay 7 | pkgs.python 8 | ]; 9 | 10 | shellHook = '' 11 | cowsay 12 | ''; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/ShellifyTemplate.hs: -------------------------------------------------------------------------------- 1 | module ShellifyTemplate where 2 | 3 | import Text.RawString.QQ (r) 4 | 5 | shellifyTemplate = [r|{ $parameters;separator=', '$ }: 6 | 7 | pkgs.mkShell { 8 | 9 | buildInputs = [ 10 | $build_inputs;separator=' 11 | '$ 12 | ]; 13 | $if(shell_hook)$ 14 | 15 | shellHook = '' 16 | $shell_hook$ 17 | ''; 18 | $endif$ 19 | } 20 | 21 | |] 22 | -------------------------------------------------------------------------------- /app/Main.hs: -------------------------------------------------------------------------------- 1 | module Main where 2 | 3 | import Shellify (runShellify, printErrorAndReturnFailure) 4 | import System.Environment (getArgs) 5 | import Options(parseCommandLine) 6 | import Options.Applicative (handleParseResult) 7 | import Control.Monad ((>=>)) 8 | 9 | main :: IO () 10 | main = getArgs >>= 11 | either printErrorAndReturnFailure 12 | (handleParseResult >=> runShellify ) 13 | . parseCommandLine -------------------------------------------------------------------------------- /.github/workflows/cabaltest.yml: -------------------------------------------------------------------------------- 1 | name: "Cabal test" 2 | on: 3 | pull_request: 4 | push: 5 | jobs: 6 | tests: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v3 10 | - uses: cachix/install-nix-action@v20 11 | with: 12 | nix_path: nixpkgs=channel:nixos-unstable 13 | - run: nix develop 14 | - run: nix develop --command cabal v2-update 15 | - run: nix develop --command cabal v2-test --enable-tests 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | To build this project just run `nix build`. To hack it run `nix develop` to bring in all dependencies. 2 | 3 | Feel free to raise PRs. Small iterations are always better than major rewrites. 4 | 5 | If you are not confident writing Haskell you may find it easier to add a test case for what you want in `test/Spec.hs`. 6 | This is easy to do without really understanding the code by copying a test case and editing the parameters ands expected result and is probably the easiest way to communicate an intended change. 7 | Just creating an issue is ok too. 8 | -------------------------------------------------------------------------------- /src/FlakeTemplate.hs: -------------------------------------------------------------------------------- 1 | module FlakeTemplate where 2 | 3 | import Text.RawString.QQ (r) 4 | 5 | 6 | flakeTemplate = [r|{ 7 | description = "my project description"; 8 | 9 | inputs = { 10 | 11 | flake-utils.url = "github:numtide/flake-utils"; 12 | $repo_inputs;separator=' 13 | '$ 14 | 15 | }; 16 | 17 | outputs = { self, $repos;separator=', '$, flake-utils }: 18 | flake-utils.lib.eachDefaultSystem 19 | (system: 20 | let $pkgs_decls;separator=' 21 | '$ 22 | in 23 | { 24 | devShells.default = import ./shell.nix { $shell_args;separator=' '$ }; 25 | } 26 | ); 27 | } 28 | 29 | |] 30 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1741513245, 6 | "narHash": "sha256-7rTAMNTY1xoBwz0h7ZMtEcd8LELk9R5TzBPoHuhNSCk=", 7 | "owner": "NixOS", 8 | "repo": "nixpkgs", 9 | "rev": "e3e32b642a31e6714ec1b712de8c91a3352ce7e1", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "NixOS", 14 | "ref": "nixos-unstable", 15 | "repo": "nixpkgs", 16 | "type": "github" 17 | } 18 | }, 19 | "root": { 20 | "inputs": { 21 | "nixpkgs": "nixpkgs" 22 | } 23 | } 24 | }, 25 | "root": "root", 26 | "version": 7 27 | } 28 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-local-nixpkgs-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nixpkgs.url = "path:/local/nixpkgs/path"; 8 | 9 | }; 10 | 11 | outputs = { self, nixpkgs, flake-utils }: 12 | flake-utils.lib.eachDefaultSystem 13 | (system: 14 | let nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 15 | in 16 | { 17 | devShells.default = import ./shell.nix { pkgs=nixpkgsPkgs; }; 18 | } 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /test/outputs/two-nixpkgs-inputs-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 8 | 9 | }; 10 | 11 | outputs = { self, nixpkgs, flake-utils }: 12 | flake-utils.lib.eachDefaultSystem 13 | (system: 14 | let nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 15 | in 16 | { 17 | devShells.default = import ./shell.nix { pkgs=nixpkgsPkgs; }; 18 | } 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-user-nixpkgs-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-user-registry"; 8 | 9 | }; 10 | 11 | outputs = { self, nixpkgs, flake-utils }: 12 | flake-utils.lib.eachDefaultSystem 13 | (system: 14 | let nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 15 | in 16 | { 17 | devShells.default = import ./shell.nix { pkgs=nixpkgsPkgs; }; 18 | } 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-global-nixpkgs-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-global-registry"; 8 | 9 | }; 10 | 11 | outputs = { self, nixpkgs, flake-utils }: 12 | flake-utils.lib.eachDefaultSystem 13 | (system: 14 | let nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 15 | in 16 | { 17 | devShells.default = import ./shell.nix { pkgs=nixpkgsPkgs; }; 18 | } 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-system-nixpkgs-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-system-registry"; 8 | 9 | }; 10 | 11 | outputs = { self, nixpkgs, flake-utils }: 12 | flake-utils.lib.eachDefaultSystem 13 | (system: 14 | let nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 15 | in 16 | { 17 | devShells.default = import ./shell.nix { pkgs=nixpkgsPkgs; }; 18 | } 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog for Shellify 2 | 3 | ## 0.14.0 4 | - Substantial command line parsing changes. 5 | Expect some changes of behaviour e.g. exit codes. 6 | - Command line completion support 7 | 8 | ## 0.13.0 9 | - Return exit code zero when some invalid options are passed 10 | - End shell and flake files with a newline character 11 | 12 | ## 0.12.0 13 | - Add --allow-local-pinned-registries-to-be-prioritized switch 14 | - Prioiritise registries favouring those not pinned to local 15 | 16 | ## 0.11.0 17 | - Drop the shellify executable in favour or nix-shellify 18 | 19 | ## 0.10.0 20 | - Add dependency bounds 21 | 22 | ## 0.9.0 23 | - Completed usable with good test coverage. I'll await some feedback before declaring a v1.0.0 release. 24 | 25 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "shellify"; 3 | 4 | inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 5 | 6 | outputs = { self, nixpkgs }: 7 | 8 | let pkgs = nixpkgs.legacyPackages.x86_64-linux; 9 | in { 10 | 11 | packages.x86_64-linux.default = (pkgs.haskell.lib.overrideCabal ( 12 | pkgs.haskellPackages.developPackage { 13 | root = ./.; 14 | modifier = drv: 15 | pkgs.haskell.lib.addBuildTools drv (with pkgs.haskellPackages; 16 | [ cabal-install 17 | hlint 18 | haskell-language-server 19 | ]); 20 | } 21 | ) { 22 | enableSeparateDataOutput = false; 23 | }).overrideAttrs(old: { 24 | buildInputs = old.buildInputs ++ [ pkgs.nix ]; 25 | }); 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /src/Constants.hs: -------------------------------------------------------------------------------- 1 | module Constants where 2 | 3 | import Data.Text (Text()) 4 | import Text.RawString.QQ (r) 5 | 6 | hlDesc :: String 7 | hlDesc = [r| 8 | Pass nix-shell arguments to nix-shellify to have it generate a shell.nix in 9 | the current directory. You can then just run nix develop or nix-shell in that 10 | directory to have those packages in your environment. To run nix commands 11 | you must first install Nix. 12 | |] 13 | 14 | noPackagesError = [r|I can't write out a shell file without any packages specified. 15 | Try 'nix-shellify --help' for more information.|] :: Text 16 | 17 | pkgsDecl var repo = var <> [r| = if builtins.hasAttr "packages" |] <> repo <> [r| then |] <> repo <> [r|.packages.${system} else ( if builtins.hasAttr "legacyPackages" |] <> repo <> [r| then |] <> repo <> [r|.legacyPackages.${system} else |] <> repo <> [r|);|] 18 | -------------------------------------------------------------------------------- /test/outputs/inputs-from-unknown-source-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | foo.url = "PLEASE ENTER input here"; 8 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 9 | 10 | }; 11 | 12 | outputs = { self, foo, nixpkgs, flake-utils }: 13 | flake-utils.lib.eachDefaultSystem 14 | (system: 15 | let fooPkgs = if builtins.hasAttr "packages" foo then foo.packages.${system} else ( if builtins.hasAttr "legacyPackages" foo then foo.legacyPackages.${system} else foo); 16 | nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 17 | in 18 | { 19 | devShells.default = import ./shell.nix { foo=fooPkgs; pkgs=nixpkgsPkgs; }; 20 | } 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /test/outputs/inputs-from-know-and-unknown-sources-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | foo.url = "PLEASE ENTER input here"; 8 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 9 | 10 | }; 11 | 12 | outputs = { self, foo, nixpkgs, flake-utils }: 13 | flake-utils.lib.eachDefaultSystem 14 | (system: 15 | let fooPkgs = if builtins.hasAttr "packages" foo then foo.packages.${system} else ( if builtins.hasAttr "legacyPackages" foo then foo.legacyPackages.${system} else foo); 16 | nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 17 | in 18 | { 19 | devShells.default = import ./shell.nix { foo=fooPkgs; pkgs=nixpkgsPkgs; }; 20 | } 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /test/outputs/cowsay-from-system-custompkgs-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | custompkgs.url = "github:NixOS/custompkgs/custompkgs-system-registry"; 8 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 9 | 10 | }; 11 | 12 | outputs = { self, custompkgs, nixpkgs, flake-utils }: 13 | flake-utils.lib.eachDefaultSystem 14 | (system: 15 | let custompkgsPkgs = if builtins.hasAttr "packages" custompkgs then custompkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" custompkgs then custompkgs.legacyPackages.${system} else custompkgs); 16 | nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 17 | in 18 | { 19 | devShells.default = import ./shell.nix { custompkgs=custompkgsPkgs; pkgs=nixpkgsPkgs; }; 20 | } 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /test/outputs/inputs-from-different-registries-flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "my project description"; 3 | 4 | inputs = { 5 | 6 | flake-utils.url = "github:numtide/flake-utils"; 7 | blender-bin.url = "github:edolstra/nix-warez?dir=blender"; 8 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 9 | 10 | }; 11 | 12 | outputs = { self, blender-bin, nixpkgs, flake-utils }: 13 | flake-utils.lib.eachDefaultSystem 14 | (system: 15 | let blender-binPkgs = if builtins.hasAttr "packages" blender-bin then blender-bin.packages.${system} else ( if builtins.hasAttr "legacyPackages" blender-bin then blender-bin.legacyPackages.${system} else blender-bin); 16 | nixpkgsPkgs = if builtins.hasAttr "packages" nixpkgs then nixpkgs.packages.${system} else ( if builtins.hasAttr "legacyPackages" nixpkgs then nixpkgs.legacyPackages.${system} else nixpkgs); 17 | in 18 | { 19 | devShells.default = import ./shell.nix { blender-bin=blender-binPkgs; pkgs=nixpkgsPkgs; }; 20 | } 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /shellify.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 3.0 2 | name: shellify 3 | version: 0.14.0.2 4 | 5 | author: Daniel Rolls 6 | maintainer: daniel.rolls.27@googlemail.com 7 | license: Apache-2.0 8 | license-files: LICENSE 9 | copyright: (c) 2023 Daniel Rolls 10 | synopsis: A tool for generating shell.nix files 11 | description: 12 | Please see the README on GitHub at 13 | category: Packaging 14 | extra-source-files: 15 | test/outputs/*.nix 16 | extra-doc-files: 17 | CHANGELOG.md 18 | tested-with: 19 | GHC == 9.2.4, 20 | GHC == 9.2.8, 21 | GHC == 9.6.2, 22 | GHC == 9.10.1, 23 | GHC == 9.12.2 24 | 25 | source-repository head 26 | type: git 27 | location: https://github.com/danielrolls/shellify 28 | 29 | common deps 30 | default-language: GHC2021 31 | build-depends: 32 | base >=4.16 && <4.22, 33 | optparse-applicative >=0.18.1.0 && <0.20, 34 | raw-strings-qq >=1.1 && <1.2, 35 | text >=1.2.5.0 && <2.2 36 | 37 | default-extensions: 38 | LambdaCase 39 | OverloadedStrings 40 | QuasiQuotes 41 | 42 | library 43 | import: deps 44 | exposed-modules: 45 | Constants 46 | FlakeTemplate 47 | Options 48 | Shellify 49 | ShellifyTemplate 50 | TemplateGeneration 51 | Paths_shellify 52 | autogen-modules: 53 | Paths_shellify 54 | hs-source-dirs: src 55 | build-depends: 56 | containers >=0.6.5.1 && <0.9, 57 | data-default >=0.7 && <0.9, 58 | directory >=1.3.6.2 && <1.4, 59 | HStringTemplate >=0.8.8 && <0.9, 60 | lens >=5.1.1 && <5.4, 61 | mtl >=2.2.2 && <2.4, 62 | parsec >=3.1.15.0 && <3.2, 63 | shake >=0.19.7 && <0.20, 64 | unordered-containers >=0.2.19.1 && <0.3 65 | 66 | executable nix-shellify 67 | import: deps 68 | main-is: Main.hs 69 | build-depends: 70 | shellify >=0 71 | hs-source-dirs: app 72 | 73 | test-suite haskelltest-test 74 | import: deps 75 | type: exitcode-stdio-1.0 76 | main-is: Spec.hs 77 | hs-source-dirs: test 78 | other-modules: 79 | Paths_shellify, 80 | TestHelpers 81 | autogen-modules: 82 | Paths_shellify 83 | ghc-options: -threaded -rtsopts -with-rtsopts=-N 84 | build-depends: 85 | data-default >=0.7 && <0.9, 86 | extra >=1.7.16 && <1.9, 87 | hspec >=2.9.7 && <2.12, 88 | hspec-core >=2.9.7 && <2.12, 89 | shellify >=0 90 | 91 | -------------------------------------------------------------------------------- /src/Shellify.hs: -------------------------------------------------------------------------------- 1 | module Shellify (printErrorAndReturnFailure, runShellify, calculateExpectedFiles) where 2 | 3 | import Prelude hiding (readFile, writeFile) 4 | import Options (Options()) 5 | import TemplateGeneration ( generateFlakeText, generateShellDotNixText, getRegistryDB) 6 | 7 | import Control.Monad (guard, when) 8 | import Data.Bool (bool) 9 | import Data.Maybe (isNothing) 10 | import Data.Text (pack, Text(), unpack) 11 | import Data.Text.IO (hPutStrLn, readFile, writeFile) 12 | import GHC.IO.Exception (ExitCode(ExitSuccess, ExitFailure)) 13 | import System.Directory (doesPathExist) 14 | import System.Exit (exitWith) 15 | import System.IO (stderr) 16 | 17 | runShellify :: Options -> IO () 18 | runShellify opts = 19 | getRegistryDB >>= 20 | either 21 | (printErrorAndReturnFailure . ("Error calling nix registry: " <>)) 22 | (mapM_ createAFile . (`calculateExpectedFiles` opts)) 23 | 24 | createAFile :: (Text, Text) -> IO () 25 | createAFile (name, content) = do extCde <- createFile (unpack name) content 26 | when (extCde /= ExitSuccess) 27 | $ exitWith extCde 28 | 29 | where createFile :: FilePath -> Text -> IO ExitCode 30 | createFile fileName expectedContents = do 31 | fileContents <- traverse readFile . bool Nothing 32 | (Just fileName) 33 | =<< doesPathExist fileName 34 | printError $ actionDescription (pack fileName) expectedContents fileContents 35 | when (isNothing fileContents) 36 | $ writeFile fileName expectedContents 37 | return $ returnCode expectedContents fileContents 38 | 39 | calculateExpectedFiles :: Text -> Options -> [(Text,Text)] 40 | calculateExpectedFiles registry options = 41 | ("shell.nix", generateShellDotNixText options) 42 | : maybe 43 | [] 44 | (pure . ("flake.nix",)) 45 | (generateFlakeText registry options) 46 | 47 | actionDescription :: Text -> Text -> Maybe Text -> Text 48 | actionDescription fName _ Nothing = fName <> " does not exist. Creating one" 49 | actionDescription fName a (Just b) | a == b = "The existing " <> fName <> " is good already" 50 | actionDescription fName _ _ = "A " <> fName <> " exists already. Delete it or move it and try again" 51 | 52 | returnCode :: Text -> Maybe Text -> ExitCode 53 | returnCode _ Nothing = ExitSuccess 54 | returnCode a (Just b) | a == b = ExitSuccess 55 | returnCode _ _ = ExitFailure 1 56 | 57 | printErrorAndReturnFailure err = printError err >> exitWith (ExitFailure 1) 58 | printError = hPutStrLn stderr 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shellify 2 | 3 | [![Packaging status](https://repology.org/badge/vertical-allrepos/shellify.svg?columns=4&header=Shellify)](https://repology.org/project/shellify/versions) 4 | 5 | [![Packaging status](https://repology.org/badge/vertical-allrepos/haskell%3Ashellify.svg?columns=4&header=Shellify%20Library)](https://repology.org/project/shellify/versions) 6 | 7 | Want to quicky get something to build and to have it reproducable and sharable? With [`nix`](https://nixos.org/manual/nix/stable/command-ref/nix-shell.html) it is easy to quickly add dependencies to get something to build. It's also easy to work quickly and iteratively. With this tool, once you're done you can save a `shell.nix` so that you and anybody else can quickly and instantly rebuild with an identical environment with all the same dependencies. Just swap out `nix-shell` or `nix` for `nix-shellify` to create the necessary `shell.nix` in the local directory. It makes saving a basic working `shell.nix` almost instant. Take a look at the short examples below to see the workflow. 8 | 9 | ## Prerequisites 10 | 11 | This utility assumes [nix is installed](https://nixos.org/download.html). 12 | 13 | 14 | ## Example usage without flakes 15 | 16 | ![Interactive demo showing how to use shellify with flakes](docs/legacy-nix-demo.gif) 17 | 18 | I want to run a program called `foo`. When I run `./foo` it complains I don't have python. So I run `nix-shell -p python` and try running `./foo` again. 19 | 20 | Now it complains I don't have asciidoc so I come out of the shell and edit the last command to add asciidoc by running `nix-shell -p python asciidoc`. Now it works. 21 | 22 | I exit my shell and change `nix-shell -p python asciidoc` to `nix-shellify -p python asciidoc`. It then creates a `shell.nix` which I keep next to foo. It looks like this: 23 | 24 | ```nix 25 | { pkgs ? import {} }: 26 | 27 | pkgs.mkShell { 28 | 29 | buildInputs = [ 30 | pkgs.asciidoc 31 | pkgs.python 32 | ]; 33 | 34 | } 35 | ``` 36 | 37 | Now I can just type `nix-shell` and I have what I need to run foo. I can share and everybody else can run foo too without the same search. They also don't need to run it in a conatainer or VM or to maintain depenencies on their system themself. 38 | 39 | ## Example usage with flakes 40 | 41 | ![Interactive demo showing how to use shellify with flakes](https://user-images.githubusercontent.com/50051176/258610444-6e848fa4-a675-4aa3-b3b6-d099605bc4b7.gif) 42 | 43 | I want to run something called `foo`. When I run `./foo` it complains I don't have python. So I run `nixshell nixpkgs#python` and try running `./foo` again. 44 | 45 | Now it complains I didn't have asciidoc so I come out of the shell and edit the last command to add asciideoc by running `nix shell nixpkgs#python nixpkgs#asciidoc`. Now it works. 46 | 47 | I exit my shell and change `nix shell nixpkgs#python nixpkgs#asciidoc` to `nix-shellify shell nixpkgs#python nixpkgs#asciidoc`. I do this by quickly extending `nix` to `nix-shellify` using tab completion. It then creates a `flake.nix` and `shell.nix` which I commit in git next to foo. Now I can just type `nix develop` and I have what I need to run foo. I can share and everybody else can quickly run foo too with the same environment. I can also go on to modify my nix files e.g. to run as an app or run an initialisation command when starting the shell. 48 | 49 | -------------------------------------------------------------------------------- /src/Options.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE TemplateHaskell #-} 2 | module Options (Options(..), OutputForm(..), Package(), Packages(Packages), parseCommandLine, setPackages) where 3 | 4 | import Constants (hlDesc, noPackagesError) 5 | 6 | import Control.Lens.Combinators (makeLenses, makePrisms) 7 | import Data.Default (Default(def)) 8 | import Data.List (isPrefixOf) 9 | import Data.Maybe (fromMaybe) 10 | import Data.Set (Set(), fromList) 11 | import Data.Text (Text()) 12 | import Data.Version (showVersion) 13 | import Options.Applicative ((<**>), Parser, ParserResult(Success, Failure, CompletionInvoked), argument, command, defaultPrefs, execParserPure, fullDesc, header, help, helper, hidden, info, long, metavar, option, optional, progDesc, short, simpleVersioner, some, str, strOption, switch) 14 | import Paths_shellify (version) 15 | 16 | data OutputForm = Traditional 17 | | Flake 18 | deriving (Eq, Show) 19 | 20 | newtype Packages = Packages (Set Package) 21 | deriving (Eq, Monoid, Semigroup, Show) 22 | 23 | type Package = Text 24 | 25 | makePrisms ''Packages 26 | setPackages = Packages . fromList 27 | 28 | opts = info (commandParser <**> simpleVersioner (showVersion version) 29 | <**> helper) $ 30 | fullDesc 31 | <> progDesc hlDesc 32 | <> header "Quickly generate shell.nix files once you have a working shell" 33 | 34 | commandParser :: Parser CommandLineOptions 35 | commandParser = CommandLineOptions 36 | <$> optional (some (option str ( 37 | long "packages" 38 | <> short 'p' 39 | <> metavar "PACKAGE" 40 | <> help "Packages to install in the shell.nix file. This option can be used multiple times to specify multiple packages" 41 | ))) 42 | <*> optional (option str ( 43 | long "command" 44 | <> long "run" 45 | <> short 'c' 46 | <> metavar "COMMAND" 47 | <> help "Command to run on initial shell startup" 48 | )) 49 | <*> switch ( 50 | long "with-flake" 51 | <> help "When using the -p option to specify packages, use this switch to have a flake.nix created in addition to a shell.nix. This is recommended to ensure the versions of dependencies are kept for reproducibility and so that shells are cached to load faster." 52 | ) 53 | <*> switch ( 54 | long "allow-local-pinned-registries-to-be-prioritized" 55 | <> help "Pinned local repoisitory URLs are usually taken last when looking for URLs for generated flake.nix files. This is usually desired. If you do however want to see these pinned entries in the flake file as specified in your registry, then set this flag." 56 | ) 57 | <*> optional (some (option str ( 58 | long "arg" 59 | <> long "argstr" 60 | <> hidden 61 | ))) 62 | <*> optional (some (argument str (metavar "shell PACKAGES..."))) 63 | 64 | data Options = Options { 65 | _packages :: !Packages 66 | , _command :: !(Maybe Text) 67 | , _outputForm :: !OutputForm 68 | , _prioritiseLocalPinnedSystem :: !Bool 69 | } deriving (Eq, Show) 70 | 71 | data CommandLineOptions = CommandLineOptions { 72 | __packages :: !(Maybe [Text]) 73 | , __command :: !(Maybe Text) 74 | , __withFlake :: !Bool 75 | , __prioritiseLocalPinnedSystem :: Bool 76 | , __discard :: !(Maybe [String]) 77 | , __shellPackages :: Maybe [Package] 78 | } deriving (Show) 79 | 80 | makeLenses ''Options 81 | 82 | instance Default Options where 83 | def = Options { 84 | _packages = mempty, 85 | _command = Nothing, 86 | _outputForm = Traditional, 87 | _prioritiseLocalPinnedSystem = False 88 | } 89 | 90 | parseCommandLine :: [String] -> Either Text (ParserResult Options) 91 | parseCommandLine = 92 | (\case 93 | Success res -> fmap Success (parseCommandLineOptions res) 94 | Failure failure -> Right $ Failure failure 95 | CompletionInvoked f -> Right $ CompletionInvoked f) 96 | . execParserPure defaultPrefs opts . fixupRequest 97 | where parseCommandLineOptions :: CommandLineOptions -> Either Text Options 98 | parseCommandLineOptions originalParsedOptions = 99 | if _packages transformedOptions == mempty then 100 | Left noPackagesError 101 | else 102 | Right transformedOptions 103 | where transformedOptions = 104 | (Options <$> setPackages . ((++) <$> fromMaybe mempty . __packages 105 | <*> shellArgs . __shellPackages) 106 | <*> __command 107 | <*> \case 108 | f | __withFlake f -> Flake 109 | | (hasShellArg . __shellPackages) f -> Flake 110 | _ | otherwise -> Traditional 111 | <*> __prioritiseLocalPinnedSystem) originalParsedOptions 112 | hasShellArg (Just ("shell":_)) = True 113 | hasShellArg _ = False 114 | shellArgs (Just ("shell": rst)) = rst 115 | shellArgs _ = [] 116 | fixupRequest (a : b : c : d) | (a == "-p" || a == "--packages") 117 | && isNotASwitch b 118 | && isNotASwitch c = 119 | a : b : fixupRequest ("-p" : c : d) 120 | where isNotASwitch = not . isPrefixOf "-" 121 | fixupRequest (a : b) = a : fixupRequest b 122 | fixupRequest [] = [] 123 | -------------------------------------------------------------------------------- /src/TemplateGeneration.hs: -------------------------------------------------------------------------------- 1 | module TemplateGeneration (generateShellDotNixText, generateFlakeText, getRegistryDB) where 2 | 3 | import Prelude hiding (map) 4 | import Constants 5 | import FlakeTemplate 6 | import Options 7 | import ShellifyTemplate 8 | 9 | import Data.Bifunctor (bimap) 10 | import Data.Bool (bool) 11 | import Data.List (find, sortBy, sortOn) 12 | import Data.Maybe (fromMaybe) 13 | import Data.Set (Set(), insert, map, toList) 14 | import Data.Text (Text(), isInfixOf, isPrefixOf, pack, splitOn, unpack) 15 | import Development.Shake.Command (cmd, Exit(Exit), Stderr(Stderr), Stdout(Stdout)) 16 | import System.Exit (ExitCode (ExitSuccess)) 17 | import Text.ParserCombinators.Parsec (Parser, char, endBy, eof, many1, noneOf, parse, string, (<|>)) 18 | import Text.StringTemplate (newSTMP, render, setAttribute) 19 | 20 | generateFlakeText :: Text -> Options -> Maybe Text 21 | generateFlakeText db Options{_packages=Packages packages, _outputForm=outputForm, _prioritiseLocalPinnedSystem=_prioritiseLocalPinnedSystem} = 22 | bool 23 | Nothing 24 | (Just $ render 25 | $ setAttribute "repo_inputs" repoInputs 26 | $ setAttribute "repos" repos 27 | $ setAttribute "pkgs_decls" pkgsDecls 28 | $ setAttribute "shell_args" shellArgs 29 | $ newSTMP flakeTemplate) 30 | (outputForm == Flake) 31 | where repos = getPackageRepoWrapper packages 32 | repoVars = getPackageRepoVarName <$> repos 33 | repoInputs = repoInput <$> repos 34 | repoInputLine repoName url = repoName <> ".url = \"" <> url <> "\";" 35 | repoInput repoName = repoInputLine repoName . 36 | either 37 | (error . ("Unexpected output from nix registry call: " <>)) 38 | (fromMaybe "PLEASE ENTER input here") 39 | . findFlakeRepoUrl _prioritiseLocalPinnedSystem db $ repoName 40 | pkgsVar = (<> "Pkgs") 41 | pkgsVars = pkgsVar <$> repos 42 | pkgsDecls = (\repo -> pkgsDecl (pkgsVar repo) repo) <$> repos 43 | shellArgs = (\(a,b) -> a <> "=" <> b <> ";") <$> zip repoVars pkgsVars 44 | 45 | generateShellDotNixText :: Options -> Text 46 | generateShellDotNixText Options{_packages=Packages packages, _command=command} = 47 | render 48 | $ setAttribute "build_inputs" pkgs 49 | $ setAttribute "parameters" parameters 50 | $ maybe id 51 | (setAttribute "shell_hook") 52 | command 53 | $ newSTMP shellifyTemplate 54 | where pkgs = map generateBuildInput packages 55 | parameters = generateParametersWrapper packages 56 | generateBuildInput input = (toImportVar . getPackageRepo) input <> "." <> getPackageName input 57 | 58 | getPackageRepoWrapper :: Set Package -> [Text] 59 | getPackageRepoWrapper = toList . insert "nixpkgs" . map getPackageRepo 60 | 61 | getPackageRepo input | "#" `isInfixOf` input 62 | = head $ splitOn "#" input 63 | | otherwise 64 | = "nixpkgs" 65 | 66 | getPackageName input | "#" `isInfixOf` input 67 | = head $ tail $ splitOn "#" input 68 | | otherwise 69 | = input 70 | 71 | toImportVar var | var == "nixpkgs" 72 | = "pkgs" 73 | | otherwise 74 | = var 75 | 76 | getPackageRepoVarName "nixpkgs" = "pkgs" 77 | getPackageRepoVarName a = a 78 | 79 | generateParametersWrapper :: Set Package -> Set Text 80 | generateParametersWrapper = insert "pkgs ? import {}" 81 | . map generateParameters 82 | 83 | generateParameters :: Package -> Text 84 | generateParameters package | "#" `isInfixOf` package 85 | && not ("nixpkgs#" `isPrefixOf` package) 86 | = getPackageRepo package 87 | generateParameters _ = "pkgs ? import {}" 88 | 89 | getRegistryDB :: IO (Either Text Text) 90 | getRegistryDB = 91 | do (Stdout out, Stderr err, Exit ex) <- cmd 92 | ("nix --extra-experimental-features nix-command --extra-experimental-features flakes registry list" :: String) 93 | return $ bool (Left $ pack err) 94 | (Right $ pack out) 95 | (ex == ExitSuccess) 96 | 97 | findFlakeRepoUrl :: Bool -> Text -> Text -> Either String (Maybe Text) 98 | findFlakeRepoUrl prioritiseLocalPinnedSystem haystack needle = 99 | bimap ((<>) "Error processing nix registry list output: " . show) 100 | (fmap repoUrl . find ((needle ==) . repoName) 101 | . (if prioritiseLocalPinnedSystem then sortOn repoType else sortBy compareRepoEntries)) 102 | $ parse parseRepos "" . unpack $ haystack 103 | 104 | compareRepoEntries repoA repoB 105 | | repoHasLocalPinning repoA && not (repoHasLocalPinning repoB) = GT 106 | | repoHasLocalPinning repoB && not (repoHasLocalPinning repoA) = LT 107 | | otherwise = repoType repoA `compare` repoType repoB 108 | where repoHasLocalPinning = isPrefixOf "path:" . repoUrl 109 | 110 | data RepoType = User | System | Global 111 | deriving (Eq, Ord) 112 | 113 | data FlakeRepo = FlakeRepo { 114 | repoName :: Text 115 | , repoUrl :: Text 116 | , repoType :: RepoType 117 | } 118 | 119 | parseRepos :: Parser [FlakeRepo] 120 | parseRepos = do res <- endBy parseLine (char '\n') 121 | eof 122 | return res 123 | where parseLine = do repoType <- parseRepoType 124 | char ' ' 125 | flakeName <- string "flake:" >> parseParam 126 | char ' ' 127 | repoUrl <- parseParam 128 | return $ FlakeRepo (pack flakeName) (pack repoUrl) repoType 129 | parseParam = many1 (noneOf " \n") 130 | parseRepoType = (string "global" >> return Global) 131 | <|> (string "system" >> return System) 132 | <|> (string "user" >> return User) 133 | 134 | -------------------------------------------------------------------------------- /test/Spec.hs: -------------------------------------------------------------------------------- 1 | import Data.Default (Default(def)) 2 | import Test.Hspec (describe, hspec, it, shouldBe, specify) 3 | 4 | import Options 5 | import TestHelpers 6 | 7 | main = hspec $ do 8 | 9 | describe "When passing option combinations" $ do 10 | 11 | it "prints a message saying no package is specified when no argument is supplied" $ 12 | shellifyWithArgs "" 13 | `shouldReturnSubstring` 14 | "without any packages specified" 15 | 16 | it "should complain if no package is specified" $ 17 | shellifyWithArgs "nipkgs#cowsay" 18 | `shouldReturnSubstring` 19 | "without any packages specified" 20 | 21 | it "shows the version number when requested" $ do 22 | shellifyWithArgs "--version" 23 | `shouldReturnSubstring` "0." 24 | 25 | describe "When using the --command option" $ do 26 | 27 | it "produces a shell with a shell hook" $ 28 | shellifyWithArgs "-p python -p cowsay --command cowsay" 29 | `shouldReturnShellTextDefinedBy` 30 | "two-build-inputs-and-command" 31 | 32 | it "allows a command to be specified with a package" $ 33 | theOptions "-p python --command cowsay" 34 | `shouldBe` 35 | Right def{_packages=setPackages ["python"], _command=Just "cowsay"} 36 | 37 | it "allows a command to be specified before a package" $ 38 | theOptions "--run cowsay -p python" 39 | `shouldBe` 40 | Right def{_packages=setPackages ["python"], _command=Just "cowsay"} 41 | 42 | it "allows a command to be specified before and after a package" $ 43 | theOptions "-p cowsay --command cowsay -p python" 44 | `shouldBe` 45 | Right def{_packages=setPackages [ "cowsay", "python" ], _command=Just "cowsay"} 46 | 47 | it "fails if command has no argument" $ 48 | shellifyWithArgs "--command" 49 | `shouldReturnSubstring` "expects an argument" 50 | 51 | it "supports specifying one program to install after other arguments" $ 52 | "foo -p python" 53 | `shouldResultInPackages` 54 | [ "python" ] 55 | 56 | it "supports multiple packages passed to -p" $ 57 | "-p python cowsay" 58 | `shouldResultInPackages` 59 | [ "cowsay", "python" ] 60 | 61 | it "only accepts packages up to the next switch" $ 62 | "-p python --arg x 2" 63 | `shouldResultInPackages` 64 | [ "python" ] 65 | 66 | it "supports multiple adjacent -p switches" $ 67 | "-p python -p cowsay" 68 | `shouldResultInPackages` 69 | [ "python", "cowsay" ] 70 | 71 | it "supports separated -p switches" $ 72 | "-p cowsay --arg 4 cowsay -p python" 73 | `shouldResultInPackages` 74 | [ "cowsay", "python" ] 75 | 76 | it "supports long switches" $ 77 | "--packages cowsay" 78 | `shouldResultInPackages` 79 | [ "cowsay" ] 80 | 81 | it "supports new shell commands" $ 82 | theOptions "shell nixpkgs#python nixpkgs#cowsay" 83 | `shouldBe` 84 | Right def{_packages=setPackages [ "nixpkgs#python", "nixpkgs#cowsay" ], _outputForm=Flake} 85 | 86 | it "supports the --with-flake option" $ 87 | theOptions "--with-flake -p python -p cowsay" 88 | `shouldBe` 89 | Right def{_packages=setPackages [ "python", "cowsay" ], _outputForm=Flake} 90 | 91 | describe "When dealing with multiple source repositories it should produce the correct output files for" $ do 92 | 93 | specify "one buildInput required from an unknown source" $ 94 | shellifyWithArgs "--with-flake shell foo#cowsay" 95 | `shouldReturnShellAndFlakeTextDefinedBy` 96 | "inputs-from-unknown-source" 97 | 98 | specify "two buildInputs required from two sources" $ 99 | shellifyWithArgs "--with-flake shell foo#cowsay nixpkgs#python" 100 | `shouldReturnShellAndFlakeTextDefinedBy` 101 | "inputs-from-know-and-unknown-sources" 102 | 103 | specify "2 buildInputs from one source" $ 104 | shellifyWithArgs "shell --with-flake python cowsay" 105 | `shouldReturnShellAndFlakeTextDefinedBy` 106 | "two-nixpkgs-inputs" 107 | 108 | specify "pulling from 2 different known sources" $ 109 | shellifyWithArgs "shell nixpkgs#python blender-bin#blender_3_5" 110 | `shouldReturnShellAndFlakeTextDefinedBy` 111 | "inputs-from-different-registries" 112 | 113 | specify "2 nixpkgs buildInputs" $ 114 | shellifyWithArgs "shell nixpkgs#python nixpkgs#cowsay" 115 | `shouldReturnShellTextDefinedBy` 116 | "two-nixpkgs-inputs" 117 | 118 | specify "multiple repos for known and unknown sources" $ 119 | shellifyWithArgs "shell nixpkgs#python foo#cowsay" 120 | `shouldReturnShellTextDefinedBy` 121 | "multiple-repository-sources" 122 | 123 | describe "Where repository URLs need retrieving from the Nix Registry" $ do 124 | 125 | it "falls through to global where system is local and global is available" $ 126 | whereALocalSystemAndFlakeGlobalNixpkgsExistsShellifyWithArgs "shell nixpkgs#cowsay" 127 | `shouldReturnShellAndFlakeTextDefinedBy` 128 | "cowsay-from-global-nixpkgs" 129 | 130 | it "prefers system to global where system is local and always-take-from-system-registry is specified" $ 131 | whereALocalSystemAndFlakeGlobalNixpkgsExistsShellifyWithArgs "--allow-local-pinned-registries-to-be-prioritized shell nixpkgs#cowsay" 132 | `shouldReturnShellAndFlakeTextDefinedBy` 133 | "cowsay-from-local-nixpkgs" 134 | 135 | it "uses the local url where system has a local URL and no user or global repository is available" $ 136 | whereALocalSystemNixpkgsExistsShellifyWithArgs "shell nixpkgs#cowsay" 137 | `shouldReturnShellAndFlakeTextDefinedBy` 138 | "cowsay-from-local-nixpkgs" 139 | 140 | it "uses the user registry when no system or global alternative exists" $ 141 | whereAUserNixpkgsExistsShellifyWithArgs "shell nixpkgs#cowsay" 142 | `shouldReturnShellAndFlakeTextDefinedBy` 143 | "cowsay-from-user-nixpkgs" 144 | 145 | it "uses the system custom registry when a system and then global alternative are defined" $ 146 | whereASystemAndGlobalCustomPkgsExistsShellifyWithArgs "shell custompkgs#cowsay" 147 | `shouldReturnShellAndFlakeTextDefinedBy` 148 | "cowsay-from-system-custompkgs" 149 | 150 | it "uses the system custom registry when a global and then system alternative are defined" $ 151 | whereAGlobalAndSystemCustomPkgsExistsShellifyWithArgs "shell custompkgs#cowsay" 152 | `shouldReturnShellAndFlakeTextDefinedBy` 153 | "cowsay-from-system-custompkgs" 154 | 155 | it "uses the system nixpkgs when a system and then global alternative exist" $ 156 | whereASystemAndGlobalNixpkgsExistsShellifyWithArgs "shell nixpkgs#cowsay" 157 | `shouldReturnShellAndFlakeTextDefinedBy` 158 | "cowsay-from-system-nixpkgs" 159 | 160 | it "uses the system nixpkgs when a global and then system alternative exist" $ 161 | whereAGlobalAndSystemNixpkgsExistsShellifyWithArgs "shell nixpkgs#cowsay" 162 | `shouldReturnShellAndFlakeTextDefinedBy` 163 | "cowsay-from-system-nixpkgs" 164 | 165 | it "uses the global nixpkgs when no alternative exists" $ 166 | whereOnlyAGlobalNixpkgsExistsShellifyWithArgs "shell nixpkgs#cowsay" 167 | `shouldReturnShellAndFlakeTextDefinedBy` 168 | "cowsay-from-global-nixpkgs" 169 | -------------------------------------------------------------------------------- /test/TestHelpers.hs: -------------------------------------------------------------------------------- 1 | module TestHelpers where 2 | 3 | import Prelude hiding (readFile, unlines, words) 4 | import Control.Monad ((>=>)) 5 | import Data.Default (Default(def)) 6 | import Data.Text (Text(), pack, unpack, unlines, words) 7 | import Data.Text.IO (readFile) 8 | import Data.Tuple.Extra (fst3) 9 | import Test.Hspec (Expectation(), expectationFailure, shouldBe, shouldContain) 10 | import Options.Applicative (ParserResult(Success, Failure, CompletionInvoked), ParserFailure (ParserFailure)) 11 | import Options.Applicative.Help.Pretty (prettyString) 12 | import Options.Applicative.Help.Types (ParserHelp(helpError)) 13 | import Options.Applicative.Extra (ParserFailure(execFailure)) 14 | 15 | import Options (Options(..), Packages(Packages), parseCommandLine, setPackages) 16 | import Shellify ( calculateExpectedFiles ) 17 | 18 | shouldReturnSubstring :: Either Text b -> [Char] -> Expectation 19 | shouldReturnSubstring shellifyOutput expectedSubstring = 20 | either 21 | ((`shouldContain` expectedSubstring) . unpack) 22 | (const (expectationFailure "expected Left but got Right")) 23 | shellifyOutput 24 | 25 | shellifyWithArgs :: Text -> Either Text [(Text, Text)] 26 | shellifyWithArgs = shellifyWithArgsWithDb realDbExample 27 | 28 | realDbExample :: [Text] 29 | realDbExample = 30 | [ "global flake:agda github:agda/agda" 31 | , "global flake:arion github:hercules-ci/arion" 32 | , "global flake:blender-bin github:edolstra/nix-warez?dir=blender" 33 | , "global flake:composable github:ComposableFi/composable" 34 | , "global flake:dreampkgs github:nix-community/dreampkgs" 35 | , "global flake:dwarffs github:edolstra/dwarffs" 36 | , "global flake:emacs-overlay github:nix-community/emacs-overlay" 37 | , "global flake:fenix github:nix-community/fenix" 38 | , "global flake:flake-parts github:hercules-ci/flake-parts" 39 | , "global flake:flake-utils github:numtide/flake-utils" 40 | , "global flake:gemini github:nix-community/flake-gemini" 41 | , "global flake:hercules-ci-effects github:hercules-ci/hercules-ci-effects" 42 | , "global flake:hercules-ci-agent github:hercules-ci/hercules-ci-agent" 43 | , "global flake:home-manager github:nix-community/home-manager" 44 | , "global flake:hydra github:NixOS/hydra" 45 | , "global flake:mach-nix github:DavHau/mach-nix" 46 | , "global flake:nimble github:nix-community/flake-nimble" 47 | , "global flake:nix github:NixOS/nix" 48 | , "global flake:nix-darwin github:LnL7/nix-darwin" 49 | , "global flake:nixops github:NixOS/nixops" 50 | , "global flake:nixos-hardware github:NixOS/nixos-hardware" 51 | , "global flake:nixos-homepage github:NixOS/nixos-homepage" 52 | , "global flake:nixos-search github:NixOS/nixos-search" 53 | , "global flake:nur github:nix-community/NUR" 54 | , "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable" 55 | , "global flake:templates github:NixOS/templates" 56 | , "global flake:patchelf github:NixOS/patchelf" 57 | , "global flake:poetry2nix github:nix-community/poetry2nix" 58 | , "global flake:nix-serve github:edolstra/nix-serve" 59 | , "global flake:nickel github:tweag/nickel" 60 | , "global flake:bundlers github:NixOS/bundlers" 61 | , "global flake:pridefetch github:SpyHoodle/pridefetch" 62 | , "global flake:systems github:nix-systems/default" 63 | , "global flake:helix github:helix-editor/helix" 64 | , "global flake:sops-nix github:Mic92/sops-nix" 65 | ] 66 | 67 | shellifyWithArgsWithDb :: [Text] -> Text -> Either Text [(Text, Text)] 68 | shellifyWithArgsWithDb customDb = 69 | parsedOptions >=> handleParse (calculateExpectedFiles (unlines customDb)) 70 | 71 | 72 | theOptions :: Text -> Either Text Options 73 | theOptions = either 74 | Left 75 | (handleParse id) 76 | . parsedOptions 77 | 78 | parsedOptions :: Text -> Either Text (ParserResult Options) 79 | parsedOptions = parseCommandLine . fmap unpack . words 80 | 81 | handleParse :: (t -> b) -> ParserResult t -> Either Text b 82 | handleParse succF = \case 83 | Success opts -> Right (succF opts) 84 | Failure (ParserFailure help) -> 85 | Left . ("parse Error: " <>) . pack . show . helpError . fst3 . help $ "" 86 | CompletionInvoked _-> Left "completion invoked" 87 | 88 | whereAUserNixpkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 89 | whereAUserNixpkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 90 | [ "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-global-registry" 91 | , "system flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-system-registry" 92 | , "user flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-user-registry" 93 | ] 94 | 95 | whereASystemAndGlobalCustomPkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 96 | whereASystemAndGlobalCustomPkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 97 | [ "global flake:custompkgs github:NixOS/custompkgs/custompkgs-global-registry" 98 | , "system flake:custompkgs github:NixOS/custompkgs/custompkgs-system-registry" 99 | , "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable" 100 | ] 101 | 102 | whereAGlobalAndSystemCustomPkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 103 | whereAGlobalAndSystemCustomPkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 104 | [ "system flake:custompkgs github:NixOS/custompkgs/custompkgs-system-registry" 105 | , "global flake:custompkgs github:NixOS/custompkgs/custompkgs-global-registry" 106 | , "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-unstable" 107 | ] 108 | 109 | whereASystemAndGlobalNixpkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 110 | whereASystemAndGlobalNixpkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 111 | [ "system flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-system-registry" 112 | , "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-global-registry" 113 | ] 114 | 115 | whereAGlobalAndSystemNixpkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 116 | whereAGlobalAndSystemNixpkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 117 | [ "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-global-registry" 118 | , "system flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-system-registry" 119 | ] 120 | 121 | whereOnlyAGlobalNixpkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 122 | whereOnlyAGlobalNixpkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 123 | [ "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-global-registry" 124 | ] 125 | 126 | whereALocalSystemAndFlakeGlobalNixpkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 127 | whereALocalSystemAndFlakeGlobalNixpkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 128 | [ "system flake:nixpkgs path:/local/nixpkgs/path" 129 | , "global flake:nixpkgs github:NixOS/nixpkgs/nixpkgs-global-registry" 130 | ] 131 | 132 | whereALocalSystemNixpkgsExistsShellifyWithArgs :: Text -> Either Text [(Text, Text)] 133 | whereALocalSystemNixpkgsExistsShellifyWithArgs = shellifyWithArgsWithDb 134 | [ "system flake:nixpkgs path:/local/nixpkgs/path" 135 | , "global flake:templates github:NixOS/templates" 136 | ] 137 | 138 | shouldReturnShellAndFlakeTextDefinedBy :: Either Text [(Text, Text)] -> FilePath -> Expectation 139 | shouldReturnShellAndFlakeTextDefinedBy result expectedOutput = 140 | do expShell <- readNixTemplate (shellFile expectedOutput) 141 | expFlake <- readNixTemplate (flakeFile expectedOutput) 142 | result `shouldBe` 143 | Right [("shell.nix", expShell),("flake.nix", expFlake)] 144 | 145 | shouldReturnShellTextDefinedBy result expectedOutput = 146 | do expShell <- readNixTemplate (shellFile expectedOutput) 147 | either 148 | (const $ expectationFailure "Expected Right but got Left") 149 | (\((fileName, shellNixOutput):_) -> 150 | do shellNixOutput `shouldBe` expShell 151 | fileName `shouldBe` "shell.nix") 152 | result 153 | 154 | shouldResultInPackages :: Text -> [Text] -> Expectation 155 | shouldResultInPackages parameters packages = 156 | theOptions parameters 157 | `shouldBe` 158 | Right def{_packages=setPackages packages} 159 | 160 | readNixTemplate :: FilePath -> IO Text 161 | readNixTemplate = readFile . ("test/outputs/" <>) 162 | 163 | flakeFile :: FilePath -> FilePath 164 | flakeFile = (<> "-flake.nix") 165 | shellFile = (<> "-shell.nix") 166 | 167 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /docs/src/flake-demo-nix-expert.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 81, "height": 23, "timestamp": 1691249028, "env": {"SHELL": "/run/current-system/sw/bin/bash", "TERM": "xterm-256color"}} 2 | [0.025452,"o","\u001b[1m"] 3 | [0.545246, "o", "#"] 4 | [1.616772, "o", " "] 5 | [2.005623, "o", "I"] 6 | [2.559145, "o", "'"] 7 | [3.015139, "o", "v"] 8 | [3.125394, "o", "e"] 9 | [3.185992, "o", " "] 10 | [3.452956, "o", "b"] 11 | [3.634474, "o", "e"] 12 | [3.801095, "o", "e"] 13 | [3.931131, "o", "n"] 14 | [4.08985, "o", " "] 15 | [4.331685, "o", "g"] 16 | [4.452262, "o", "i"] 17 | [4.724968, "o", "v"] 18 | [5.208463, "o", "e"] 19 | [6.208463, "o", "n"] 20 | [6.35495, "o", " "] 21 | [6.491909, "o", "a"] 22 | [6.611608, "o", " "] 23 | [6.794379, "o", "s"] 24 | [7.020168, "o", "c"] 25 | [7.243978, "o", "r"] 26 | [7.338664, "o", "i"] 27 | [7.385282, "o", "p"] 28 | [7.571714, "o", "t"] 29 | [8.112258, "o", " "] 30 | [8.303891, "o", "t"] 31 | [8.389711, "o", "o"] 32 | [8.459532, "o", " "] 33 | [8.671937, "o", "r"] 34 | [8.933792, "o", "u"] 35 | [9.441343, "o", "n"] 36 | [9.899768, "o", "."] 37 | [10.073348, "o", " "] 38 | [10.410073, "o", "L"] 39 | [10.551942, "o", "e"] 40 | [10.657416, "o", "t"] 41 | [10.995129, "o", "'"] 42 | [11.093721, "o", "s"] 43 | [11.263843, "o", " "] 44 | [11.794029, "o", "t"] 45 | [11.969165, "o", "r"] 46 | [12.060043, "o", "y"] 47 | [12.540793, "o", "."] 48 | [12.696561, "o", "."] 49 | [12.862771, "o", "."] 50 | [12.862771, "o","\u001b[0m"] 51 | [13.610667, "o", "\r\n\u001b[?2004l\r"] 52 | [13.618958, "o", "\u001b[?2004h$ "] 53 | [14.71055, "o", "."] 54 | [14.765938, "o", "/"] 55 | [15.098462, "o", "u"] 56 | [15.141687, "o", "p"] 57 | [15.257083, "o", "dateScript "] 58 | [15.790737, "o", "\r\n\u001b[?2004l\r"] 59 | [15.799238, "o", "./updateScript: line 5: aws: command not found\r\n"] 60 | [15.802946, "o", "\u001b[?2004h$ "] 61 | [18.482113,"o","\u001b[1m"] 62 | [18.482113, "o", "#"] 63 | [18.854955, "o", " "] 64 | [19.199859, "o", "N"] 65 | [19.35125, "o", "o"] 66 | [19.496623, "o", " "] 67 | [19.597289, "o", "p"] 68 | [19.753675, "o", "r"] 69 | [19.804468, "o", "o"] 70 | [20.015979, "o", "b"] 71 | [20.218915, "o", "l"] 72 | [20.390047, "o", "e"] 73 | [20.516127, "o", "m"] 74 | [21.090279, "o", "."] 75 | [21.285192, "o", " "] 76 | [21.742555, "o", "N"] 77 | [21.949061, "o", "i"] 78 | [22.105239, "o", "x"] 79 | [22.242911, "o", " "] 80 | [22.344696, "o", "s"] 81 | [22.459937, "o", "h"] 82 | [22.595957, "o", "e"] 83 | [22.772354, "o", "l"] 84 | [22.91875, "o", "l"] 85 | [23.053979, "o", " "] 86 | [23.308684, "o", "t"] 87 | [23.459071, "o", "o"] 88 | [23.681758, "o", " "] 89 | [24.114004, "o", "t"] 90 | [24.23953, "o", "h"] 91 | [24.334144, "o", "e"] 92 | [24.444126, "o", " "] 93 | [24.589977, "o", "r"] 94 | [24.766133, "o", "e"] 95 | [25.009239, "o", "s"] 96 | [25.199115, "o", "c"] 97 | [25.388222, "o", "u"] 98 | [25.49595, "o", "e"] 99 | [25.717053, "o", "."] 100 | [25.864141, "o", "."] 101 | [26.035111, "o", "."] 102 | [26.035111,"o","\u001b[0m"] 103 | [27.029402, "o", "\r\n"] 104 | [27.029451, "o", "\u001b[?2004l\r"] 105 | [27.037761, "o", "\u001b[?2004h$ "] 106 | [27.782278, "o", "n"] 107 | [27.827452, "o", "i"] 108 | [27.968548, "o", "x"] 109 | [28.104711, "o", " "] 110 | [28.199505, "o", "s"] 111 | [28.334445, "o", "h"] 112 | [28.434336, "o", "e"] 113 | [28.595988, "o", "l"] 114 | [28.715826, "o", "l"] 115 | [29.45383, "o", " "] 116 | [29.871827, "o", "n"] 117 | [29.92826, "o", "i"] 118 | [30.067991, "o", "x"] 119 | [31.284289, "o", "p"] 120 | [31.410088, "o", "kgs "] 121 | [32.027109, "o", "\b\u001b[K"] 122 | [32.213679, "o", "#"] 123 | [33.177678, "o", "a"] 124 | [33.457828, "o", "w"] 125 | [33.612347, "o", "s"] 126 | [33.81439, "o", "c"] 127 | [33.926312, "o", "l"] 128 | [34.096485, "o", "i"] 129 | [35.196631, "o", "\r\n"] 130 | [35.196859, "o", "\u001b[?2004l\r"] 131 | [35.223716, "o", "\r\u001b[0m\u001b[K"] 132 | [35.273913, "o", "\r[\u001b[32;1m0\u001b[0m/1 built] \u001b[0m\u001b[K"] 133 | [35.28722, "o", "\r\u001b[K"] 134 | [35.309073, "o", "\u001b[?2004h"] 135 | [35.309101, "o", "$ "] 136 | [35.309101,"o","\u001b[1m"] 137 | [38.053799, "o", "#"] 138 | [38.275755, "o", " "] 139 | [38.540073, "o", "N"] 140 | [38.720935, "o", "o"] 141 | [38.867872, "o", "w"] 142 | [38.953928, "o", " "] 143 | [39.175351, "o", "I"] 144 | [39.390453, "o", " "] 145 | [40.400668, "o", "h"] 146 | [40.476192, "o", "a"] 147 | [40.691385, "o", "v"] 148 | [40.785724, "o", "e"] 149 | [40.881588, "o", " "] 150 | [40.969531, "o", "a"] 151 | [41.554169, "o", "w"] 152 | [42.213225, "o", "s"] 153 | [43.077139, "o", "c"] 154 | [43.198529, "o", "l"] 155 | [43.425073, "o", "i"] 156 | [43.956869, "o", " "] 157 | [45.808989, "o", "l"] 158 | [45.935016, "o", "e"] 159 | [46.009961, "o", "t"] 160 | [46.297827, "o", "'"] 161 | [46.418292, "o", "s"] 162 | [46.545308, "o", " "] 163 | [46.737542, "o", "t"] 164 | [46.918761, "o", "r"] 165 | [47.010064, "o", "y"] 166 | [47.115338, "o", " "] 167 | [47.342376, "o", "a"] 168 | [47.889049, "o", "g"] 169 | [48.004327, "o", "a"] 170 | [48.185417, "o", "i"] 171 | [48.251418, "o", "n"] 172 | [48.467166, "o", "."] 173 | [48.608775, "o", "."] 174 | [49.204424, "o", "."] 175 | [49.204424, "o","\u001b[0m"] 176 | [50.008034, "o", "\r\n"] 177 | [50.008254, "o", "\u001b[?2004l\r"] 178 | [50.015922, "o", "\u001b[?2004h$ "] 179 | [50.775917, "o", "."] 180 | [50.83596, "o", "/"] 181 | [51.203853, "o", "u"] 182 | [51.27388, "o", "p"] 183 | [51.394817, "o", "dateScript "] 184 | [52.77408, "o", "\r\n"] 185 | [52.774282, "o", "\u001b[?2004l\r"] 186 | [53.082466, "o", "./updateScript: line 7: jq: command not found\r\n"] 187 | [53.086117, "o", "\u001b[?2004h$ "] 188 | [53.086117, "o", "\u001b[1m"] 189 | [54.631092, "o", "#"] 190 | [54.808749, "o", " "] 191 | [55.080798, "o", "O"] 192 | [55.36309, "o", "k"] 193 | [55.665266, "o", "."] 194 | [55.843467, "o", " "] 195 | [56.140223, "o", "W"] 196 | [56.326791, "o", "e"] 197 | [56.438618, "o", " "] 198 | [56.649302, "o", "n"] 199 | [56.788061, "o", "e"] 200 | [56.938747, "o", "e"] 201 | [57.125619, "o", "d"] 202 | [57.396728, "o", " "] 203 | [58.165144, "o", "j"] 204 | [58.366163, "o", "q"] 205 | [58.5225, "o", " "] 206 | [58.872318, "o", "t"] 207 | [59.078562, "o", "o"] 208 | [59.194257, "o", "o"] 209 | [59.405347, "o", "."] 210 | [59.623127, "o", " "] 211 | [59.962232, "o", "L"] 212 | [60.159831, "o", "e"] 213 | [60.260076, "o", "t"] 214 | [60.461508, "o", "'"] 215 | [60.57668, "o", "s"] 216 | [61.344378, "o", " "] 217 | [62.580437, "o", "e"] 218 | [62.845478, "o", "x"] 219 | [63.006252, "o", "i"] 220 | [63.128276, "o", "t"] 221 | [63.217468, "o", " "] 222 | [63.874713, "o", "t"] 223 | [64.010829, "o", "h"] 224 | [64.06119, "o", "i"] 225 | [64.171535, "o", "s"] 226 | [64.282557, "o", " "] 227 | [64.393693, "o", "s"] 228 | [64.710282, "o", "h"] 229 | [64.810725, "o", "e"] 230 | [65.241394, "o", "l"] 231 | [65.387296, "o", "l"] 232 | [65.538498, "o", " "] 233 | [65.649477, "o", "a"] 234 | [65.831135, "o", "n"] 235 | [65.886203, "o", "d"] 236 | [66.002679, "o", " "] 237 | [66.10554, "o", "a"] 238 | [66.352134, "o", "d"] 239 | [66.507049, "o", "d"] 240 | [66.578564, "o", " "] 241 | [66.780563, "o", "j"] 242 | [67.709241, "o", "q"] 243 | [67.951551, "o", "."] 244 | [68.11275, "o", "."] 245 | [68.248427, "o", "."] 246 | [68.248427, "o", "\u001b[0m"] 247 | [69.248114, "o", "\r\n"] 248 | [69.248333, "o", "\u001b[?2004l\r"] 249 | [69.248333, "o", "$ "] 250 | [69.876859, "o", "e"] 251 | [70.101118, "o", "x"] 252 | [70.246885, "o", "i"] 253 | [70.417835, "o", "t"] 254 | [71.438092, "o", "\r\n"] 255 | [71.438279, "o", "\u001b[?2004l\rexit\r\n"] 256 | [71.448002, "o", "\u001b[?2004h$ "] 257 | [72.309509, "o", "nix shell nixpkgs#awscli"] 258 | [73.044329, "o", " "] 259 | [73.73396, "o", "n"] 260 | [73.790055, "o", "i"] 261 | [73.965788, "o", "x"] 262 | [74.159781, "o", "p"] 263 | [74.386033, "o", "k"] 264 | [74.553593, "o", "gs "] 265 | [74.95025, "o", "\b\u001b[K"] 266 | [75.501453, "o", "#"] 267 | [76.415524, "o", "j"] 268 | [76.707694, "o", "q"] 269 | [77.661758, "o", "\r\n"] 270 | [77.662164, "o", "\u001b[?2004l\r"] 271 | [77.685427, "o", "\r\u001b[0m\u001b[K"] 272 | [77.735517, "o", "\r[\u001b[32;1m0\u001b[0m/2 built] \u001b[0m\u001b[K"] 273 | [77.751391, "o", "\r\u001b[K"] 274 | [77.774122, "o", "\u001b[?2004h"] 275 | [77.774175, "o", "$ "] 276 | [77.774175, "o", "\u001b[1m"] 277 | [79.544711, "o", "#"] 278 | [79.705844, "o", " "] 279 | [80.267046, "o", "N"] 280 | [80.453509, "o", "o"] 281 | [80.630218, "o", "w"] 282 | [80.739757, "o", " "] 283 | [80.92631, "o", "I"] 284 | [81.044933, "o", " "] 285 | [81.26113, "o", "h"] 286 | [81.33663, "o", "a"] 287 | [81.502827, "o", "v"] 288 | [81.558134, "o", "e"] 289 | [81.658868, "o", " "] 290 | [82.824739, "o", "b"] 291 | [82.895109, "o", "o"] 292 | [83.056212, "o", "t"] 293 | [83.147445, "o", "h"] 294 | [83.264235, "o", " "] 295 | [83.854463, "o", "l"] 296 | [84.048203, "o", "e"] 297 | [84.127107, "o", "t"] 298 | [84.242407, "o", "'"] 299 | [84.405277, "o", "s"] 300 | [84.526402, "o", " "] 301 | [84.854226, "o", "t"] 302 | [85.020005, "o", "r"] 303 | [85.10058, "o", "y"] 304 | [85.191278, "o", " "] 305 | [85.292461, "o", "a"] 306 | [85.440441, "o", "g"] 307 | [85.54461, "o", "a"] 308 | [85.78906, "o", "i"] 309 | [85.913873, "o", "n"] 310 | [86.388859, "o", "."] 311 | [86.555228, "o", "."] 312 | [86.751399, "o", "."] 313 | [86.751399, "o", "\u001b[0m"] 314 | [88.186799, "o", "\r\n"] 315 | [88.187035, "o", "\u001b[?2004l\r"] 316 | [88.195185, "o", "\u001b[?2004h$ "] 317 | [88.697653, "o", "."] 318 | [88.727448, "o", "/"] 319 | [89.059618, "o", "u"] 320 | [89.110301, "o", "p"] 321 | [89.262432, "o", "dateScript "] 322 | [91.174195, "o", "\r\n"] 323 | [91.17434, "o", "\u001b[?2004l\r"] 324 | [91.79766, "o", "Update succeeded\r\n"] 325 | [91.804796, "o", "\u001b[?2004h$ "] 326 | [91.804796, "o", "\u001b[1m"] 327 | [93.695441, "o", "#"] 328 | [93.835768, "o", " "] 329 | [94.092726, "o", "G"] 330 | [94.379542, "o", "r"] 331 | [94.583709, "o", "e"] 332 | [94.709452, "o", "a"] 333 | [94.906885, "o", "t"] 334 | [95.092382, "o", " "] 335 | [95.723445, "o", "i"] 336 | [95.834553, "o", "t"] 337 | [95.924826, "o", " "] 338 | [96.242484, "o", "w"] 339 | [96.328016, "o", "o"] 340 | [96.536755, "o", "r"] 341 | [96.602658, "o", "k"] 342 | [96.781195, "o", "s"] 343 | [97.104162, "o", "."] 344 | [97.275907, "o", " "] 345 | [97.614559, "o", "I"] 346 | [97.719945, "o", " "] 347 | [97.810781, "o", "s"] 348 | [97.965587, "o", "h"] 349 | [98.917194, "o", "o"] 350 | [98.981666, "o", "u"] 351 | [99.077573, "o", "l"] 352 | [99.56802, "o", "d"] 353 | [101.054482, "o", " "] 354 | [101.411489, "o", "n"] 355 | [101.461935, "o", "o"] 356 | [102.557428, "o", "w"] 357 | [102.668384, "o", " "] 358 | [103.036385, "o", "c"] 359 | [103.423564, "o", "r"] 360 | [103.710455, "o", "e"] 361 | [103.866709, "o", "a"] 362 | [103.992319, "o", "t"] 363 | [104.118723, "o", "e"] 364 | [104.768332, "o", " "] 365 | [104.944298, "o", "a"] 366 | [105.085302, "o", " "] 367 | [105.337203, "o", "s"] 368 | [105.463266, "o", "h"] 369 | [105.588922, "o", "e"] 370 | [106.028175, "o", "l"] 371 | [106.163049, "o", "l"] 372 | [106.369554, "o", "."] 373 | [106.692569, "o", "n"] 374 | [106.767419, "o", "i"] 375 | [106.90839, "o", "x"] 376 | [107.80766, "o", " "] 377 | [108.326272, "o", "f"] 378 | [108.401029, "o", "i"] 379 | [108.457055, "o", "l"] 380 | [108.552388, "o", "e"] 381 | [108.696102, "o", "."] 382 | [109.29577, "o", " "] 383 | [109.750797, "o", "I"] 384 | [109.877115, "o", " "] 385 | [110.038188, "o", "a"] 386 | [110.174158, "o", "l"] 387 | [110.28995, "o", "w"] 388 | [110.451298, "o", "a"] 389 | [110.591418, "o", "y"] 390 | [110.67249, "o", "s"] 391 | [110.761368, "o", " "] 392 | [111.238421, "o", "p"] 393 | [111.354733, "o", "u"] 394 | [111.506176, "o", "t"] 395 | [111.59673, "o", " "] 396 | [111.720169, "o", "t"] 397 | [111.770396, "o", "h"] 398 | [111.841796, "o", "i"] 399 | [111.957067, "o", "s"] 400 | [112.065222, "o", " "] 401 | [112.340785, "o", "o"] 402 | [112.567129, "o", "f"] 403 | [112.702036, "o", "f"] 404 | [113.555134, "o", "!"] 405 | [113.555134, "o", "\u001b[0m"] 406 | [115.378232, "o", "\r\n"] 407 | [115.378449, "o", "\u001b[?2004l\r"] 408 | [115.386213, "o", "\u001b[?2004h$ "] 409 | [115.386213, "o", "\u001b[1m"] 410 | [116.18611, "o", "#"] 411 | [116.342943, "o", " "] 412 | [116.979396, "o", "N"] 413 | [117.151788, "o", "o"] 414 | [117.297335, "o", "w"] 415 | [118.533319, "o", " "] 416 | [118.694139, "o", "t"] 417 | [118.765738, "o", "h"] 418 | [118.90823, "o", "e"] 419 | [119.090512, "o", "r"] 420 | [119.225067, "o", "e"] 421 | [119.307106, "o", "'"] 422 | [119.436755, "o", "s"] 423 | [119.998553, "o", " "] 424 | [120.119354, "o", "a"] 425 | [120.633446, "o", "n"] 426 | [121.345406, "o", " "] 427 | [121.512932, "o", "e"] 428 | [121.732993, "o", "a"] 429 | [121.89898, "o", "s"] 430 | [122.050033, "o", "y"] 431 | [122.131059, "o", " "] 432 | [122.342628, "o", "w"] 433 | [122.694827, "o", "a"] 434 | [123.368205, "o", "y"] 435 | [123.368205, "o", "\u001b[0m"] 436 | [124.195479, "o", "\r\n"] 437 | [124.195746, "o", "\u001b[?2004l\r"] 438 | [124.203788, "o", "\u001b[?2004h$ "] 439 | [124.203788, "o", "\u001b[1m"] 440 | [124.948467, "o", "#"] 441 | [125.133951, "o", " "] 442 | [125.814752, "o", "W"] 443 | [126.039133, "o", "i"] 444 | [126.159282, "o", "t"] 445 | [126.255666, "o", "h"] 446 | [126.345569, "o", " "] 447 | [127.169691, "o", "s"] 448 | [127.340447, "o", "h"] 449 | [127.446242, "o", "e"] 450 | [127.602315, "o", "l"] 451 | [127.723383, "o", "l"] 452 | [127.875079, "o", "i"] 453 | [128.043474, "o", "f"] 454 | [128.153562, "o", "y"] 455 | [128.26698, "o", " "] 456 | [129.369774, "o", "I"] 457 | [129.485551, "o", " "] 458 | [129.641702, "o", "c"] 459 | [129.703027, "o", "a"] 460 | [129.822997, "o", "n"] 461 | [129.955411, "o", " "] 462 | [130.350353, "o", "j"] 463 | [130.500428, "o", "u"] 464 | [130.627197, "o", "s"] 465 | [130.727008, "o", "t"] 466 | [131.123908, "o", " "] 467 | [131.248869, "o", "s"] 468 | [131.52026, "o", "w"] 469 | [131.722182, "o", "a"] 470 | [131.873655, "o", "p"] 471 | [132.018742, "o", " "] 472 | [132.181011, "o", "o"] 473 | [132.271833, "o", "u"] 474 | [132.396614, "o", "t"] 475 | [133.22515, "o", " "] 476 | [133.598252, "o", "n"] 477 | [133.648143, "o", "i"] 478 | [133.794572, "o", "x"] 479 | [133.915344, "o", " "] 480 | [134.925033, "o", "f"] 481 | [135.016704, "o", "o"] 482 | [135.153586, "o", "r"] 483 | [135.345249, "o", " "] 484 | [135.793866, "o", "n"] 485 | [135.833537, "o", "i"] 486 | [136.133093, "o", "x"] 487 | [136.239795, "o", "-"] 488 | [136.441387, "o", "s"] 489 | [136.551038, "o", "h"] 490 | [136.671401, "o", "e"] 491 | [136.797719, "o", "l"] 492 | [136.903241, "o", "l"] 493 | [137.097134, "o", "i"] 494 | [137.273396, "o", "f"] 495 | [137.399049, "o", "y"] 496 | [137.807455, "o", " "] 497 | [137.928297, "o", "a"] 498 | [138.06004, "o", "n"] 499 | [138.141294, "o", "d"] 500 | [138.248138, "o", " "] 501 | [138.414261, "o", "w"] 502 | [138.610665, "o", "e"] 503 | [138.748471, "o", "'"] 504 | [138.83229, "o", "r"] 505 | [138.998896, "o", "e"] 506 | [139.109742, "o", " "] 507 | [139.488701, "o", "g"] 508 | [139.670629, "o", "o"] 509 | [139.787871, "o", "o"] 510 | [139.927937, "o", "d"] 511 | [140.307968, "o", "."] 512 | [140.454173, "o", "."] 513 | [140.604787, "o", "."] 514 | [140.604787, "o", "\u001b[0m"] 515 | [142.372488, "o", "\r\n"] 516 | [142.372574, "o", "\u001b[?2004l\r"] 517 | [142.380945, "o", "\u001b[?2004h$ "] 518 | [145.925189, "o", "e"] 519 | [146.136583, "o", "x"] 520 | [146.2752, "o", "i"] 521 | [146.400729, "o", "t"] 522 | [147.589613, "o", "\r\n\u001b[?2004l\r"] 523 | [147.589852, "o", "exit\r\n"] 524 | [147.599231, "o", "\u001b[?2004h$ "] 525 | [148.506072, "o", "nix shell nixpkgs#awscli nixpkgs#jq"] 526 | [150.553695, "o", "\b\r\u001b[C\u001b[C"] 527 | [151.29866, "o", "\u001b[C\u001b[C"] 528 | [151.772204, "o", "\u001b[C"] 529 | [152.255292, "o", "\u001b[1@-"] 530 | [152.529768, "o", "\u001b[1@s"] 531 | [152.695701, "o", "\u001b[1@h"] 532 | [152.777375, "o", "\u001b[1@e"] 533 | [152.988276, "o", "\u001b[1@l"] 534 | [153.114444, "o", "\u001b[1@l"] 535 | [153.402956, "o", "\u001b[1@i"] 536 | [153.602142, "o", "\u001b[2@fy"] 537 | [154.73017, "o", "\r\n"] 538 | [154.730459, "o", "\u001b[?2004l\r"] 539 | [154.760524, "o", "shell.nix does not exist. Creating one\r\n"] 540 | [154.761035, "o", "flake.nix d"] 541 | [154.761182, "o", "oes not exist. Creating one\r\n"] 542 | [154.765663, "o", "\u001b[?2004h$ "] 543 | [157.026712, "o", "l"] 544 | [157.117015, "o", "s"] 545 | [157.83395, "o", "\r\n"] 546 | [157.834085, "o", "\u001b[?2004l\r"] 547 | [157.835913, "o", "flake.nix shell.nix \u001b[0m\u001b[01;32mupdateScript\u001b[0m\r\n"] 548 | [157.840847, "o", "\u001b[?2004h$ "] 549 | [157.840847, "o", "\u001b[1m"] 550 | [159.35788, "o", "#"] 551 | [159.507212, "o", " "] 552 | [159.712472, "o", "C"] 553 | [159.875402, "o", "o"] 554 | [160.020272, "o", "o"] 555 | [160.211837, "o", "l"] 556 | [161.080132, "o", "."] 557 | [161.240918, "o", " "] 558 | [163.590635, "o", "I"] 559 | [163.76193, "o", " "] 560 | [163.938152, "o", "h"] 561 | [164.054046, "o", "a"] 562 | [164.177965, "o", "v"] 563 | [164.381387, "o", "e"] 564 | [164.715739, "o", " "] 565 | [164.841749, "o", "a"] 566 | [164.948562, "o", " "] 567 | [165.19934, "o", "s"] 568 | [165.335156, "o", "h"] 569 | [165.436864, "o", "e"] 570 | [165.594751, "o", "l"] 571 | [165.720087, "o", "l"] 572 | [165.917253, "o", "."] 573 | [166.229249, "o", "n"] 574 | [166.310158, "o", "i"] 575 | [166.430763, "o", "x"] 576 | [166.665642, "o", " "] 577 | [166.785723, "o", "a"] 578 | [166.937433, "o", "n"] 579 | [166.9925, "o", "d"] 580 | [167.142756, "o", " "] 581 | [167.593801, "o", "i"] 582 | [167.684263, "o", "t"] 583 | [167.836608, "o", "'"] 584 | [167.951604, "o", "s"] 585 | [168.072315, "o", " "] 586 | [168.693688, "o", "e"] 587 | [168.900874, "o", "v"] 588 | [168.991569, "o", "e"] 589 | [169.32868, "o", "n"] 590 | [169.52005, "o", " "] 591 | [170.055842, "o", "l"] 592 | [170.222002, "o", "o"] 593 | [170.358417, "o", "c"] 594 | [170.478929, "o", "k"] 595 | [170.658321, "o", "e"] 596 | [170.874832, "o", "d"] 597 | [171.01041, "o", " "] 598 | [171.479069, "o", "d"] 599 | [171.579583, "o", "o"] 600 | [171.689317, "o", "w"] 601 | [171.934325, "o", "n"] 602 | [172.095531, "o", " "] 603 | [172.372783, "o", "w"] 604 | [172.528623, "o", "i"] 605 | [172.716949, "o", "t"] 606 | [172.863647, "o", "h"] 607 | [172.925262, "o", " "] 608 | [173.064825, "o", "a"] 609 | [173.170521, "o", " "] 610 | [173.533224, "o", "f"] 611 | [173.647028, "o", "l"] 612 | [173.717255, "o", "a"] 613 | [173.878256, "o", "k"] 614 | [173.980095, "o", "e"] 615 | [174.009117, "o", "."] 616 | [174.165125, "o", " "] 617 | [175.945133, "o", "L"] 618 | [176.196856, "o", "e"] 619 | [176.352856, "o", "t"] 620 | [176.665275, "o", "'"] 621 | [176.778633, "o", "s"] 622 | [176.92048, "o", " "] 623 | [177.906832, "o", "t"] 624 | [178.067528, "o", "r"] 625 | [178.138272, "o", "y"] 626 | [178.657276, "o", "."] 627 | [178.81537, "o", "."] 628 | [178.981616, "o", "."] 629 | [178.981616, "o", "\u001b[0m"] 630 | [178.981616, "o", "\r\n\u001b[?2004l\r"] 631 | [178.981616, "o", "\u001b[?2004h"] 632 | [179.000000, "o", "$ "] 633 | [180.77085, "o", "n"] 634 | [180.815283, "o", "i"] 635 | [180.871188, "o", "x"] 636 | [181.017626, "o", " "] 637 | [181.108214, "o", "d"] 638 | [181.299445, "o", "e"] 639 | [181.485427, "o", "v"] 640 | [181.561248, "o", "e"] 641 | [181.692622, "o", "l"] 642 | [181.853125, "o", "o"] 643 | [181.929718, "o", "p"] 644 | [183.749049, "o", "\r\n"] 645 | [183.749143, "o", "\u001b[?2004l\r"] 646 | [183.768163, "o", "\r\u001b[0m\u001b[K"] 647 | [183.818264, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 648 | [183.868393, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 649 | [183.918524, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 650 | [183.968851, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 651 | [184.018966, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 652 | [184.068983, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 653 | [184.119191, "o", "\rdownloading 'https://api.github.com/repos/numtide/flake-utils/commits/HEAD'\u001b[0m\u001b[K"] 654 | [184.138462, "o", "\r\u001b[K\u001b[35;1mwarning:\u001b[0m creating lock file '/home/dan/repos/updateScript/flake.lock'\u001b[0m\r\n\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 655 | [184.169323, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 656 | [184.219442, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 657 | [184.269426, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 658 | [184.319542, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 659 | [184.369661, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 660 | [184.419768, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 661 | [184.469866, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 662 | [184.519936, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 663 | [184.570015, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 664 | [184.620083, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 665 | [184.670163, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 666 | [184.720255, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 667 | [184.770351, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 668 | [184.820416, "o", "\revaluating derivation 'path:/home/dan/repos/updateScript#devShells.x86_64-linux.d\u001b[0m\u001b[K"] 669 | [184.870541, "o", "\r[\u001b[32;1m0\u001b[0m/1 built] \u001b[0m\u001b[K"] 670 | [184.894248, "o", "\r\u001b[K"] 671 | [184.935666, "o", "\u001b[?2004h"] 672 | [184.935699, "o", "$ "] 673 | [185.825131, "o", "."] 674 | [185.891866, "o", "/"] 675 | [186.23956, "o", "u"] 676 | [186.305601, "o", "p"] 677 | [186.395521, "o", "dateScript "] 678 | [187.911341, "o", "\r\n\u001b[?2004l\r"] 679 | [188.282684, "o", "Update succeeded\r\n"] 680 | [188.28649, "o", "\u001b[?2004h$ "] 681 | [188.28649, "o", "\u001b[1m"] 682 | [189.706691, "o", "#"] 683 | [189.868739, "o", " "] 684 | [190.118691, "o", "I"] 685 | [190.283521, "o", "t"] 686 | [190.902254, "o", " "] 687 | [191.892576, "o", "w"] 688 | [192.169538, "o", "o"] 689 | [192.280305, "o", "r"] 690 | [192.462388, "o", "k"] 691 | [193.567677, "o", "s"] 692 | [193.732854, "o", "!"] 693 | [193.732854, "o", "\u001b[0m"] 694 | [194.384737, "o", "\r\n"] 695 | [194.385046, "o", "\u001b[?2004l\r"] 696 | [194.393951, "o", "\u001b[?2004h$ "] 697 | [194.393951, "o", "\u001b[1m"] 698 | [194.893343, "o", "#"] 699 | [195.043445, "o", " "] 700 | [195.27437, "o", "N"] 701 | [195.439299, "o", "o"] 702 | [195.565289, "o", "w"] 703 | [195.691235, "o", " "] 704 | [195.957441, "o", "I"] 705 | [196.079396, "o", " "] 706 | [196.229759, "o", "c"] 707 | [196.297664, "o", "a"] 708 | [196.388432, "o", "n"] 709 | [196.519443, "o", " "] 710 | [196.745954, "o", "c"] 711 | [196.867005, "o", "o"] 712 | [197.053319, "o", "m"] 713 | [197.176727, "o", "m"] 714 | [197.354372, "o", "i"] 715 | [197.479052, "o", "t"] 716 | [197.584881, "o", " "] 717 | [197.700418, "o", "t"] 718 | [197.81622, "o", "h"] 719 | [197.902225, "o", "e"] 720 | [197.9879, "o", " "] 721 | [198.498403, "o", "f"] 722 | [198.574163, "o", "l"] 723 | [198.649203, "o", "a"] 724 | [198.956453, "o", "k"] 725 | [199.022098, "o", "e"] 726 | [199.806433, "o", " "] 727 | [199.891954, "o", "a"] 728 | [200.0271, "o", "n"] 729 | [200.140522, "o", "d"] 730 | [200.208298, "o", " "] 731 | [200.692343, "o", "s"] 732 | [200.788364, "o", "h"] 733 | [200.963675, "o", "e"] 734 | [201.63162, "o", "l"] 735 | [201.762119, "o", "l"] 736 | [202.140017, "o", " "] 737 | [202.470006, "o", "f"] 738 | [202.549984, "o", "i"] 739 | [202.610621, "o", "l"] 740 | [202.711094, "o", "e"] 741 | [202.897854, "o", "s"] 742 | [203.00274, "o", " "] 743 | [203.39158, "o", "k"] 744 | [203.63829, "o", "n"] 745 | [203.85989, "o", "o"] 746 | [204.015571, "o", "w"] 747 | [204.162135, "o", "i"] 748 | [204.234736, "o", "n"] 749 | [204.390986, "o", "g"] 750 | [204.501925, "o", " "] 751 | [205.531466, "o", "i"] 752 | [205.628296, "o", "t"] 753 | [205.778472, "o", "'"] 754 | [206.181266, "o", "l"] 755 | [206.390244, "o", "l"] 756 | [207.019087, "o", " "] 757 | [208.475839, "o", "r"] 758 | [208.627081, "o", "u"] 759 | [208.762884, "o", "n"] 760 | [208.837849, "o", " "] 761 | [209.004621, "o", "n"] 762 | [209.089303, "o", "e"] 763 | [209.308617, "o", "x"] 764 | [209.424725, "o", "t"] 765 | [209.495267, "o", " "] 766 | [210.220399, "o", "t"] 767 | [210.321038, "o", "i"] 768 | [210.386859, "o", "m"] 769 | [210.527653, "o", "e"] 770 | [210.638415, "o", " "] 771 | [210.698856, "o", "f"] 772 | [210.839754, "o", "o"] 773 | [210.910091, "o", "r"] 774 | [212.325392, "o", " "] 775 | [212.541721, "o", "m"] 776 | [212.622491, "o", "e"] 777 | [212.748593, "o", " "] 778 | [212.954532, "o", "a"] 779 | [213.080228, "o", "n"] 780 | [213.15163, "o", "d"] 781 | [213.241464, "o", " "] 782 | [213.395256, "o", "o"] 783 | [213.562027, "o", "t"] 784 | [213.697753, "o", "h"] 785 | [213.778375, "o", "e"] 786 | [213.828605, "o", "r"] 787 | [214.00016, "o", "s"] 788 | [214.311746, "o", "!"] 789 | [214.311746, "o", "\u001b[0m"] 790 | [214.953966, "o", "\r\n"] 791 | [214.954031, "o", "\u001b[?2004l\r"] 792 | [214.962982, "o", "\u001b[?2004h$ "] 793 | [214.962982, "o", "\u001b[1m"] 794 | [215.430655, "o", "#"] 795 | [215.56536, "o", " "] 796 | [215.938972, "o", "A"] 797 | [216.15512, "o", "n"] 798 | [216.255964, "o", "d"] 799 | [216.371863, "o", " "] 800 | [216.908285, "o", "I"] 801 | [217.013774, "o", " "] 802 | [217.144686, "o", "c"] 803 | [217.219632, "o", "a"] 804 | [217.327656, "o", "n"] 805 | [217.872517, "o", " "] 806 | [219.091765, "o", "c"] 807 | [219.216832, "o", "h"] 808 | [219.278435, "o", "a"] 809 | [219.407935, "o", "n"] 810 | [220.312695, "o", "g"] 811 | [220.443876, "o", "e"] 812 | [220.778847, "o", " "] 813 | [221.145787, "o", "t"] 814 | [221.261907, "o", "h"] 815 | [221.337507, "o", "e"] 816 | [221.397419, "o", " "] 817 | [221.561494, "o", "f"] 818 | [221.662263, "o", "l"] 819 | [221.74301, "o", "a"] 820 | [221.898826, "o", "k"] 821 | [221.99523, "o", "e"] 822 | [222.406901, "o", " "] 823 | [222.475603, "o", "a"] 824 | [222.622033, "o", "n"] 825 | [222.657161, "o", "d"] 826 | [222.782468, "o", " "] 827 | [222.918481, "o", "s"] 828 | [223.069852, "o", "h"] 829 | [223.185299, "o", "e"] 830 | [223.352247, "o", "l"] 831 | [223.490429, "o", "l"] 832 | [223.616256, "o", " "] 833 | [224.367398, "o", "f"] 834 | [224.50544, "o", "i"] 835 | [224.604493, "o", "l"] 836 | [224.693843, "o", "e"] 837 | [224.90545, "o", "s"] 838 | [225.01728, "o", " "] 839 | [225.234667, "o", "g"] 840 | [225.412176, "o", "o"] 841 | [225.461146, "o", "i"] 842 | [225.653243, "o", "n"] 843 | [225.713118, "o", "g"] 844 | [225.836658, "o", " "] 845 | [226.013156, "o", "f"] 846 | [226.098743, "o", "o"] 847 | [226.219602, "o", "r"] 848 | [226.456641, "o", "w"] 849 | [226.637634, "o", "a"] 850 | [226.869289, "o", "r"] 851 | [227.110466, "o", "d"] 852 | [227.504253, "o", " "] 853 | [227.918884, "o", "a"] 854 | [227.969396, "o", "s"] 855 | [228.160535, "o", " "] 856 | [228.337194, "o", "n"] 857 | [228.45815, "o", "e"] 858 | [228.624382, "o", "e"] 859 | [228.807657, "o", "d"] 860 | [228.984432, "o", "e"] 861 | [229.135539, "o", "d"] 862 | [229.351876, "o", "."] 863 | [229.351876, "o", "\u001b[0m"] 864 | [230.42674, "o", "\r\n"] 865 | [230.427, "o", "\u001b[?2004l\r"] 866 | [230.435585, "o", "\u001b[?2004h$ "] 867 | [230.435585, "o", "\u001b[1m"] 868 | [231.481907, "o", "#"] 869 | [231.653879, "o", " "] 870 | [232.502605, "o", "E"] 871 | [232.77414, "o", "n"] 872 | [233.017913, "o", "j"] 873 | [233.173688, "o", "o"] 874 | [233.435939, "o", "y"] 875 | [233.813558, "o", "!"] 876 | [233.813558, "o", "\u001b[0m"] 877 | -------------------------------------------------------------------------------- /docs/src/legacy-nix-demo.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 81, "height": 23, "timestamp": 1692449645, "env": {"SHELL": "/run/current-system/sw/bin/bash", "TERM": "xterm-256color"}} 2 | [0.023675, "o", "\u001b[?2004h"] 3 | [0.023759, "o", "$ "] 4 | [0.023760, "o", "\u001b[1m"] 5 | [0.46831, "o", "#"] 6 | [0.824696, "o", " "] 7 | [1.196862, "o", "I"] 8 | [1.788208, "o", "'"] 9 | [2.180508, "o", "v"] 10 | [2.306527, "o", "e"] 11 | [2.387187, "o", " "] 12 | [2.640415, "o", "b"] 13 | [2.938021, "o", "e"] 14 | [3.073835, "o", "e"] 15 | [3.445477, "o", "n"] 16 | [3.821881, "o", " "] 17 | [4.107948, "o", "g"] 18 | [4.415049, "o", "i"] 19 | [4.640563, "o", "v"] 20 | [4.789656, "o", "e"] 21 | [5.855174, "o", "n"] 22 | [5.975524, "o", " "] 23 | [6.110261, "o", "a"] 24 | [6.221215, "o", " "] 25 | [6.403183, "o", "s"] 26 | [6.596256, "o", "c"] 27 | [6.827996, "o", "r"] 28 | [6.922848, "o", "i"] 29 | [6.963718, "o", "p"] 30 | [7.094727, "o", "t"] 31 | [7.366573, "o", " "] 32 | [7.742139, "o", "t"] 33 | [7.87698, "o", "o"] 34 | [7.952244, "o", " "] 35 | [8.299871, "o", "r"] 36 | [8.460485, "o", "u"] 37 | [8.724859, "o", "n"] 38 | [9.384592, "o", "."] 39 | [9.51636, "o", " "] 40 | [10.508771, "o", "L"] 41 | [10.732896, "o", "e"] 42 | [10.838339, "o", "t"] 43 | [11.416975, "o", "'"] 44 | [11.756573, "o", "s"] 45 | [11.953924, "o", " "] 46 | [12.532601, "o", "t"] 47 | [12.690054, "o", "r"] 48 | [12.787238, "o", "y"] 49 | [13.591751, "o", "."] 50 | [13.711877, "o", "."] 51 | [13.903476, "o", "."] 52 | [13.903477, "o","\u001b[0m"] 53 | [14.452411, "o", "\r\n\u001b[?2004l\r"] 54 | [14.460369, "o", "\u001b[?2004h$ "] 55 | [15.347477, "o", "."] 56 | [15.393596, "o", "/"] 57 | [15.730699, "o", "u"] 58 | [15.790007, "o", "p"] 59 | [15.966374, "o", "dateScript "] 60 | [16.535026, "o", "\r\n"] 61 | [16.535244, "o", "\u001b[?2004l\r"] 62 | [16.551804, "o", "./updateScript: line 5: aws: command not found\r\n"] 63 | [16.56045, "o", "\u001b[?2004h$ "] 64 | [16.56045, "o", "\u001b[1m"] 65 | [19.196842, "o", "#"] 66 | [19.36853, "o", " "] 67 | [19.58027, "o", "N"] 68 | [19.755701, "o", "o"] 69 | [19.855914, "o", " "] 70 | [20.736531, "o", "p"] 71 | [21.104516, "o", "r"] 72 | [21.255209, "o", "o"] 73 | [21.517024, "o", "b"] 74 | [21.779231, "o", "l"] 75 | [21.940589, "o", "e"] 76 | [22.045313, "o", "m"] 77 | [22.573698, "o", "."] 78 | [22.762995, "o", " "] 79 | [23.103831, "o", "N"] 80 | [23.306597, "o", "i"] 81 | [23.477701, "o", "x"] 82 | [23.57921, "o", " "] 83 | [23.846571, "o", "s"] 84 | [23.947575, "o", "h"] 85 | [24.068339, "o", "e"] 86 | [24.210068, "o", "l"] 87 | [24.319838, "o", "l"] 88 | [24.49181, "o", " "] 89 | [24.791162, "o", "t"] 90 | [24.831123, "o", "o"] 91 | [24.952002, "o", " "] 92 | [25.086683, "o", "t"] 93 | [25.484829, "o", "h"] 94 | [25.927794, "o", "e"] 95 | [26.168709, "o", " "] 96 | [26.441104, "o", "r"] 97 | [26.612568, "o", "e"] 98 | [27.236043, "o", "s"] 99 | [27.48793, "o", "c"] 100 | [27.695016, "o", "u"] 101 | [28.207872, "o", "e"] 102 | [28.841725, "o", "."] 103 | [28.977967, "o", "."] 104 | [29.143648, "o", "."] 105 | [30.155126, "o", "\r\n"] 106 | [30.155126, "o", "\u001b[0m"] 107 | [30.155185, "o", "\u001b[?2004l\r"] 108 | [30.161674, "o", "\u001b[?2004h$ "] 109 | [30.859442, "o", "n"] 110 | [30.900269, "o", "i"] 111 | [31.046603, "o", "x"] 112 | [31.454351, "o", "-"] 113 | [31.635536, "o", "s"] 114 | [31.720629, "o", "h"] 115 | [31.844011, "o", "ell"] 116 | [32.636856, "o", " "] 117 | [32.793441, "o", "-"] 118 | [33.126191, "o", "p"] 119 | [33.21782, "o", " "] 120 | [33.50896, "o", "a"] 121 | [33.781135, "o", "w"] 122 | [35.539999, "o", "s"] 123 | [36.594703, "o", "c"] 124 | [36.755755, "o", "l"] 125 | [36.933645, "o", "i"] 126 | [37.875848, "o", "\r\n"] 127 | [37.876042, "o", "\u001b[?2004l\r"] 128 | [38.805754, "o", "\u001b[?2004h"] 129 | [38.805791, "o", "\r\r\n"] 130 | [38.805815, "o", "\u001b[1;32m(nix-shell)\u001b[0m $ "] 131 | [38.805815, "o","\u001b[1m"] 132 | [40.277755, "o", "#"] 133 | [40.428409, "o", " "] 134 | [40.689389, "o", "N"] 135 | [40.855457, "o", "o"] 136 | [40.981775, "o", "w"] 137 | [41.09198, "o", " "] 138 | [41.476358, "o", "I"] 139 | [41.960237, "o", " "] 140 | [42.357837, "o", "h"] 141 | [42.483715, "o", "a"] 142 | [42.659351, "o", "v"] 143 | [42.979389, "o", "e"] 144 | [44.134943, "o", " "] 145 | [44.448088, "o", "a"] 146 | [44.624576, "o", "w"] 147 | [44.789903, "o", "s"] 148 | [45.005705, "o", "c"] 149 | [45.126488, "o", "l"] 150 | [45.298221, "o", "i"] 151 | [45.762787, "o", " "] 152 | [46.252767, "o", "l"] 153 | [46.403282, "o", "e"] 154 | [46.604094, "o", "t"] 155 | [46.700188, "o", "'"] 156 | [46.877011, "o", "s"] 157 | [47.233184, "o", " "] 158 | [47.424556, "o", "t"] 159 | [47.596005, "o", "r"] 160 | [47.706642, "o", "y"] 161 | [47.88279, "o", " "] 162 | [48.416832, "o", "a"] 163 | [48.718527, "o", "g"] 164 | [48.859311, "o", "a"] 165 | [49.055719, "o", "i"] 166 | [49.110937, "o", "n"] 167 | [49.211031, "o", "."] 168 | [49.367573, "o", "."] 169 | [49.548247, "o", "."] 170 | [50.394705, "o", "\r\n"] 171 | [50.394705, "o","\u001b[0m"] 172 | [50.39477, "o", "\u001b[?2004l\r"] 173 | [50.402529, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 174 | [51.19231, "o", "."] 175 | [51.23749, "o", "/"] 176 | [51.564934, "o", "u"] 177 | [51.736246, "o", "pdateScript "] 178 | [52.341865, "o", "\r\n"] 179 | [52.341983, "o", "\u001b[?2004l\r"] 180 | [52.948955, "o", "./updateScript: line 7: jq: command not found\r\n"] 181 | [52.953117, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 182 | [52.953117, "o","\u001b[1m"] 183 | [55.436744, "o", "#"] 184 | [55.834765, "o", " "] 185 | [56.071343, "o", "O"] 186 | [57.086336, "o", "k"] 187 | [57.345561, "o", "."] 188 | [57.506405, "o", " "] 189 | [57.733266, "o", "W"] 190 | [57.90927, "o", "e"] 191 | [58.065401, "o", " "] 192 | [58.365037, "o", "n"] 193 | [58.692405, "o", "e"] 194 | [58.818267, "o", "e"] 195 | [58.980413, "o", "d"] 196 | [59.070425, "o", " "] 197 | [59.303867, "o", "j"] 198 | [59.606064, "o", "q"] 199 | [59.844257, "o", " "] 200 | [60.560292, "o", "t"] 201 | [60.72157, "o", "o"] 202 | [60.852335, "o", "o"] 203 | [61.099867, "o", "."] 204 | [61.099867, "o","\u001b[0m"] 205 | [62.124866, "o", "\r\n"] 206 | [62.125144, "o", "\u001b[?2004l\r"] 207 | [62.13329, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 208 | [63.144572, "o","\u001b[1m"] 209 | [63.144572, "o", "#"] 210 | [63.329578, "o", " "] 211 | [64.135588, "o", "L"] 212 | [64.393362, "o", "e"] 213 | [64.464372, "o", "t"] 214 | [65.214751, "o", "'"] 215 | [65.299842, "o", "s"] 216 | [66.719765, "o", " "] 217 | [66.920813, "o", "e"] 218 | [67.126989, "o", "x"] 219 | [67.269564, "o", "i"] 220 | [67.663393, "o", "t"] 221 | [68.026527, "o", " "] 222 | [68.147263, "o", "t"] 223 | [68.278612, "o", "h"] 224 | [68.38041, "o", "i"] 225 | [68.607679, "o", "s"] 226 | [68.753642, "o", " "] 227 | [68.995352, "o", "s"] 228 | [69.116292, "o", "h"] 229 | [69.232679, "o", "e"] 230 | [69.435771, "o", "l"] 231 | [69.562548, "o", "l"] 232 | [69.667514, "o", " "] 233 | [69.779481, "o", "a"] 234 | [69.924412, "o", "n"] 235 | [69.999493, "o", "d"] 236 | [70.081691, "o", " "] 237 | [70.241653, "o", "a"] 238 | [70.46573, "o", "d"] 239 | [70.61156, "o", "d"] 240 | [70.742396, "o", " "] 241 | [71.155106, "o", "j"] 242 | [72.099241, "o", "q"] 243 | [72.340807, "o", "."] 244 | [72.494253, "o", "."] 245 | [72.635253, "o", "."] 246 | [72.635253, "o","\u001b[0m"] 247 | [73.811022, "o", "\r\n\u001b[?2004l\r"] 248 | [73.820194, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 249 | [74.488229, "o", "e"] 250 | [74.685464, "o", "x"] 251 | [74.806348, "o", "i"] 252 | [74.946343, "o", "t"] 253 | [76.632821, "o", "\r\n"] 254 | [76.633053, "o", "\u001b[?2004l\rexit\r\n"] 255 | [76.646425, "o", "\u001b[?2004h$ "] 256 | [77.195369, "o", "nix-shell -p awscli"] 257 | [77.899468, "o", " "] 258 | [78.318841, "o", "j"] 259 | [78.672733, "o", "q"] 260 | [80.040087, "o", "\r\n\u001b[?2004l\r"] 261 | [80.951541, "o", "\u001b[?2004h"] 262 | [80.951578, "o", "\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 263 | [81.76754, "o","\u001b[1m"] 264 | [81.76754, "o", "#"] 265 | [81.943076, "o", " "] 266 | [82.214455, "o", "N"] 267 | [82.376301, "o", "o"] 268 | [82.516823, "o", "w"] 269 | [82.601214, "o", " "] 270 | [82.786292, "o", "I"] 271 | [82.867604, "o", " "] 272 | [83.048965, "o", "h"] 273 | [83.148954, "o", "a"] 274 | [83.289873, "o", "v"] 275 | [83.385352, "o", "e"] 276 | [83.4761, "o", " "] 277 | [83.679375, "o", "b"] 278 | [83.720085, "o", "o"] 279 | [83.886297, "o", "t"] 280 | [83.983275, "o", "h"] 281 | [85.172348, "o", ","] 282 | [85.364096, "o", " "] 283 | [85.479958, "o", "l"] 284 | [85.598034, "o", "e"] 285 | [85.775001, "o", "t"] 286 | [85.846153, "o", "'"] 287 | [86.031783, "o", "s"] 288 | [86.151842, "o", " "] 289 | [86.733677, "o", "t"] 290 | [86.935177, "o", "r"] 291 | [87.040447, "o", "y"] 292 | [87.191747, "o", " "] 293 | [87.614503, "o", "a"] 294 | [87.813298, "o", "g"] 295 | [87.934378, "o", "a"] 296 | [88.095685, "o", "i"] 297 | [88.187085, "o", "n"] 298 | [88.647035, "o", "."] 299 | [88.794341, "o", "."] 300 | [88.969333, "o", "."] 301 | [88.969333, "o","\u001b[0m"] 302 | [89.589722, "o", "\r\n\u001b[?2004l\r"] 303 | [89.598317, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 304 | [89.97992, "o", "."] 305 | [90.008868, "o", "/"] 306 | [90.29637, "o", "u"] 307 | [90.35644, "o", "p"] 308 | [90.488061, "o", "dateScript "] 309 | [91.079394, "o", "\r\n"] 310 | [91.079478, "o", "\u001b[?2004l\r"] 311 | [91.410881, "o", "Update succeeded\r\n"] 312 | [91.414685, "o", "\u001b[?2004h\r\r\n"] 313 | [91.414716, "o", "\u001b[1;32m(nix-shell)\u001b[0m $ "] 314 | [93.730668, "o","\u001b[1m"] 315 | [93.730668, "o", "#"] 316 | [93.920746, "o", " "] 317 | [94.222896, "o", "G"] 318 | [94.474189, "o", "r"] 319 | [94.681257, "o", "e"] 320 | [94.769074, "o", "a"] 321 | [94.884877, "o", "t"] 322 | [95.015724, "o", " "] 323 | [95.49852, "o", "i"] 324 | [95.609523, "o", "t"] 325 | [95.748671, "o", " "] 326 | [95.944879, "o", "w"] 327 | [96.049793, "o", "o"] 328 | [96.206196, "o", "r"] 329 | [96.392841, "o", "k"] 330 | [96.487767, "o", "s"] 331 | [96.684147, "o", "."] 332 | [96.684147, "o","\u001b[0m"] 333 | [97.184729, "o", "\r\n"] 334 | [97.184989, "o", "\u001b[?2004l\r"] 335 | [97.193621, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 336 | [97.193621, "o","\u001b[1m"] 337 | [97.766309, "o", "#"] 338 | [98.068124, "o", " "] 339 | [98.611791, "o", "I"] 340 | [98.776909, "o", " "] 341 | [98.936998, "o", "s"] 342 | [99.089207, "o", "h"] 343 | [99.239177, "o", "o"] 344 | [99.38548, "o", "u"] 345 | [99.474717, "o", "l"] 346 | [99.651383, "o", "d"] 347 | [99.8051, "o", " "] 348 | [100.242966, "o", "n"] 349 | [100.265958, "o", "o"] 350 | [100.821247, "o", "w"] 351 | [100.93685, "o", " "] 352 | [101.258715, "o", "c"] 353 | [101.525911, "o", "r"] 354 | [101.701771, "o", "e"] 355 | [101.83544, "o", "a"] 356 | [101.971139, "o", "t"] 357 | [102.08727, "o", "e"] 358 | [102.232934, "o", " "] 359 | [102.333792, "o", "a"] 360 | [102.459528, "o", " "] 361 | [102.975462, "o", "s"] 362 | [103.121706, "o", "h"] 363 | [103.191987, "o", "e"] 364 | [103.363075, "o", "l"] 365 | [103.473572, "o", "l"] 366 | [103.674574, "o", "."] 367 | [104.068279, "o", "n"] 368 | [104.121755, "o", "i"] 369 | [104.261458, "o", "x"] 370 | [105.282139, "o", " "] 371 | [105.56356, "o", "f"] 372 | [105.643473, "o", "i"] 373 | [105.698703, "o", "l"] 374 | [105.84137, "o", "e"] 375 | [106.195783, "o", "."] 376 | [106.195783, "o", "\u001b[0m"] 377 | [107.002613, "o", "\r\n"] 378 | [107.002831, "o", "\u001b[?2004l\r"] 379 | [107.01126, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 380 | [107.01126, "o", "\u001b[1m"] 381 | [107.81795, "o", "#"] 382 | [107.959191, "o", " "] 383 | [108.165122, "o", "I"] 384 | [108.276739, "o", " "] 385 | [108.603409, "o", "u"] 386 | [108.709748, "o", "s"] 387 | [108.866449, "o", "e"] 388 | [108.99752, "o", "d"] 389 | [109.066848, "o", " "] 390 | [109.182466, "o", "t"] 391 | [109.26839, "o", "o"] 392 | [109.323762, "o", " "] 393 | [109.650482, "o", "a"] 394 | [109.756406, "o", "l"] 395 | [109.990528, "o", "w"] 396 | [110.156469, "o", "a"] 397 | [110.353548, "o", "y"] 398 | [110.358582, "o", "s"] 399 | [111.176344, "o", " "] 400 | [111.478693, "o", "p"] 401 | [111.605515, "o", "u"] 402 | [111.725241, "o", "t"] 403 | [111.796755, "o", " "] 404 | [111.922135, "o", "t"] 405 | [111.962744, "o", "h"] 406 | [112.005458, "o", "i"] 407 | [112.177491, "o", "s"] 408 | [112.27178, "o", " "] 409 | [112.448549, "o", "o"] 410 | [112.694932, "o", "f"] 411 | [112.848801, "o", "f"] 412 | [113.146679, "o", "!"] 413 | [113.146679, "o", "\u001b[0m"] 414 | [114.738219, "o", "\r\n"] 415 | [114.738478, "o", "\u001b[?2004l\r"] 416 | [114.748562, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 417 | [114.748562, "o", "\u001b[1m"] 418 | [115.264435, "o", "#"] 419 | [115.41555, "o", " "] 420 | [115.671679, "o", "B"] 421 | [115.823205, "o", "u"] 422 | [115.913376, "o", "t"] 423 | [115.969435, "o", " "] 424 | [116.162513, "o", "n"] 425 | [116.218473, "o", "o"] 426 | [116.319573, "o", "w"] 427 | [116.434903, "o", " "] 428 | [116.58611, "o", "w"] 429 | [116.706808, "o", "i"] 430 | [116.857883, "o", "t"] 431 | [116.944161, "o", "h"] 432 | [117.070137, "o", " "] 433 | [117.973004, "o", "s"] 434 | [118.086251, "o", "h"] 435 | [118.181803, "o", "e"] 436 | [118.328727, "o", "l"] 437 | [118.433645, "o", "l"] 438 | [118.610154, "o", "i"] 439 | [118.836462, "o", "f"] 440 | [118.95797, "o", "y"] 441 | [119.085587, "o", " "] 442 | [119.484999, "o", "I"] 443 | [119.56013, "o", " "] 444 | [119.767156, "o", "c"] 445 | [119.831119, "o", "a"] 446 | [119.952214, "o", "n"] 447 | [120.068523, "o", " "] 448 | [120.186516, "o", "j"] 449 | [120.348095, "o", "u"] 450 | [120.488812, "o", "s"] 451 | [120.589814, "o", "t"] 452 | [120.780246, "o", " "] 453 | [121.55822, "o", "s"] 454 | [121.766288, "o", "w"] 455 | [121.966937, "o", "a"] 456 | [121.996937, "o", "p"] 457 | [122.149947, "o", " "] 458 | [122.497759, "o", "n"] 459 | [122.542798, "o", "i"] 460 | [122.995878, "o", "x"] 461 | [123.09672, "o", " "] 462 | [123.255896, "o", "f"] 463 | [123.346064, "o", "o"] 464 | [123.426804, "o", "r"] 465 | [123.51348, "o", " "] 466 | [123.881218, "o", "n"] 467 | [123.917921, "o", "i"] 468 | [124.295238, "o", "x"] 469 | [124.446685, "o", "-"] 470 | [124.617402, "o", "s"] 471 | [124.743736, "o", "h"] 472 | [124.814217, "o", "e"] 473 | [124.980141, "o", "l"] 474 | [125.075358, "o", "l"] 475 | [125.269759, "o", "i"] 476 | [125.587723, "o", "f"] 477 | [125.732551, "o", "y"] 478 | [126.130779, "o", " "] 479 | [126.570283, "o", "a"] 480 | [126.704494, "o", "n"] 481 | [126.799121, "o", "d"] 482 | [126.906056, "o", " "] 483 | [127.189022, "o", "w"] 484 | [127.345213, "o", "e"] 485 | [127.461094, "o", "'"] 486 | [127.733257, "o", "r"] 487 | [128.121133, "o", "e"] 488 | [128.429858, "o", " "] 489 | [128.743965, "o", "g"] 490 | [128.877737, "o", "o"] 491 | [128.998562, "o", "o"] 492 | [129.134989, "o", "d"] 493 | [129.384293, "o", "."] 494 | [129.515903, "o", "."] 495 | [129.6828, "o", "."] 496 | [129.6828, "o", "\u001b[0m"] 497 | [130.715075, "o", "\r\n"] 498 | [130.715321, "o", "\u001b[?2004l\r"] 499 | [130.722664, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 500 | [131.427208, "o", "e"] 501 | [131.633944, "o", "x"] 502 | [131.740098, "o", "i"] 503 | [131.91529, "o", "t"] 504 | [133.303689, "o", "\r\n"] 505 | [133.303764, "o", "\u001b[?2004l\rexit\r\n"] 506 | [133.31671, "o", "\u001b[?2004h$ "] 507 | [133.92185, "o", "nix-shell -p awscli jq"] 508 | [135.413235, "o", "\b\r\u001b[C\u001b[C"] 509 | [136.19986, "o", "\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C\u001b[C"] 510 | [136.686785, "o", "\u001b[C"] 511 | [137.523726, "o", "\u001b[1@i"] 512 | [137.70287, "o", "\u001b[2@fy"] 513 | [140.085369, "o", "\r\n"] 514 | [140.085663, "o", "\u001b[?2004l\r"] 515 | [140.126087, "o", "shell.nix does not exist. Creating one"] 516 | [140.1262, "o", "\r\n"] 517 | [140.129929, "o", "\u001b[?2004h$ "] 518 | [143.757701, "o", "l"] 519 | [143.937781, "o", "s"] 520 | [144.315446, "o", "\r\n\u001b[?2004l\r"] 521 | [144.319065, "o", "shell.nix \u001b[0m\u001b[01;32mupdateScript\u001b[0m\r\n"] 522 | [144.327005, "o", "\u001b[?2004h$ "] 523 | [144.327005, "o", "\u001b[1m"] 524 | [145.137968, "o", "#"] 525 | [145.334891, "o", " "] 526 | [146.074977, "o", "C"] 527 | [146.281405, "o", "o"] 528 | [146.407553, "o", "o"] 529 | [146.613009, "o", "l"] 530 | [147.186004, "o", " "] 531 | [147.46374, "o", "I"] 532 | [147.518873, "o", " "] 533 | [147.719988, "o", "h"] 534 | [147.82067, "o", "a"] 535 | [147.987101, "o", "v"] 536 | [148.112717, "o", "e"] 537 | [148.444833, "o", " "] 538 | [148.621862, "o", "a"] 539 | [148.724162, "o", " "] 540 | [148.9809, "o", "s"] 541 | [149.12116, "o", "h"] 542 | [149.222621, "o", "e"] 543 | [149.393921, "o", "l"] 544 | [149.515484, "o", "l"] 545 | [149.730274, "o", "."] 546 | [150.091258, "o", "n"] 547 | [150.15185, "o", "i"] 548 | [150.267569, "o", "x"] 549 | [150.555611, "o", "."] 550 | [150.738092, "o", " "] 551 | [151.357621, "o", "L"] 552 | [151.508676, "o", "e"] 553 | [151.684743, "o", "t"] 554 | [151.742312, "o", "'"] 555 | [151.92897, "o", "s"] 556 | [152.034686, "o", " "] 557 | [152.231621, "o", "t"] 558 | [152.392626, "o", "r"] 559 | [152.497926, "o", "y"] 560 | [152.889389, "o", "."] 561 | [153.004305, "o", "."] 562 | [153.139596, "o", "."] 563 | [153.139596, "o", "\u001b[0m"] 564 | [154.759856, "o", "\r\n\u001b[?2004l\r"] 565 | [154.767689, "o", "\u001b[?2004h$ "] 566 | [158.367655, "o", "n"] 567 | [158.424262, "o", "i"] 568 | [158.52522, "o", "x"] 569 | [158.778195, "o", "-"] 570 | [159.697314, "o", "s"] 571 | [159.818394, "o", "h"] 572 | [159.966901, "o", "e"] 573 | [160.131961, "o", "l"] 574 | [160.252269, "o", "l"] 575 | [161.155983, "o", "\r\n"] 576 | [161.156227, "o", "\u001b[?2004l\r"] 577 | [162.104131, "o", "\u001b[?2004h"] 578 | [162.104167, "o", "\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 579 | [163.045154, "o", "."] 580 | [163.140669, "o", "/"] 581 | [163.417954, "o", "u"] 582 | [163.583988, "o", "pdateScript "] 583 | [164.431988, "o", "\r\n"] 584 | [164.43215, "o", "\u001b[?2004l\r"] 585 | [164.762958, "o", "Update succeeded\r\n"] 586 | [164.766617, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 587 | [164.766617, "o", "\u001b[1m"] 588 | [167.571393, "o", "#"] 589 | [167.73626, "o", " "] 590 | [168.036023, "o", "I"] 591 | [168.176287, "o", "t"] 592 | [168.348253, "o", " "] 593 | [168.504367, "o", "w"] 594 | [168.621185, "o", "o"] 595 | [168.750954, "o", "r"] 596 | [168.87685, "o", "k"] 597 | [169.010255, "o", "s"] 598 | [169.710362, "o", "!"] 599 | [169.710362, "o", "\u001b[0m"] 600 | [170.382799, "o", "\r\n"] 601 | [170.382876, "o", "\u001b[?2004l\r"] 602 | [170.392268, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 603 | [170.392268, "o", "\u001b[1m"] 604 | [172.053423, "o", "#"] 605 | [172.223534, "o", " "] 606 | [172.466014, "o", "N"] 607 | [173.004887, "o", "o"] 608 | [173.172185, "o", "w"] 609 | [173.293167, "o", " "] 610 | [173.535758, "o", "I"] 611 | [173.737184, "o", " "] 612 | [174.229094, "o", "c"] 613 | [174.319773, "o", "a"] 614 | [174.410627, "o", "n"] 615 | [174.555646, "o", " "] 616 | [174.938137, "o", "c"] 617 | [175.029398, "o", "o"] 618 | [175.192162, "o", "m"] 619 | [175.302449, "o", "m"] 620 | [175.39357, "o", "i"] 621 | [175.549724, "o", "t"] 622 | [175.611149, "o", " "] 623 | [175.788278, "o", "t"] 624 | [175.897172, "o", "h"] 625 | [176.896926, "o", "e"] 626 | [177.048604, "o", " "] 627 | [177.224423, "o", "s"] 628 | [177.345044, "o", "h"] 629 | [177.438936, "o", "e"] 630 | [177.597288, "o", "l"] 631 | [177.708558, "o", "l"] 632 | [178.708324, "o", " "] 633 | [178.885954, "o", "f"] 634 | [178.985794, "o", "i"] 635 | [179.019696, "o", "l"] 636 | [179.153292, "o", "e"] 637 | [179.481111, "o", " "] 638 | [179.703902, "o", "n"] 639 | [179.79319, "o", "e"] 640 | [180.009888, "o", "x"] 641 | [180.14807, "o", "t"] 642 | [180.268915, "o", " "] 643 | [180.808428, "o", "t"] 644 | [180.878854, "o", "o"] 645 | [181.065698, "o", " "] 646 | [181.692486, "o", "m"] 647 | [181.915164, "o", "y"] 648 | [181.985591, "o", " "] 649 | [182.204427, "o", "s"] 650 | [182.391228, "o", "c"] 651 | [182.602017, "o", "r"] 652 | [182.632153, "o", "i"] 653 | [183.387088, "o", "p"] 654 | [183.512363, "o", "t"] 655 | [184.835339, "o", " "] 656 | [185.091309, "o", "s"] 657 | [185.181515, "o", "o"] 658 | [185.275423, "o", " "] 659 | [185.501403, "o", "I"] 660 | [185.582253, "o", " "] 661 | [186.050931, "o", "d"] 662 | [186.103268, "o", "o"] 663 | [186.161062, "o", "n"] 664 | [187.196301, "o", "'"] 665 | [187.326383, "o", "t"] 666 | [187.445596, "o", " "] 667 | [187.945024, "o", "h"] 668 | [188.020103, "o", "a"] 669 | [188.191662, "o", "v"] 670 | [188.288374, "o", "e"] 671 | [188.378755, "o", " "] 672 | [188.549636, "o", "t"] 673 | [188.665306, "o", "o"] 674 | [188.757152, "o", " "] 675 | [189.469746, "o", "d"] 676 | [190.109156, "o", "o"] 677 | [190.373861, "o", " "] 678 | [190.438598, "o", "t"] 679 | [190.545518, "o", "h"] 680 | [190.600024, "o", "i"] 681 | [190.746796, "o", "s"] 682 | [190.856943, "o", " "] 683 | [190.978347, "o", "a"] 684 | [191.119576, "o", "g"] 685 | [191.195787, "o", "a"] 686 | [191.348259, "o", "i"] 687 | [191.439351, "o", "n"] 688 | [191.875405, "o", "!"] 689 | [191.875405, "o", "\u001b[0m"] 690 | [192.501565, "o", "\r\n"] 691 | [192.501843, "o", "\u001b[?2004l\r"] 692 | [192.509733, "o", "\u001b[?2004h\r\r\n\u001b[1;32m(nix-shell)\u001b[0m $ "] 693 | [192.509733, "o", "\u001b[1m"] 694 | [193.227562, "o", "#"] 695 | [193.370746, "o", " "] 696 | [194.352686, "o", "B"] 697 | [194.546592, "o", "u"] 698 | [194.657615, "o", "t"] 699 | [194.738912, "o", " "] 700 | [194.999935, "o", "w"] 701 | [195.135708, "o", "h"] 702 | [195.256961, "o", "a"] 703 | [195.352438, "o", "t"] 704 | [196.281546, "o", " "] 705 | [197.478889, "o", "i"] 706 | [198.023278, "o", "f"] 707 | [198.138198, "o", " "] 708 | [198.243743, "o", "a"] 709 | [198.329634, "o", " "] 710 | [198.524456, "o", "d"] 711 | [198.704917, "o", "e"] 712 | [198.81638, "o", "p"] 713 | [198.946764, "o", "e"] 714 | [199.097735, "o", "n"] 715 | [199.493013, "o", "d"] 716 | [199.669574, "o", "e"] 717 | [199.785426, "o", "n"] 718 | [200.006864, "o", "c"] 719 | [200.15796, "o", "y"] 720 | [201.177628, "o", " "] 721 | [201.374969, "o", "w"] 722 | [201.559047, "o", "e"] 723 | [201.755227, "o", "r"] 724 | [201.921161, "o", "e"] 725 | [202.022727, "o", " "] 726 | [202.123196, "o", "t"] 727 | [202.193207, "o", "o"] 728 | [202.278965, "o", " "] 729 | [202.480083, "o", "b"] 730 | [202.660182, "o", "r"] 731 | [202.865278, "o", "e"] 732 | [203.279957, "o", "a"] 733 | [204.155022, "o", "k"] 734 | [204.280175, "o", " "] 735 | [204.458575, "o", "a"] 736 | [204.736727, "o", "f"] 737 | [204.943668, "o", "t"] 738 | [205.139727, "o", "e"] 739 | [205.205696, "o", "r"] 740 | [205.968423, "o", " "] 741 | [206.099124, "o", "a"] 742 | [206.270527, "o", "n"] 743 | [206.382052, "o", " "] 744 | [206.656027, "o", "u"] 745 | [206.701291, "o", "p"] 746 | [206.973488, "o", "d"] 747 | [207.120311, "o", "a"] 748 | [207.331574, "o", "t"] 749 | [207.411724, "o", "e"] 750 | [208.320424, "o", "?"] 751 | [208.320424, "o", "\u001b[0m"] 752 | [209.908054, "o", "\r\n"] 753 | [209.90826, "o", "\u001b[?2004l\r"] 754 | [209.91704, "o", "\u001b[?2004h\r\r\n"] 755 | [209.917135, "o", "\u001b[1;32m(nix-shell)\u001b[0m $ "] 756 | [209.917135, "o", "\u001b[1m"] 757 | [210.981952, "o", "#"] 758 | [211.123157, "o", " "] 759 | [211.531208, "o", "I"] 760 | [211.770326, "o", "f"] 761 | [211.88198, "o", " "] 762 | [212.062151, "o", "y"] 763 | [212.088253, "o", "o"] 764 | [212.157817, "o", "u"] 765 | [212.284058, "o", " "] 766 | [212.51555, "o", "w"] 767 | [212.631733, "o", "o"] 768 | [212.990053, "o", "r"] 769 | [213.125304, "o", "r"] 770 | [213.61984, "o", "y"] 771 | [213.726888, "o", " "] 772 | [213.843752, "o", "a"] 773 | [214.024557, "o", "b"] 774 | [214.06478, "o", "o"] 775 | [214.115726, "o", "u"] 776 | [214.322596, "o", "t"] 777 | [214.492639, "o", " "] 778 | [215.480749, "o", "t"] 779 | [215.561036, "o", "h"] 780 | [215.861164, "o", "a"] 781 | [216.016894, "o", "t"] 782 | [216.374486, "o", ","] 783 | [216.531098, "o", " "] 784 | [216.755656, "o", "a"] 785 | [217.011451, "o", "d"] 786 | [217.15738, "o", "d"] 787 | [217.279742, "o", " "] 788 | [219.068386, "o", "w"] 789 | [219.266035, "o", "i"] 790 | [219.401155, "o", "t"] 791 | [219.501324, "o", "h"] 792 | [219.792017, "o", "-"] 793 | [220.143663, "o", "f"] 794 | [220.265269, "o", "l"] 795 | [220.344786, "o", "a"] 796 | [220.531515, "o", "k"] 797 | [220.632103, "o", "e"] 798 | [222.596415, "o", " "] 799 | [223.635797, "o", "l"] 800 | [223.766649, "o", "i"] 801 | [223.925282, "o", "k"] 802 | [223.975569, "o", "e"] 803 | [224.086569, "o", " "] 804 | [224.156787, "o", "t"] 805 | [224.237544, "o", "h"] 806 | [224.288716, "o", "i"] 807 | [224.66049, "o", "s"] 808 | [224.921393, "o", "."] 809 | [225.071116, "o", "."] 810 | [225.242411, "o", "."] 811 | [225.242411, "o", "\u001b[0m"] 812 | [226.139284, "o", "\r\n"] 813 | [226.139356, "o", "\u001b[?2004l\r"] 814 | [226.148625, "o", "\u001b[?2004h\r\r\n"] 815 | [226.148696, "o", "\u001b[1;32m(nix-shell) \u001b[0m$ "] 816 | [227.952684, "o", "\u001b[?2004l\r\r\nexit\r\n"] 817 | [227.96317, "o", "\u001b[?2004h$ "] 818 | [229.02028, "o", "nix-shell"] 819 | [231.178877, "o", "\r\u001b[C\u001b[C# Cool I have a shell.nix. Let's try..."] 820 | [232.420525, "o", "\r\u001b[C\u001b[Cls\u001b[K"] 821 | [232.869315, "o", "\b\bnix-shellify -p awscli jq"] 822 | [235.282922, "o", "\b"] 823 | [235.872839, "o", "\b"] 824 | [236.192039, "o", "\b\b\b\b\b\b\b"] 825 | [236.565358, "o", "\b\b\b"] 826 | [238.300343, "o", "\u001b[C\u001b[1@-\b"] 827 | [238.648664, "o", "\u001b[C\u001b[1@-\b"] 828 | [239.068365, "o", "\u001b[1@w"] 829 | [239.204686, "o", "\u001b[1@i"] 830 | [239.365461, "o", "\u001b[1@t"] 831 | [239.451789, "o", "\u001b[1@h"] 832 | [239.683216, "o", "\u001b[C\u001b[1@-\b"] 833 | [239.969761, "o", "\u001b[1@f"] 834 | [240.081581, "o", "\u001b[1@l"] 835 | [240.133644, "o", "\u001b[1@a"] 836 | [240.285396, "o", "\u001b[1@k"] 837 | [240.416397, "o", "\u001b[1@e"] 838 | [241.76796, "o", "\u001b[1@ "] 839 | [242.427549, "o", "\r\n"] 840 | [242.427838, "o", "\u001b[?2004l\r"] 841 | [242.45493, "o", "The existing shell.nix is good already\r\nflake.nix does not exist. Creating one\r\n"] 842 | [242.467798, "o", "\u001b[?2004h$ "] 843 | [243.42747, "o", "l"] 844 | [243.528583, "o", "s"] 845 | [243.704274, "o", "\r\n\u001b[?2004l\r"] 846 | [243.707731, "o", "flake.nix shell.nix \u001b[0m\u001b[01;32mupdateScript\u001b[0m\r\n"] 847 | [243.715711, "o", "\u001b[?2004h"] 848 | [243.715776, "o", "$ "] 849 | [243.715776, "o", "\u001b[1m"] 850 | [245.066157, "o", "#"] 851 | [245.74459, "o", " "] 852 | [246.026061, "o", "N"] 853 | [246.168678, "o", "o"] 854 | [246.285154, "o", "w"] 855 | [246.375239, "o", " "] 856 | [247.183935, "o", "I"] 857 | [247.334726, "o", " "] 858 | [247.566916, "o", "a"] 859 | [247.671768, "o", "l"] 860 | [247.834214, "o", "s"] 861 | [248.045292, "o", "o"] 862 | [248.84785, "o", " "] 863 | [249.323639, "o", "h"] 864 | [249.394335, "o", "a"] 865 | [249.615777, "o", "v"] 866 | [249.696933, "o", "e"] 867 | [249.827571, "o", " "] 868 | [250.049066, "o", "a"] 869 | [250.199772, "o", " "] 870 | [250.459509, "o", "f"] 871 | [250.564795, "o", "l"] 872 | [250.594764, "o", "a"] 873 | [250.782076, "o", "k"] 874 | [250.943247, "o", "e"] 875 | [251.266964, "o", "."] 876 | [252.239879, "o", "n"] 877 | [252.296645, "o", "i"] 878 | [252.498374, "o", "x"] 879 | [252.599139, "o", " "] 880 | [252.769738, "o", "f"] 881 | [252.8762, "o", "i"] 882 | [252.9262, "o", "l"] 883 | [253.128206, "o", "e"] 884 | [253.784886, "o", " "] 885 | [254.263346, "o", "a"] 886 | [254.518146, "o", "n"] 887 | [254.59294, "o", "d"] 888 | [254.703899, "o", " "] 889 | [255.565042, "o", "I"] 890 | [255.843311, "o", " "] 891 | [256.125074, "o", "c"] 892 | [256.199802, "o", "a"] 893 | [256.328113, "o", "n"] 894 | [256.474363, "o", " "] 895 | [256.63592, "o", "g"] 896 | [256.802367, "o", "e"] 897 | [257.029097, "o", "t"] 898 | [257.153976, "o", " "] 899 | [257.261005, "o", "a"] 900 | [257.37332, "o", " "] 901 | [257.56041, "o", "d"] 902 | [257.742311, "o", "e"] 903 | [257.932111, "o", "v"] 904 | [257.983355, "o", "e"] 905 | [258.138933, "o", "l"] 906 | [258.39375, "o", "o"] 907 | [258.468648, "o", "p"] 908 | [258.886456, "o", "m"] 909 | [258.992428, "o", "e"] 910 | [259.13395, "o", "n"] 911 | [259.179081, "o", "t"] 912 | [259.358192, "o", " "] 913 | [259.544215, "o", "s"] 914 | [259.711875, "o", "h"] 915 | [259.837154, "o", "e"] 916 | [259.983582, "o", "l"] 917 | [260.098278, "o", "l"] 918 | [260.224572, "o", " "] 919 | [260.786031, "o", "b"] 920 | [261.102921, "o", "y"] 921 | [261.339693, "o", " "] 922 | [261.652192, "o", "r"] 923 | [261.829073, "o", "u"] 924 | [261.985041, "o", "n"] 925 | [262.141193, "o", "n"] 926 | [262.252345, "o", "i"] 927 | [262.348612, "o", "n"] 928 | [262.557453, "o", "g"] 929 | [262.924366, "o", "."] 930 | [263.089749, "o", "."] 931 | [263.281444, "o", "."] 932 | [263.281444, "o", "\u001b[0m"] 933 | [264.090389, "o", "\r\n"] 934 | [264.090649, "o", "\u001b[?2004l\r"] 935 | [264.098764, "o", "\u001b[?2004h$ "] 936 | [265.099747, "o", "n"] 937 | [265.164773, "o", "i"] 938 | [265.27576, "o", "x"] 939 | [266.068866, "o", " "] 940 | [266.17442, "o", "d"] 941 | [266.351161, "o", "e"] 942 | [266.544715, "o", "v"] 943 | [266.60539, "o", "e"] 944 | [266.756432, "o", "l"] 945 | [266.897413, "o", "o"] 946 | [266.937905, "o", "p"] 947 | [267.47205, "o", "\r\n"] 948 | [267.472267, "o", "\u001b[?2004l\r"] 949 | [267.49056, "o", "\r\u001b[0m\u001b[K"] 950 | [267.540608, "o", "\r\u001b[0m\u001b[K"] 951 | [267.590802, "o", "\r\u001b[0m\u001b[K"] 952 | [267.640788, "o", "\r\u001b[0m\u001b[K"] 953 | [267.640895, "o", "\r\u001b[K"] 954 | [267.675175, "o", "\u001b[?2004h"] 955 | [267.675281, "o", "$ "] 956 | [269.368999, "o", "."] 957 | [269.408396, "o", "/"] 958 | [269.742714, "o", "u"] 959 | [269.788515, "o", "p"] 960 | [269.929855, "o", "dateScript "] 961 | [271.1163, "o", "\r\n\u001b[?2004l\r"] 962 | [271.742456, "o", "Update succeeded\r\n"] 963 | [271.746329, "o", "\u001b[?2004h"] 964 | [271.746396, "o", "$ "] 965 | [271.746396, "o", "\u001b[1m"] 966 | [273.218564, "o", "#"] 967 | [273.349922, "o", " "] 968 | [273.58035, "o", "I"] 969 | [273.664761, "o", "t"] 970 | [273.755405, "o", " "] 971 | [273.918128, "o", "w"] 972 | [274.007209, "o", "o"] 973 | [274.157596, "o", "r"] 974 | [274.224272, "o", "k"] 975 | [274.416551, "o", "s"] 976 | [274.416551, "o", "\u001b[0m"] 977 | [276.310491, "o", "\r\n"] 978 | [276.310597, "o", "\u001b[?2004l\r"] 979 | [276.318058, "o", "\u001b[?2004h$ "] 980 | [276.901001, "o", "l"] 981 | [276.991664, "o", "s"] 982 | [277.112757, "o", "\r\n"] 983 | [277.112814, "o", "\u001b[?2004l\r"] 984 | [277.115586, "o", "flake.lock flake.nix shell.nix \u001b[0m\u001b[01;32mupdateScript\u001b[0m\r\n"] 985 | [277.115586, "o", "$ "] 986 | [277.115586, "o", "\u001b[1m"] 987 | [278.802893, "o", "#"] 988 | [278.937572, "o", " "] 989 | [279.200237, "o", "I"] 990 | [279.431021, "o", "t"] 991 | [279.533163, "o", "'"] 992 | [279.676557, "o", "s"] 993 | [279.803591, "o", " "] 994 | [280.1638, "o", "a"] 995 | [280.401531, "o", "d"] 996 | [280.540216, "o", "d"] 997 | [280.71716, "o", "e"] 998 | [280.868354, "o", "d"] 999 | [280.964237, "o", " "] 1000 | [281.360721, "o", "a"] 1001 | [281.542072, "o", " "] 1002 | [282.153824, "o", "f"] 1003 | [285.221867, "o", "l"] 1004 | [285.317407, "o", "a"] 1005 | [285.442854, "o", "k"] 1006 | [285.539628, "o", "e"] 1007 | [285.700726, "o", "."] 1008 | [285.939244, "o", "l"] 1009 | [286.08123, "o", "o"] 1010 | [286.377656, "o", "c"] 1011 | [286.463867, "o", "k"] 1012 | [287.628964, "o", " "] 1013 | [287.908839, "o", "f"] 1014 | [287.958812, "o", "i"] 1015 | [288.025484, "o", "l"] 1016 | [288.130353, "o", "e"] 1017 | [288.130353, "o", "\u001b[0m"] 1018 | [290.231067, "o", "\r\n\u001b[?2004l\r"] 1019 | [290.24045, "o", "\u001b[?2004h$ "] 1020 | [290.24045, "o", "\u001b[1m"] 1021 | [291.178191, "o", "#"] 1022 | [291.334579, "o", " "] 1023 | [291.606698, "o", "I"] 1024 | [292.001142, "o", "f"] 1025 | [292.389429, "o", " "] 1026 | [292.726953, "o", "I"] 1027 | [292.860433, "o", " "] 1028 | [293.112439, "o", "c"] 1029 | [293.404791, "o", "o"] 1030 | [293.701823, "o", "m"] 1031 | [293.844024, "o", "m"] 1032 | [293.997224, "o", "i"] 1033 | [294.339972, "o", "t"] 1034 | [294.894428, "o", " "] 1035 | [295.040778, "o", "t"] 1036 | [295.136149, "o", "h"] 1037 | [295.267076, "o", "e"] 1038 | [295.356911, "o", " "] 1039 | [295.619101, "o", "f"] 1040 | [295.709931, "o", "l"] 1041 | [295.750019, "o", "a"] 1042 | [295.904398, "o", "k"] 1043 | [295.999183, "o", "e"] 1044 | [296.694333, "o", " "] 1045 | [296.744853, "o", "a"] 1046 | [296.909119, "o", "n"] 1047 | [296.974867, "o", "d"] 1048 | [297.055011, "o", " "] 1049 | [297.195998, "o", "l"] 1050 | [297.337429, "o", "o"] 1051 | [297.427429, "o", "c"] 1052 | [297.539468, "o", "k"] 1053 | [297.65901, "o", " "] 1054 | [298.201131, "o", "f"] 1055 | [298.262092, "o", "i"] 1056 | [298.307122, "o", "l"] 1057 | [298.427731, "o", "e"] 1058 | [298.639562, "o", "s"] 1059 | [298.74588, "o", " "] 1060 | [298.999738, "o", "I"] 1061 | [299.135957, "o", " "] 1062 | [299.525045, "o", "k"] 1063 | [299.726674, "o", "n"] 1064 | [299.811533, "o", "o"] 1065 | [300.008653, "o", "w"] 1066 | [300.768867, "o", " "] 1067 | [301.046624, "o", "I"] 1068 | [301.157664, "o", " "] 1069 | [301.29838, "o", "c"] 1070 | [301.41892, "o", "a"] 1071 | [301.601867, "o", "n"] 1072 | [301.736918, "o", " "] 1073 | [301.913092, "o", "r"] 1074 | [302.092329, "o", "e"] 1075 | [302.172794, "o", "p"] 1076 | [302.806003, "o", "r"] 1077 | [302.97741, "o", "o"] 1078 | [303.221704, "o", "d"] 1079 | [303.387896, "o", "u"] 1080 | [303.513958, "o", "c"] 1081 | [303.634993, "o", "e"] 1082 | [306.117023, "o", " "] 1083 | [306.414561, "o", "t"] 1084 | [306.499406, "o", "h"] 1085 | [306.596183, "o", "e"] 1086 | [306.681567, "o", " "] 1087 | [307.039749, "o", "e"] 1088 | [307.294286, "o", "x"] 1089 | [307.532283, "o", "a"] 1090 | [307.732974, "o", "c"] 1091 | [307.768781, "o", "t"] 1092 | [308.353597, "o", " "] 1093 | [308.53461, "o", "s"] 1094 | [309.176146, "o", "a"] 1095 | [309.318093, "o", "m"] 1096 | [309.448968, "o", "e"] 1097 | [309.580824, "o", " "] 1098 | [309.917655, "o", "e"] 1099 | [310.039528, "o", "n"] 1100 | [310.318172, "o", "v"] 1101 | [310.52895, "o", "i"] 1102 | [310.827045, "o", "r"] 1103 | [311.09431, "o", "o"] 1104 | [311.150895, "o", "n"] 1105 | [311.517583, "o", "m"] 1106 | [311.615752, "o", "e"] 1107 | [311.774995, "o", "n"] 1108 | [311.891117, "o", "t"] 1109 | [312.628553, "o", " "] 1110 | [313.012088, "o", "a"] 1111 | [313.172841, "o", "n"] 1112 | [313.26174, "o", "d"] 1113 | [313.357487, "o", " "] 1114 | [313.523639, "o", "i"] 1115 | [313.690941, "o", "t"] 1116 | [313.826126, "o", " "] 1117 | [314.183723, "o", "w"] 1118 | [314.274913, "o", "i"] 1119 | [314.48192, "o", "l"] 1120 | [314.618822, "o", "l"] 1121 | [314.705166, "o", " "] 1122 | [314.829508, "o", "a"] 1123 | [314.940128, "o", "l"] 1124 | [315.101704, "o", "w"] 1125 | [315.272637, "o", "a"] 1126 | [315.381016, "o", "y"] 1127 | [315.490388, "o", "s"] 1128 | [315.591172, "o", " "] 1129 | [316.18645, "o", "r"] 1130 | [316.457944, "o", "u"] 1131 | [316.518764, "o", "n"] 1132 | [316.518764, "o", "\u001b[0m"] 1133 | [318.547269, "o", "\r\n"] 1134 | [318.547558, "o", "\u001b[?2004l\r"] 1135 | [318.55221, "o", "\u001b[?2004h"] 1136 | [318.552221, "o", "$ "] 1137 | [318.552221, "o", "\u001b[1m"] 1138 | [320.126976, "o", "#"] 1139 | [320.299927, "o", " "] 1140 | [320.623899, "o", "E"] 1141 | [320.712588, "o", "n"] 1142 | [321.024419, "o", "j"] 1143 | [321.095314, "o", "o"] 1144 | [321.312223, "o", "y"] 1145 | [321.720402, "o", "!"] 1146 | [318.552221, "o", "\u001b[0m"] 1147 | --------------------------------------------------------------------------------