niv 0.2.13 → 0.2.14
raw patch · 8 files changed
+231/−61 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Niv.Cli: Nixpkgs :: Text -> Text -> Nixpkgs
+ Niv.Cli: NoNixpkgs :: FetchNixpkgs
+ Niv.Cli: YesNixpkgs :: Text -> Nixpkgs -> FetchNixpkgs
+ Niv.Cli: data FetchNixpkgs
+ Niv.Cli: data Nixpkgs
+ Niv.Cli: defaultNixpkgsBranch :: Text
+ Niv.Cli: defaultNixpkgsRepo :: Text
+ Niv.Cli: defaultNixpkgsUser :: Text
+ Niv.Cli: instance GHC.Show.Show Niv.Cli.Nixpkgs
+ Niv.Local.Cmd: describeLocal :: InfoMod a
+ Niv.Local.Cmd: localCmd :: Cmd
+ Niv.Local.Cmd: parseLocalPackageSpec :: Parser PackageSpec
+ Niv.Local.Cmd: parseLocalShortcut :: Text -> Maybe (PackageName, Object)
+ Niv.Sources: V17 :: SourcesNixVersion
+ Niv.Sources: V18 :: SourcesNixVersion
- Niv.Cli: cmdInit :: NIO ()
+ Niv.Cli: cmdInit :: FetchNixpkgs -> NIO ()
Files
- README.md +59/−14
- niv.cabal +4/−3
- nix/sources.nix +33/−29
- src/Niv/Cli.hs +66/−13
- src/Niv/GitHub.hs +1/−1
- src/Niv/GitHub/Cmd.hs +1/−1
- src/Niv/Local/Cmd.hs +59/−0
- src/Niv/Sources.hs +8/−0
README.md view
@@ -9,6 +9,12 @@ <img src="https://niv.nmattia.com/niv.svg"> </p> ++* [Install](#install)+* [Build](#build)+* [Usage](#usage)+* [FAQ](#frequently-asked-questions)+ ## Install `niv` is available in [`nixpkgs`](https://github.com/NixOS/nixpkgs) on the@@ -16,7 +22,9 @@ `haskellPackages.niv`. Otherwise, run: ``` bash-$ nix-env -iA niv -f https://github.com/nmattia/niv/tarball/master+$ nix-env -iA niv -f https://github.com/nmattia/niv/tarball/master \+ --substituters https://niv.cachix.org \+ --trusted-public-keys niv.cachix.org-1:X32PCg2e/zAm3/uD1ScqW2z/K0LtDyNV7RdaxIuLgQM= ``` ## Build@@ -99,13 +107,13 @@ ``` json { "nixpkgs": {- "url": "https://github.com/NixOS/nixpkgs-channels/archive/109a28ab954a0ad129f7621d468f829981b8b96c.tar.gz",+ "url": "https://github.com/NixOS/nixpkgs/archive/109a28ab954a0ad129f7621d468f829981b8b96c.tar.gz", "owner": "NixOS", "branch": "nixos-19.09", "url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz",- "repo": "nixpkgs-channels",+ "repo": "nixpkgs", "sha256": "12wnxla7ld4cgpdndaipdh3j4zdalifk287ihxhnmrzrghjahs3q",- "description": "Nixpkgs/NixOS branches that track the Nixpkgs/NixOS channels",+ "description": "Nix Packages collection", "rev": "109a28ab954a0ad129f7621d468f829981b8b96c" }, "niv": {@@ -204,7 +212,7 @@ ``` niv - dependency manager for Nix projects -version: 0.2.13+version: 0.2.14 Usage: niv [-s|--sources-file FILE] COMMAND @@ -221,7 +229,6 @@ modify Modify dependency attributes without performing an update drop Drop dependency- ``` #### Add@@ -230,7 +237,7 @@ Examples: niv add stedolan/jq- niv add NixOS/nixpkgs-channels -n nixpkgs -b nixos-19.09+ niv add NixOS/nixpkgs -n nixpkgs -b nixpkgs-unstable niv add my-package -v alpha-0.1 -t http://example.com/archive/<version>.zip Usage: niv add PACKAGE [-n|--name NAME] ([-a|--attribute KEY=VAL] |@@ -259,7 +266,7 @@ Experimental commands: git Add a git dependency. Experimental. github Add a GitHub dependency-+ local Add a local dependency. Experimental. ``` #### Update@@ -292,7 +299,6 @@ 'file' or 'tarball'. If not set, the value is inferred from the suffix of the URL. -h,--help Show this help text- ``` #### Modify@@ -325,7 +331,6 @@ 'file' or 'tarball'. If not set, the value is inferred from the suffix of the URL. -h,--help Show this help text- ``` #### Drop@@ -341,18 +346,21 @@ Available options: -h,--help Show this help text- ``` #### Init ```-Usage: niv init +Usage: niv init ([--no-nixpkgs] | [-b|--nixpkgs-branch ARG]+ [--nixpkgs OWNER/REPO]) Initialize a Nix project. Existing files won't be modified. Available options:+ --no-nixpkgs Don't add a nixpkgs entry to sources.json.+ -b,--nixpkgs-branch ARG The nixpkgs branch to use. (default: "release-20.03")+ --nixpkgs OWNER/REPO Use a custom nixpkgs repository from+ GitHub. (default: NixOS/nixpkgs) -h,--help Show this help text- ``` #### show@@ -362,9 +370,46 @@ Available options: -h,--help Show this help text- ``` [Nix]: https://nixos.org/nix/ [jq]: https://stedolan.github.io/jq/ [GHC]: https://www.haskell.org/ghc/+++## Frequently Asked Questions++### Can you use private GitHub repositories?++Yes. There are two ways:++#### 1. Use the git protocol++When using the git protocol, your public SSH keypair is used to authenticate+you:++``` shell+$ niv add git git@github.com:my_user/my_private_repo+```++##### 2. Use the netrc file++in order to `niv add` a private github repo you'll need to:++1. create a .netrc file with the following content+```+machine github.com+ login YOUR_GITHUB_USER_NAME+ password YOUR_GITHUB_TOKEN+```++2. add the path to the above file to `/etc/nix/nix.conf`:+```+netrc-file = /PATH/TO/.netrc+```++3. set `GITHUB_TOKEN` env var when calling `niv add`+```+GITHUB_TOKEN=$YOUR_GITHUB_TOKEN niv add ...+```+
niv.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.32.0.+-- This file has been generated from package.yaml by hpack version 0.33.0. -- -- see: https://github.com/sol/hpack ----- hash: a1d6256f329a5a130dcb0d8cbcbef0144451cc06f2ac5e70034bf3ed419b8914+-- hash: 7f73602ea1ac16df6a54a599572573246b2d3260596b88111bc2971a028ac645 name: niv-version: 0.2.13+version: 0.2.14 synopsis: Easy dependency management for Nix projects description: Easy dependency management for Nix projects. category: Development@@ -41,6 +41,7 @@ Niv.GitHub.API Niv.GitHub.Cmd Niv.GitHub.Test+ Niv.Local.Cmd Niv.Logger Niv.Sources Niv.Sources.Test
nix/sources.nix view
@@ -12,36 +12,29 @@ else pkgs.fetchurl { inherit (spec) url sha256; }; - fetch_tarball = pkgs: spec:- if spec.builtin or true then- builtins_fetchTarball { inherit (spec) url sha256; }- else- pkgs.fetchzip { inherit (spec) url sha256; };+ fetch_tarball = pkgs: name: spec:+ let+ ok = str: ! builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str);+ # sanitize the name, though nix will still fail if name starts with period+ name' = stringAsChars (x: if ! ok x then "-" else x) "${name}-src";+ in+ if spec.builtin or true then+ builtins_fetchTarball { name = name'; inherit (spec) url sha256; }+ else+ pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; fetch_git = spec: builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; - fetch_builtin-tarball = spec:- builtins.trace- ''- WARNING:- The niv type "builtin-tarball" will soon be deprecated. You should- instead use `builtin = true`.-- $ niv modify <package> -a type=tarball -a builtin=true- ''- builtins_fetchTarball { inherit (spec) url sha256; };+ fetch_local = spec: spec.path; - fetch_builtin-url = spec:- builtins.trace- ''- WARNING:- The niv type "builtin-url" will soon be deprecated. You should- instead use `builtin = true`.+ fetch_builtin-tarball = name: throw+ ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.+ $ niv modify ${name} -a type=tarball -a builtin=true''; - $ niv modify <package> -a type=file -a builtin=true- ''- (builtins_fetchurl { inherit (spec) url sha256; });+ fetch_builtin-url = name: throw+ ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.+ $ niv modify ${name} -a type=file -a builtin=true''; # # Various helpers@@ -72,10 +65,11 @@ if ! builtins.hasAttr "type" spec then abort "ERROR: niv spec ${name} does not have a 'type' attribute" else if spec.type == "file" then fetch_file pkgs spec- else if spec.type == "tarball" then fetch_tarball pkgs spec+ else if spec.type == "tarball" then fetch_tarball pkgs name spec else if spec.type == "git" then fetch_git spec- else if spec.type == "builtin-tarball" then fetch_builtin-tarball spec- else if spec.type == "builtin-url" then fetch_builtin-url spec+ else if spec.type == "local" then fetch_local spec+ else if spec.type == "builtin-tarball" then fetch_builtin-tarball name+ else if spec.type == "builtin-url" then fetch_builtin-url name else abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; @@ -87,13 +81,23 @@ listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) ); + # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295+ range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);++ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257+ stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));++ # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269+ stringAsChars = f: s: concatStrings (map f (stringToCharacters s));+ concatStrings = builtins.concatStringsSep "";+ # fetchTarball version that is compatible between all the versions of Nix- builtins_fetchTarball = { url, sha256 }@attrs:+ builtins_fetchTarball = { url, name, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchTarball; in if lessThan nixVersion "1.12" then- fetchTarball { inherit url; }+ fetchTarball { inherit name url; } else fetchTarball attrs;
src/Niv/Cli.hs view
@@ -19,6 +19,7 @@ import Data.Version (showVersion) import Niv.Cmd import Niv.Git.Cmd+import Niv.Local.Cmd import Niv.GitHub.Cmd import Niv.Logger import Niv.Sources@@ -96,17 +97,59 @@ -- INIT ------------------------------------------------------------------------------- +-- | Whether or not to fetch nixpkgs+data FetchNixpkgs+ = NoNixpkgs+ | YesNixpkgs T.Text Nixpkgs -- branch, nixpkgs++data Nixpkgs = Nixpkgs T.Text T.Text -- owner, repo++instance Show Nixpkgs where+ show (Nixpkgs o r) = T.unpack o <> "/" <> T.unpack r++-- | The default nixpkgs+defaultNixpkgsRepo, defaultNixpkgsUser, defaultNixpkgsBranch :: T.Text+defaultNixpkgsRepo = "nixpkgs"+defaultNixpkgsUser = "NixOS"+defaultNixpkgsBranch = "release-20.03"+ parseCmdInit :: Opts.ParserInfo (NIO ())-parseCmdInit = Opts.info (pure cmdInit <**> Opts.helper) $ mconcat desc+parseCmdInit = Opts.info (cmdInit <$> parseNixpkgs <**> Opts.helper) $ mconcat desc where+ customNixpkgsReader = Opts.maybeReader $ \(T.pack -> repo) -> case T.splitOn "/" repo of+ [owner, reponame] -> Just (Nixpkgs owner reponame)+ _ -> Nothing+ parseNixpkgs =+ Opts.flag' NoNixpkgs+ (+ Opts.long "no-nixpkgs" <>+ Opts.help "Don't add a nixpkgs entry to sources.json."+ ) <|>+ (YesNixpkgs <$>+ (Opts.strOption+ (+ Opts.long "nixpkgs-branch" <>+ Opts.short 'b' <>+ Opts.help "The nixpkgs branch to use." <>+ Opts.showDefault <>+ Opts.value defaultNixpkgsBranch+ )+ ) <*> Opts.option customNixpkgsReader+ (+ Opts.long "nixpkgs" <>+ Opts.showDefault <>+ Opts.help "Use a custom nixpkgs repository from GitHub." <>+ Opts.metavar "OWNER/REPO" <>+ Opts.value (Nixpkgs defaultNixpkgsUser defaultNixpkgsRepo)+ )) desc = [ Opts.fullDesc , Opts.progDesc "Initialize a Nix project. Existing files won't be modified." ] -cmdInit :: NIO ()-cmdInit = do+cmdInit :: FetchNixpkgs -> NIO ()+cmdInit nixpkgs = do job "Initializing" $ do fsj <- getFindSourcesJson @@ -125,7 +168,7 @@ , ( pathNixSourcesJson fsj , \path -> do createFile path initNixSourcesJsonContent- -- Imports @niv@ and @nixpkgs@ (19.09)+ -- Imports @niv@ and @nixpkgs@ say "Importing 'niv' ..." cmdAdd (updateCmd githubCmd) (PackageName "niv") (specToFreeAttrs $ PackageSpec $ HMS.fromList@@ -133,14 +176,19 @@ , "repo" .= ("niv" :: T.Text) ] )- say "Importing 'nixpkgs' ..."- cmdAdd (updateCmd githubCmd) (PackageName "nixpkgs")- (specToFreeAttrs $ PackageSpec $ HMS.fromList- [ "owner" .= ("NixOS" :: T.Text)- , "repo" .= ("nixpkgs-channels" :: T.Text)- , "branch" .= ("nixos-19.09" :: T.Text)- ]- )+ case nixpkgs of+ NoNixpkgs -> say "Not importing 'nixpkgs'."+ YesNixpkgs branch nixpkgs' -> do+ say "Importing 'nixpkgs' ..."+ let (owner, repo) = case nixpkgs' of+ Nixpkgs o r -> (o,r)+ cmdAdd (updateCmd githubCmd) (PackageName "nixpkgs")+ (specToFreeAttrs $ PackageSpec $ HMS.fromList+ [ "owner" .= owner+ , "repo" .= repo+ , "branch" .= branch+ ]+ ) , \path _content -> dontCreateFile path) ] $ \(path, onCreate, onUpdate) -> do exists <- li $ Dir.doesFileExist path@@ -190,13 +238,16 @@ parseCmd cmd = uncurry (cmdAdd (updateCmd cmd)) <$> (parseCmdArgs cmd) parseCmdAddGit = Opts.info (parseCmd gitCmd <**> Opts.helper) (description gitCmd)+ parseCmdAddLocal =+ Opts.info (parseCmd localCmd <**> Opts.helper) (description localCmd) parseCmdAddGitHub = Opts.info (parseCmd githubCmd <**> Opts.helper) (description githubCmd) parseCommands = Opts.subparser ( Opts.hidden <> Opts.commandGroup "Experimental commands:" <> Opts.command "git" parseCmdAddGit <>- Opts.command "github" parseCmdAddGitHub+ Opts.command "github" parseCmdAddGitHub <>+ Opts.command "local" parseCmdAddLocal ) -- | only used in shortcuts (niv add foo/bar ...) because PACKAGE is NOT@@ -341,6 +392,7 @@ -- github let cmd = case HMS.lookup "type" (unPackageSpec defaultSpec) of Just "git" -> gitCmd+ Just "local" -> localCmd _ -> githubCmd fmap attrsToSpec <$> li (tryEvalUpdate (specToLockedAttrs cliSpec <> specToFreeAttrs defaultSpec)@@ -366,6 +418,7 @@ -- github let cmd = case HMS.lookup "type" (unPackageSpec defaultSpec) of Just "git" -> gitCmd+ Just "local" -> localCmd _ -> githubCmd finalSpec <- fmap attrsToSpec <$> li (tryEvalUpdate initialSpec
src/Niv/GitHub.hs view
@@ -33,7 +33,7 @@ (useOrSet "url_template" <<< completeSpec) <+> (load "url_template") -< () url <- update "url" -< urlTemplate- let isTar = ("tar.gz" `T.isSuffixOf`) <$> url+ let isTar = (\u -> "tar.gz" `T.isSuffixOf` u || ".tgz" `T.isSuffixOf` u) <$> url useOrSet "type" -< bool "file" "tarball" <$> isTar :: Box T.Text let doUnpack = isTar _sha256 <- update "sha256" <<< run (\(up, u) -> prefetch up u) -< (,) <$> doUnpack <*> url
src/Niv/GitHub/Cmd.hs view
@@ -110,7 +110,7 @@ "Examples:" Opts.<$$> "" Opts.<$$> " niv add stedolan/jq" Opts.<$$>- " niv add NixOS/nixpkgs-channels -n nixpkgs -b nixos-19.09" Opts.<$$>+ " niv add NixOS/nixpkgs -n nixpkgs -b nixpkgs-unstable" Opts.<$$> " niv add my-package -v alpha-0.1 -t http://example.com/archive/<version>.zip" ]
+ src/Niv/Local/Cmd.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE Arrows #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE ViewPatterns #-}++module Niv.Local.Cmd where++import Niv.Cmd+import Control.Arrow+import Niv.Sources+import Niv.Update+import qualified Data.Aeson as Aeson+import qualified Data.HashMap.Strict as HMS+import qualified Data.Text as T+import qualified Options.Applicative as Opts+import qualified Options.Applicative.Help.Pretty as Opts++localCmd :: Cmd+localCmd = Cmd+ { description = describeLocal+ , parseCmdShortcut = parseLocalShortcut+ , parsePackageSpec = parseLocalPackageSpec+ , updateCmd = proc () -> do+ useOrSet "type" -< ("local" :: Box T.Text)+ returnA -< ()+ , name = "local"+ }++parseLocalShortcut :: T.Text -> Maybe (PackageName, Aeson.Object)+parseLocalShortcut txt =+ if (T.isPrefixOf "./" txt || T.isPrefixOf "/" txt ) then do+ let n = last $ T.splitOn "/" txt+ Just (PackageName n, HMS.fromList [ ("path", Aeson.String txt) ])+ else Nothing++parseLocalPackageSpec :: Opts.Parser PackageSpec+parseLocalPackageSpec = PackageSpec . HMS.fromList <$> parseParams+ where+ parseParams :: Opts.Parser [(T.Text, Aeson.Value)]+ parseParams = maybe [] pure <$> Opts.optional parsePath++ parsePath =+ ("path", ) . Aeson.String <$> Opts.strOption+ ( Opts.long "path" <>+ Opts.metavar "PATH"+ )++describeLocal :: Opts.InfoMod a+describeLocal = mconcat+ [ Opts.fullDesc+ , Opts.progDesc "Add a local dependency. Experimental."+ , Opts.headerDoc $ Just $+ "Examples:" Opts.<$$>+ "" Opts.<$$>+ " niv add local ./foo/bar"+ ]
src/Niv/Sources.hs view
@@ -147,6 +147,10 @@ | V14 | V15 | V16+ | V17+ -- prettify derivation name+ -- add 'local' type of sources+ | V18 deriving stock (Bounded, Enum, Eq) -- | A user friendly version@@ -168,6 +172,8 @@ V14 -> "14" V15 -> "15" V16 -> "16"+ V17 -> "17"+ V18 -> "18" latestVersionMD5 :: T.Text latestVersionMD5 = sourcesVersionToMD5 maxBound@@ -196,6 +202,8 @@ V14 -> "b470e235e7bcbf106d243fea90b6cfc9" V15 -> "dc11af910773ec9b4e505e0f49ebcfd2" V16 -> "2d93c52cab8e960e767a79af05ca572a"+ V17 -> "149b8907f7b08dc1c28164dfa55c7fad"+ V18 -> "bc5e6aefcaa6f9e0b2155ca4f44e5a33" -- | The MD5 sum of ./nix/sources.nix sourcesNixMD5 :: IO T.Text