about summary refs log tree commit diff
path: root/tools/tvlc/tvlc-new
blob: 4ef0df5d33b280b0e7ea83c5ab7adebe6e573a83 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/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

# The big one: call into Nix to figure out what paths the desired derivations depend on.
readarray -t includedPaths < <("$depot_scanner" --mode 'print' --only 'DEPOT' --relpath --depot "$DEPOT_ROOT" --nix-bin "$tvix_instantiate" "$@")

# 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 "${includedPaths[@]}"

ln -s "$checkout_dir" "$nice_checkout_root"/"$checkout_name"

echo "$nice_checkout_root/$checkout_name"