-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·168 lines (145 loc) · 5.65 KB
/
build.sh
File metadata and controls
executable file
·168 lines (145 loc) · 5.65 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/bash
# build.sh - Create single-file clsecure from modular structure
#
# This script concatenates all modules and main script into a single file
# for distribution, while preserving functionality and variable initialization order.
#
# Usage: ./build.sh [output-file]
# output-file: Output file path (default: clsecure)
set -euo pipefail
OUTPUT_FILE="${1:-clsecure}"
LIB_DIR="lib"
MAIN_SCRIPT_SRC="clsecure-src" # Modular source file (sources from lib/)
if [ ! -d "$LIB_DIR" ]; then
echo "Error: lib/ directory not found. Run from project root." >&2
exit 1
fi
if [ ! -f "$MAIN_SCRIPT_SRC" ]; then
echo "Error: $MAIN_SCRIPT_SRC not found. Run from project root." >&2
echo "Expected modular source file: $MAIN_SCRIPT_SRC" >&2
exit 1
fi
echo "Building single-file distribution: $OUTPUT_FILE"
echo " Source: $MAIN_SCRIPT_SRC"
echo " Modules: $LIB_DIR/"
# Step 1: Start with shebang and header
cat > "$OUTPUT_FILE" << 'HEADER'
#!/bin/bash
# clsecure - Enhanced isolation with User + Namespace (Firejail)
# This file is auto-generated from modular source. Do not edit directly.
# Source: https://github.com/pablopda/clsecure
#
# To modify: Edit files in lib/ directory and run ./build.sh
set -euo pipefail
HEADER
# Step 2: Add module separator
cat >> "$OUTPUT_FILE" << 'SEPARATOR'
# ============================================================================
# Library Modules (auto-merged from lib/ directory)
# ============================================================================
SEPARATOR
# Step 3: Concatenate modules in dependency order
# Remove shebangs and add module headers
for module in vars.sh logging.sh lock.sh config.sh worker.sh status.sh git.sh sanitize.sh deps.sh isolation.sh sync.sh worktree.sh cleanup.sh; do
if [ -f "$LIB_DIR/$module" ]; then
echo "" >> "$OUTPUT_FILE"
echo "# --- Module: $module ---" >> "$OUTPUT_FILE"
# Remove shebang, keep everything else
grep -v '^#!/bin/bash' "$LIB_DIR/$module" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
else
echo "Warning: $LIB_DIR/$module not found, skipping..." >&2
fi
done
# Step 4: Initialize variables (call init_clsecure_vars after modules are loaded)
cat >> "$OUTPUT_FILE" << 'INIT'
# Initialize all global variables
init_clsecure_vars
INIT
# Step 5: Add main script separator
cat >> "$OUTPUT_FILE" << 'SEPARATOR'
# ============================================================================
# Main Script (orchestration, CLI parsing, execution flow)
# ============================================================================
SEPARATOR
# Step 6: Extract main script logic
# Find the line where main script logic starts (after module sourcing)
# This is after the source statements and before actual execution
#
# Strategy: Extract everything from main script EXCEPT:
# - Shebang (already added)
# - set -euo pipefail (already added)
# - Module source statements (modules already concatenated)
# - Variable initialization (already called above)
# Extract main script logic from clsecure-src
# The source file contains: SCRIPT_DIR setup, source statements, init calls, and main logic
# We need everything EXCEPT the source statements (modules already concatenated)
if grep -q "^SCRIPT_DIR=" "$MAIN_SCRIPT_SRC"; then
# Extract from first non-module line onwards, but skip source statements and init calls
# Track heredoc state to avoid filtering export statements inside heredocs
awk "$(cat << 'AWKSCRIPT'
BEGIN {
in_heredoc = 0
heredoc_delim = ""
}
/^SCRIPT_DIR=/ { start=1 }
# Track heredoc start: look for << followed by a delimiter
start && /<</ {
# Extract delimiter: find the word after << (handles << EOF, <<- EOF, << 'EOF', etc.)
pos = index($0, "<<")
if (pos > 0) {
# Get substring after <<
rest = substr($0, pos + 2)
# Remove leading whitespace and optional dash
gsub(/^[ \t-]+/, "", rest)
# Extract first word (may be quoted)
first_char = substr(rest, 1, 1)
if (first_char == "\047" || first_char == "\042") {
quote = first_char
end = index(substr(rest, 2), quote)
if (end > 0) {
heredoc_delim = substr(rest, 2, end - 1)
}
} else {
# Unquoted: take first word
gsub(/[ \t].*$/, "", rest)
heredoc_delim = rest
}
if (heredoc_delim ~ /^[A-Za-z_][A-Za-z0-9_]*$/) {
in_heredoc = 1
}
}
}
# Track heredoc end: line contains only the delimiter (possibly with whitespace)
start && in_heredoc && heredoc_delim != "" {
trimmed = $0
gsub(/^[ \t]+/, "", trimmed)
gsub(/[ \t]+$/, "", trimmed)
if (trimmed == heredoc_delim) {
in_heredoc = 0
heredoc_delim = ""
}
}
# Skip filters only apply when NOT in heredoc
start && !in_heredoc && /^source / { next }
start && !in_heredoc && /^init_clsecure_vars/ { next }
# Filter out export statements EXCEPT runtime exports (ORIGINAL_BRANCH, CLAUDE_BIN)
# These are needed by subshells and functions, unlike vars.sh exports which are handled during init
start && !in_heredoc && /^export / && !/export (ORIGINAL_BRANCH|CLAUDE_BIN)/ { next }
# Note: Don't filter out trap statements - they're needed early in the script
start { print }
AWKSCRIPT
)" "$MAIN_SCRIPT_SRC" >> "$OUTPUT_FILE"
else
echo "Error: Could not find SCRIPT_DIR in $MAIN_SCRIPT_SRC" >&2
echo "Expected modular source file with SCRIPT_DIR setup" >&2
exit 1
fi
# Step 7: Make executable
chmod +x "$OUTPUT_FILE"
echo "✓ Built: $OUTPUT_FILE"
echo " Lines: $(wc -l < "$OUTPUT_FILE")"
echo ""
echo "To test:"
echo " bash -n $OUTPUT_FILE # Syntax check"
echo " ./$OUTPUT_FILE --help # Functional test"