refactor(readTree): Move 'restrictFolder' function into readTree

This is generally useful for readTree users and should be part of
readTree itself.

This is a move towards exposing several readTree-related features from
the library itself, in the future also including logic like 'gather'.

Note that this has a small functional change: In error messages of the
function, the notation for accessing Nix attributes is now used rather
than the Perforce-style `//` notation common in TVL.

For example, an error at `//web/tvl/logo` will produce `web.tvl.logo`
in the error message (which corresponds to the readTree attribute
itself).

This makes more sense for non-TVL consumers of readTree, as the
Perforce-style notation is custom to us specifically.

Change-Id: I8e199e473843c40db40b404c20d2c71f48a0f658
This commit is contained in:
Vincent Ambo 2021-11-23 14:24:58 +03:00
parent 95ee86225b
commit bc51bd99d9
2 changed files with 37 additions and 26 deletions

View file

@ -6,10 +6,7 @@
let let
inherit (builtins) inherit (builtins)
attrValues
concatMap concatMap
elem
elemAt
filter filter
; ;
@ -17,27 +14,10 @@ let
# package set is not available here. # package set is not available here.
fix = f: let x = f x; in x; fix = f: let x = f x; in x;
# Create a readTree filter disallowing access to the specified readTree = import ./nix/readTree {};
# top-level folder in other parts of the depot, except for specific
# exceptions specified by their (full) paths.
restrictFolder = { folder, exceptions ? [], reason }: parts: args:
if (elemAt parts 0) == folder || elem parts exceptions
then args
else args // {
depot = args.depot // {
"${folder}" = throw ''
Access to targets under //${folder} is not permitted from
other depot paths. Specific exceptions are configured at the
top-level.
${reason}
At location: //${builtins.concatStringsSep "/" parts}
'';
};
};
# Disallow access to //users from other depot parts. # Disallow access to //users from other depot parts.
usersFilter = restrictFolder { usersFilter = readTree.restrictFolder {
folder = "users"; folder = "users";
reason = '' reason = ''
Code under //users is not considered stable or dependable in the Code under //users is not considered stable or dependable in the
@ -60,7 +40,7 @@ let
}; };
# Disallow access to //corp from other depot parts. # Disallow access to //corp from other depot parts.
corpFilter = restrictFolder { corpFilter = readTree.restrictFolder {
folder = "corp"; folder = "corp";
reason = '' reason = ''
Code under //corp may use incompatible licensing terms with Code under //corp may use incompatible licensing terms with
@ -76,7 +56,7 @@ let
]; ];
}; };
readDepot = depotArgs: import ./nix/readTree {} { readDepot = depotArgs: readTree {
args = depotArgs; args = depotArgs;
path = ./.; path = ./.;
filter = parts: args: corpFilter parts (usersFilter parts args); filter = parts: args: corpFilter parts (usersFilter parts args);

View file

@ -20,13 +20,13 @@
let let
inherit (builtins) inherit (builtins)
attrNames attrNames
baseNameOf
concatStringsSep concatStringsSep
elem
elemAt
filter filter
hasAttr hasAttr
head head
isAttrs isAttrs
length
listToAttrs listToAttrs
map map
match match
@ -138,4 +138,35 @@ in {
rootDir = true; rootDir = true;
parts = []; parts = [];
}; };
# In addition to readTree itself, some functionality is exposed that
# is useful for users of readTree.
# Create a readTree filter disallowing access to the specified
# top-level folder in the repository, except for specific exceptions
# specified by their (full) paths.
#
# Called with the arguments:
#
# folder: Name of the restricted top-level folder (e.g. 'experimental')
#
# exceptions: List of readTree parts (e.g. [ [ "services" "some-app" ] ]),
# which should be able to access the restricted folder.
#
# reason: Textual explanation for the restriction (included in errors)
restrictFolder = { folder, exceptions ? [], reason }: parts: args:
if (elemAt parts 0) == folder || elem parts exceptions
then args
else args // {
depot = args.depot // {
"${folder}" = throw ''
Access to targets under //${folder} is not permitted from
other repository paths. Specific exceptions are configured
at the top-level.
${reason}
At location: ${builtins.concatStringsSep "." parts}
'';
};
};
} }