feat(tools/tvlc): init project
tvlc is a tool for managing sparse git worktrees of the TVL depot. It is still in development; near-term tasks include a setup script, Nix dependency resolution, worktree removal, and the dispatch script. See cs.tvl.fyi/depot/docs/designs/SPARSE_CHECKOUTS.md for more info. Change-Id: Iad96656f0206178980fe7dcadd3dffe70d690f8f Reviewed-on: https://cl.tvl.fyi/c/depot/+/1760 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
parent
d6f17f48de
commit
92d4554b62
5 changed files with 171 additions and 0 deletions
1
third_party/default.nix
vendored
1
third_party/default.nix
vendored
|
@ -137,6 +137,7 @@ let
|
|||
rustc
|
||||
s6-portable-utils
|
||||
sbcl
|
||||
shellcheck
|
||||
sqlite
|
||||
stdenvNoCC
|
||||
stern
|
||||
|
|
3
tools/tvlc/OWNERS
Normal file
3
tools/tvlc/OWNERS
Normal file
|
@ -0,0 +1,3 @@
|
|||
inherited: true
|
||||
owners:
|
||||
- riking
|
30
tools/tvlc/common.sh
Normal file
30
tools/tvlc/common.sh
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
tvlc_root="$XDG_DATA_HOME/tvlc"
|
||||
|
||||
if [ -f "$tvlc_root"/nice_checkout_root ]; then
|
||||
nice_checkout_root="$(cat "$tvlc_root"/nice_checkout_root)"
|
||||
fi
|
||||
nice_checkout_root="${nice_checkout_root:-$HOME/tvlc}"
|
||||
|
||||
depot_root=
|
||||
if [ -f "$tvlc_root/depot_root" ]; then
|
||||
depot_root="$(cat "$tvlc_root/depot_root")"
|
||||
fi
|
||||
if [ -d /depot ]; then
|
||||
# don't require config on tvl nixos servers
|
||||
depot_root="${depot_root:-/depot}"
|
||||
fi
|
||||
if [ -n "$depot_root" ]; then
|
||||
export DEPOT_ROOT="$depot_root"
|
||||
fi
|
||||
|
||||
if [ ! -d "$tvlc_root" ]; then
|
||||
echo "tvlc: setup required"
|
||||
echo "please run 'tvlc setup' from the depot root"
|
||||
exit 1
|
||||
fi
|
35
tools/tvlc/default.nix
Normal file
35
tools/tvlc/default.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ pkgs, depot, ... }:
|
||||
|
||||
let
|
||||
commonsh = ./common.sh;
|
||||
|
||||
# TODO(riking): path deduction
|
||||
#tvix-instantiate="${third_party.nix}/bin/nix-instantiate"
|
||||
pathScripts = pkgs.writeShellScript "imports" ''
|
||||
'';
|
||||
|
||||
# setup: git rev-parse --show-toplevel > $tvlc_root/depot_root
|
||||
# setup: mkdir $tvlc_root/clients
|
||||
# setup: echo 1 > $tvlc_root/next_clientid
|
||||
|
||||
tvlcNew = pkgs.stdenv.mkDerivation {
|
||||
name = "tvlc-new";
|
||||
src = ./tvlc-new;
|
||||
doCheck = true;
|
||||
|
||||
unpackPhase = "true";
|
||||
buildPhase = ''
|
||||
substitute ${./tvlc-new} $out --replace common.sh ${commonsh}
|
||||
'';
|
||||
checkPhase = ''
|
||||
${pkgs.shellcheck}/bin/shellcheck $out ${commonsh} && echo "SHELLCHECK OK"
|
||||
'';
|
||||
installPhase = ''
|
||||
chmod +x $out
|
||||
'';
|
||||
};
|
||||
|
||||
in pkgs.stdenv.mkDerivation rec {
|
||||
inherit commonsh;
|
||||
inherit tvlcNew;
|
||||
}
|
102
tools/tvlc/tvlc-new
Executable file
102
tools/tvlc/tvlc-new
Executable file
|
@ -0,0 +1,102 @@
|
|||
#!/bin/bash
|
||||
|
||||
source common.sh
|
||||
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
function usage() {
|
||||
echo "tvlc new [-n|--name CLIENTNAME] [derivation...]"
|
||||
echo ""
|
||||
cat <<EOF
|
||||
The 'new' command creates a new git sparse checkout with the given name, and
|
||||
contents needed to build the Nix derivation(s) specified on the command line.
|
||||
|
||||
Options:
|
||||
-n/--name client-name: Sets the git branch and nice checkout name for the
|
||||
workspace. If the option is not provided, the name will be based on the
|
||||
first non-option command-line argument.
|
||||
--branch branch-name: Sets the git branch name only.
|
||||
EOF
|
||||
}
|
||||
|
||||
checkout_name=
|
||||
branch_name=
|
||||
|
||||
options=$(getopt -o 'n:' --long debug --long name: -- "$@")
|
||||
eval set -- "$options"
|
||||
while true; do
|
||||
case "$1" in
|
||||
-h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-v)
|
||||
version
|
||||
exit 0
|
||||
;;
|
||||
-n|--name)
|
||||
shift
|
||||
checkout_name="$1"
|
||||
if [ -z "$branch_name" ]; then
|
||||
branch_name=tvlc-"$1"
|
||||
fi
|
||||
;;
|
||||
--branch)
|
||||
shift
|
||||
branch_name="$1"
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "error: workspace name, target derivations required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$checkout_name" ]; then
|
||||
# TODO(riking): deduce
|
||||
echo "error: workspace name (-n) required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$nice_checkout_root/$checkout_name" ]; then
|
||||
echo "error: checkout $checkout_name already exists"
|
||||
# nb: shellescape checkout_name because we expect the user to copy-paste it
|
||||
# shellcheck disable=SC1003
|
||||
echo "consider deleting it with tvlc remove '${checkout_name/'/\'}'"
|
||||
exit 1
|
||||
fi
|
||||
if [ -f "$DEPOT_ROOT/.git/refs/heads/$branch_name" ]; then
|
||||
echo "error: branch $branch_name already exists in git"
|
||||
# shellcheck disable=SC1003
|
||||
echo "consider deleting it with cd $DEPOT_ROOT; git branch -d '${checkout_name/'/\'}'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO(riking): tvlc-get-depends
|
||||
|
||||
# bash math
|
||||
checkout_id=$(("$(cat "$tvlc_root/next_clientid")"))
|
||||
next_checkout_id=$(("$checkout_id"+1))
|
||||
echo "$next_checkout_id" > "$tvlc_root/next_clientid"
|
||||
|
||||
checkout_dir="$tvlc_root/clients/$checkout_id"
|
||||
mkdir "$checkout_dir"
|
||||
cd "$DEPOT_ROOT"
|
||||
git worktree add --no-checkout -b "$branch_name" "$checkout_dir"
|
||||
# BUG: git not creating the /info/ subdir
|
||||
mkdir "$DEPOT_ROOT/.git/worktrees/$checkout_id/info"
|
||||
|
||||
cd "$checkout_dir"
|
||||
git sparse-checkout init --cone
|
||||
git sparse-checkout set "$@"
|
||||
|
||||
ln -s "$checkout_dir" "$nice_checkout_root"/"$checkout_name"
|
||||
|
||||
echo "$nice_checkout_root/$checkout_name"
|
Loading…
Reference in a new issue