1#!/usr/bin/env bash
2
3set -euo pipefail
4
5AGPL_CRATES=("collab")
6RELEASE_CRATES=("cli" "remote_server" "zed")
7
8check_symlink_target () {
9 local symlink_path="$1"
10 local license_name="$2"
11
12 local target=$(readlink "$symlink_path")
13
14 local dir=$(dirname "$symlink_path")
15 local depth=$(echo "$dir" | tr '/' '\n' | wc -l)
16 local expected_prefix=""
17 for ((i = 0; i < depth; i++)); do
18 expected_prefix="../$expected_prefix"
19 done
20 local expected_target="${expected_prefix}${license_name}"
21
22 if [[ "$target" != "$expected_target" ]]; then
23 echo "Error: $symlink_path points to '$target' but should point to '$expected_target'"
24 exit 1
25 fi
26
27 if [[ ! -e "$symlink_path" ]]; then
28 echo "Error: $symlink_path is a broken symlink (target '$target' does not exist)"
29 exit 1
30 fi
31}
32
33check_license () {
34 local dir="$1"
35 local allowed_licenses=()
36
37 local is_agpl=false
38 for agpl_crate in "${AGPL_CRATES[@]}"; do
39 if [[ "$dir" == "crates/$agpl_crate" ]]; then
40 is_agpl=true
41 break
42 fi
43 done
44
45 if [[ "$is_agpl" == true ]]; then
46 allowed_licenses=("LICENSE-AGPL")
47 else
48 allowed_licenses=("LICENSE-GPL" "LICENSE-APACHE")
49 fi
50
51 for license in "${allowed_licenses[@]}"; do
52 if [[ -L "$dir/$license" ]]; then
53 check_symlink_target "$dir/$license" "$license"
54 return 0
55 elif [[ -e "$dir/$license" ]]; then
56 echo "Error: $dir/$license exists but is not a symlink."
57 exit 1
58 fi
59 done
60
61 if [[ "$is_agpl" == true ]]; then
62 echo "Error: $dir does not contain a LICENSE-AGPL symlink"
63 else
64 echo "Error: $dir does not contain a LICENSE-GPL or LICENSE-APACHE symlink"
65 fi
66 exit 1
67}
68
69git ls-files "**/*/Cargo.toml" | while read -r cargo_toml; do
70 check_license "$(dirname "$cargo_toml")"
71done
72
73
74# Make sure the AGPL server crates are included in the release tarball.
75for release_crate in "${RELEASE_CRATES[@]}"; do
76 tree_output=$(cargo tree --package "$release_crate")
77 for agpl_crate in "${AGPL_CRATES[@]}"; do
78 # Look for lines that contain the crate name followed by " v" (version)
79 # This matches patterns like "├── collab v0.44.0"
80 if echo "$tree_output" | grep -E "(^|[^a-zA-Z_])${agpl_crate} v" > /dev/null; then
81 echo "Error: crate '${agpl_crate}' is AGPL and is a dependency of crate '${release_crate}'." >&2
82 echo "AGPL licensed code should not be used in the release distribution, only in servers." >&2
83 exit 1
84 fi
85 done
86done
87
88echo "check-licenses succeeded"