/ dhall-to-buck
dhall-to-buck
 1  #!/usr/bin/env bash
 2  # dhall-to-buck - Transpile BUILD.dhall to BUCK
 3  set -euo pipefail
 4  
 5  [[ $# -lt 1 ]] && { echo "Usage: $0 <BUILD.dhall>" >&2; exit 1; }
 6  
 7  INPUT="$1"
 8  
 9  # Check if this is the new format (exports { rules, header }) or legacy (List Binary)
10  STRUCTURE=$(dhall type <<< "./$INPUT" 2>/dev/null || echo "unknown")
11  
12  if [[ "$STRUCTURE" == *"rules"* && "$STRUCTURE" == *"header"* ]]; then
13    # New format: { rules : List Text, header : Text }
14    HEADER=$(dhall text <<< "(./$INPUT).header")
15    echo "# Generated from $INPUT"
16    echo "$HEADER"
17    dhall text <<< "let P = ./dhall/prelude/Prelude.dhall in P.Text.concatSep \"\\n\" (./$INPUT).rules"
18    exit 0
19  fi
20  
21  # Legacy format: List C.Binary (for backward compat with existing BUILD.dhall files)
22  DEPS=$(dhall text <<< "(./dhall/prelude/extract-deps.dhall) ./$INPUT" 2>/dev/null || echo "")
23  
24  if [[ -z "$DEPS" ]]; then
25    echo "# Generated from $INPUT"
26    echo 'load("@toolchains//:cxx.bzl", "cxx_binary")'
27    echo ""
28    dhall text <<< "
29  let S = ./dhall/prelude/to-starlark.dhall
30  let C = ./dhall/prelude/Cxx.dhall
31  let t = List/head C.Binary ./$INPUT
32  in merge { None = \"\", Some = \\(b : C.Binary) -> S.binary b { compiler = [] : List Text, linker = [] : List Text } } t"
33    exit 0
34  fi
35  
36  FLAGS=$(buck2 run //src/nix-analyze:nix-analyze -- resolve $DEPS 2>/dev/null | grep -v "^\[")
37  
38  CF="" LF="" next=false
39  while IFS= read -r f; do
40    [[ -z "$f" ]] && continue
41    if $next; then CF+="\"$f\", "; next=false
42    elif [[ "$f" == "-isystem" ]]; then CF+="\"$f\", "; next=true
43    elif [[ "$f" == -I* ]]; then CF+="\"$f\", "
44    elif [[ "$f" == -L* || "$f" == -Wl,* || "$f" == -l* ]]; then LF+="\"$f\", "
45    fi
46  done <<< "$FLAGS"
47  
48  echo "# Generated from $INPUT"
49  echo "# Deps: ${DEPS//$'\n'/, }"
50  echo ""
51  echo 'load("@toolchains//:cxx.bzl", "cxx_binary")'
52  echo ""
53  dhall text <<< "
54  let S = ./dhall/prelude/to-starlark.dhall
55  let C = ./dhall/prelude/Cxx.dhall
56  let t = List/head C.Binary ./$INPUT
57  let f = { compiler = [${CF%,*}], linker = [${LF%,*}] }
58  in merge { None = \"\", Some = \\(b : C.Binary) -> S.binary b f } t"