Skip to content

Commit

Permalink
lib: introduce repoToName, use it in all the fetchers tree-wide
Browse files Browse the repository at this point in the history
Motivation:

  Paths like "/nix/store/<hash>-source" are not particularly informative.
  This patch changes those paths to
  "/nix/store/<hash>-<name>-<version>-<fetcher>-source" by default.

Pros:

- Sources in /nix/store become easily discoverable.
- "These derivations will be built" list becomes more informative.
- This generalizes a bunch of copy-paste from the fetchers into a single
  function.
- It becomes harder to screw up `src` definitions (see previous patches in
  this patchset).

Cons:

- `nix-prefetch-(git|svn|etc)` will produce different paths. That can be
  fixed, but I didn't feel like reimplementing `repoToName` in shell.
  I would really like nix to get `nix prefetch` command that would
  do the fixed-outputs builds without checking the hashes instead.

- This introduces a negative effect on the allocations metric of about 0.2%
  and some unmeasurable negative effect on the time metric that gets
  lost in the jitter.
  • Loading branch information
oxij committed Nov 7, 2018
1 parent 509a802 commit 97dd9ed
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 58 deletions.
2 changes: 1 addition & 1 deletion lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ let
hiPrioSet;
inherit (sources) pathType pathIsDirectory cleanSourceFilter
cleanSource sourceByRegex sourceFilesBySuffices
commitIdFromGitRepo cleanSourceWith pathHasContext
commitIdFromGitRepo repoToName cleanSourceWith pathHasContext
canCleanSource;
inherit (modules) evalModules closeModules unifyModuleSyntax
applyIfFunction unpackSubmodule packSubmodule mergeModules
Expand Down
55 changes: 55 additions & 0 deletions lib/sources.nix
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,61 @@ rec {
else throw ("Not a .git directory: " + path);
in lib.flip readCommitFromFile "HEAD";

# Makeup a package name for a given repository and revision.
#
# This is used by fetch(zip|git|hg|svn|etc) to generate discoverable
# /nix/store paths.
repoToName = type: repo_: rev_:
let
repo = toString repo_; # url can be a path
rev = toString rev_; # rev can be a number

path = lib.reverseList (lib.splitString "/" (lib.removeSuffix "/" repo));

fst = lib.head path;
snd = lib.head (lib.tail path);
trd = lib.head (lib.tail (lib.tail path));

gitBase = builtins.match "(.*).git" fst;

svnBase =
# ../repo/trunk -> repo
if fst == "trunk" then snd
# ../repo/branches/branch -> repo
else if snd == "branches" then trd
# ../repo/tags/tag -> repo
else if snd == "tags" then trd
# ../repo (no trunk) -> repo
else fst;

base' =
if type == "git" && !isNull gitBase then builtins.head gitBase
else if type == "svn" then svnBase
else fst;

base = baseNameOf (lib.last (lib.splitString ":" base'));

svnRev =
# ../repo/branches/branch -> branch
# ../repo/tags/tag -> tag
if snd == "branches" || snd == "tags"
then "${fst}-${rev}"
else rev;

baseRev = lib.removePrefix base ( # revisions often contain project names
if type == "svn" then svnRev
else lib.last (lib.splitString "/" rev)
);

hashRev = builtins.match "[a-f0-9]+" baseRev;
versionRev = builtins.match "[-_. ]?(v|version|release)?[-_. ]?([0-9.]+.*)" baseRev;

shortRev =
if !isNull hashRev then builtins.substring 0 7 baseRev
else if !isNull versionRev then builtins.elemAt versionRev 1
else baseRev;
in "${base}-${shortRev}-${type}-source";

pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);

canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
Expand Down
19 changes: 3 additions & 16 deletions pkgs/build-support/fetchgit/default.nix
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
{stdenvNoCC, git, cacert}: let
urlToName = url: rev: let
inherit (stdenvNoCC.lib) removeSuffix splitString last;
base = last (splitString ":" (baseNameOf (removeSuffix "/" url)));

matched = builtins.match "(.*).git" base;

short = builtins.substring 0 7 rev;

appendShort = if (builtins.match "[a-f0-9]*" rev) != null
then "-${short}"
else "";
in "${if matched == null then base else builtins.head matched}${appendShort}";
in
{ lib, stdenvNoCC, git, cacert }:
{ url, rev ? "HEAD", md5 ? "", sha256 ? "", leaveDotGit ? deepClone
, fetchSubmodules ? true, deepClone ? false
, branchName ? null
, name ? urlToName url rev
, name ? lib.repoToName "git" url rev
, # Shell code executed after the file has been fetched
# successfully. This can do things like check or transform the file.
postFetch ? ""
Expand Down Expand Up @@ -62,7 +49,7 @@ stdenvNoCC.mkDerivation {

GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";

impureEnvVars = stdenvNoCC.lib.fetchers.proxyImpureEnvVars ++ [
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
"GIT_PROXY_COMMAND" "SOCKS_SERVER"
];

Expand Down
4 changes: 2 additions & 2 deletions pkgs/build-support/fetchhg/builder.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
source $stdenv/setup
header "getting $url${rev:+ ($rev)} into $out"
header "getting $url ($rev) into $out"

hg clone --insecure "$url" hg-clone

hg archive -q$subrepoClause -y ${rev:+-r "$rev"} --cwd hg-clone $out
hg archive -q$subrepoClause -y -r "$rev" --cwd hg-clone $out
rm -f $out/.hg_archival.txt

stopNest
11 changes: 8 additions & 3 deletions pkgs/build-support/fetchhg/default.nix
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
{stdenvNoCC, mercurial}: {name ? null, url, rev ? null, md5 ? null, sha256 ? null, fetchSubrepos ? false}:
{ lib, stdenvNoCC, mercurial }:
{ url, rev ? "tip", md5 ? null, sha256 ? null
, fetchSubrepos ? false
, name ? lib.repoToName "hg" url rev
}:

if md5 != null then
throw "fetchhg does not support md5 anymore, please use sha256"
else
# TODO: statically check if mercurial as the https support if the url starts woth https.
stdenvNoCC.mkDerivation {
name = "hg-archive" + (if name != null then "-${name}" else "");
inherit name;

builder = ./builder.sh;
nativeBuildInputs = [mercurial];

impureEnvVars = stdenvNoCC.lib.fetchers.proxyImpureEnvVars;
impureEnvVars = lib.fetchers.proxyImpureEnvVars;

subrepoClause = if fetchSubrepos then "S" else "";

Expand Down
2 changes: 1 addition & 1 deletion pkgs/build-support/fetchsvn/builder.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source $stdenv/setup

header "exporting $url (r$rev) into $out"
header "exporting $url ($rev) into $out"

if test "$sshSupport"; then
export SVN_SSH="$openssh/bin/ssh"
Expand Down
37 changes: 8 additions & 29 deletions pkgs/build-support/fetchsvn/default.nix
Original file line number Diff line number Diff line change
@@ -1,35 +1,14 @@
{stdenvNoCC, subversion, glibcLocales, sshSupport ? false, openssh ? null}:
{url, rev ? "HEAD", md5 ? "", sha256 ? "",
ignoreExternals ? false, ignoreKeywords ? false, name ? null}:
{ lib, stdenvNoCC, subversion, glibcLocales, sshSupport ? false, openssh ? null }:
{ url, rev ? "HEAD", md5 ? null, sha256 ? null
, ignoreExternals ? false, ignoreKeywords ? false
, name ? lib.repoToName "svn" url rev }:

let
repoName = with stdenvNoCC.lib;
let
fst = head;
snd = l: head (tail l);
trd = l: head (tail (tail l));
path_ =
(p: if head p == "" then tail p else p) # ~ drop final slash if any
(reverseList (splitString "/" url));
path = [ (removeSuffix "/" (head path_)) ] ++ (tail path_);
in
# ../repo/trunk -> repo
if fst path == "trunk" then snd path
# ../repo/branches/branch -> repo-branch
else if snd path == "branches" then "${trd path}-${fst path}"
# ../repo/tags/tag -> repo-tag
else if snd path == "tags" then "${trd path}-${fst path}"
# ../repo (no trunk) -> repo
else fst path;

name_ = if name == null then "${repoName}-r${toString rev}" else name;
in

if md5 != "" then
if md5 != null then
throw "fetchsvn does not support md5 anymore, please use sha256"
else
stdenvNoCC.mkDerivation {
name = name_;
inherit name;

builder = ./builder.sh;
nativeBuildInputs = [ subversion glibcLocales ];

Expand All @@ -39,6 +18,6 @@ stdenvNoCC.mkDerivation {

inherit url rev sshSupport openssh ignoreExternals ignoreKeywords;

impureEnvVars = stdenvNoCC.lib.fetchers.proxyImpureEnvVars;
impureEnvVars = lib.fetchers.proxyImpureEnvVars;
preferLocalBuild = true;
}
2 changes: 1 addition & 1 deletion pkgs/build-support/fetchzip/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
stripRoot ? true
, url
, extraPostFetch ? ""
, name ? "source"
, name ? lib.repoToName "unpack" url ""
, ... } @ args:

(fetchurl ({
Expand Down
11 changes: 6 additions & 5 deletions pkgs/top-level/all-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ with pkgs;
fetchCrate = callPackage ../build-support/rust/fetchcrate.nix { };

fetchFromGitHub = {
owner, repo, rev, name ? "source",
owner, repo, rev, name ? lib.repoToName "github" repo rev,
fetchSubmodules ? false, private ? false,
githubBase ? "github.com", varPrefix ? null,
... # For hash agility
Expand Down Expand Up @@ -269,7 +269,7 @@ with pkgs;
in fetcher fetcherArgs // { meta.homepage = baseUrl; inherit rev; };

fetchFromBitbucket = {
owner, repo, rev, name ? "source",
owner, repo, rev, name ? lib.repoToName "bitbucket" repo rev,
... # For hash agility
}@args: fetchzip ({
inherit name;
Expand All @@ -280,7 +280,7 @@ with pkgs;

# cgit example, snapshot support is optional in cgit
fetchFromSavannah = {
repo, rev, name ? "source",
repo, rev, name ? lib.repoToName "savannah" repo rev,
... # For hash agility
}@args: fetchzip ({
inherit name;
Expand All @@ -290,7 +290,8 @@ with pkgs;

# gitlab example
fetchFromGitLab = {
owner, repo, rev, domain ? "gitlab.com", name ? "source", group ? null,
owner, repo, rev, name ? lib.repoToName "gitlab" repo rev,
group ? null, domain ? "gitlab.com",
... # For hash agility
}@args: fetchzip ({
inherit name;
Expand All @@ -300,7 +301,7 @@ with pkgs;

# gitweb example, snapshot support is optional in gitweb
fetchFromRepoOrCz = {
repo, rev, name ? "source",
repo, rev, name ? lib.repoToName "repoorcz" repo rev,
... # For hash agility
}@args: fetchzip ({
inherit name;
Expand Down

0 comments on commit 97dd9ed

Please sign in to comment.