-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.sh
More file actions
executable file
·264 lines (221 loc) · 9.05 KB
/
build.sh
File metadata and controls
executable file
·264 lines (221 loc) · 9.05 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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#!/bin/bash
# ─────────────────────────────────────────────────────────────
# rmSync — Build & Run
#
# Usage:
# chmod +x build.sh
# ./build.sh # build macOS + run
# ./build.sh --build-only # build macOS, don't run
# ./build.sh --run-only # just run existing build
# ./build.sh --dist # macOS .dmg for sharing
# ./build.sh --win # build Windows portable .exe
# ./build.sh --all # build macOS + Windows
# ./build.sh --clean # remove all build artifacts
# ./build.sh --help # show this help
# ─────────────────────────────────────────────────────────────
set -e
# ─── Colors ───
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
DIM='\033[0;90m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${BLUE}▸${NC} $1"; }
ok() { echo -e "${GREEN}✓${NC} $1"; }
warn() { echo -e "${YELLOW}⚠${NC} $1"; }
fail() { echo -e "${RED}✗${NC} $1"; }
step() { echo -e "\n${BOLD}── $1 ──${NC}"; }
# ─── Config ───
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC_DIR="$SCRIPT_DIR/src"
DIST_DIR="$SCRIPT_DIR/dist"
APP_NAME="rmSync"
cd "$SRC_DIR"
BUILD_ONLY=false
RUN_ONLY=false
DIST=false
BUILD_WIN=false
BUILD_ALL=false
CLEAN=false
for arg in "$@"; do
case $arg in
--build-only) BUILD_ONLY=true ;;
--run-only) RUN_ONLY=true ;;
--dist) DIST=true ;;
--win) BUILD_WIN=true; BUILD_ONLY=true ;;
--all) BUILD_ALL=true; BUILD_ONLY=true ;;
--clean) CLEAN=true ;;
--help|-h)
echo "Usage: ./build.sh [options]"
echo ""
echo " (default) Check deps → build macOS → run"
echo " --build-only Build macOS app, don't launch"
echo " --run-only Launch existing build (skip build)"
echo " --dist Build macOS .dmg for sharing"
echo " --win Build Windows portable .exe (cross-compile)"
echo " --all Build both macOS + Windows"
echo " --clean Remove all build artifacts"
echo ""
echo "Output:"
echo " macOS → dist/*.dmg or dist/mac-arm64/${APP_NAME}.app"
echo " Windows→ dist/*.exe"
exit 0
;;
esac
done
# ═══════════════════════════════════════════════════════════
# CLEAN
# ═══════════════════════════════════════════════════════════
if [ "$CLEAN" = true ]; then
step "Cleaning"
[ -d "$DIST_DIR" ] && rm -rf "$DIST_DIR" && ok "Removed dist/"
[ -d dist ] && rm -rf dist && ok "Removed src/dist/"
[ -d node_modules ] && rm -rf node_modules && ok "Removed node_modules/"
[ -f package-lock.json ] && rm -f package-lock.json && ok "Removed package-lock.json"
echo ""
ok "All clean."
exit 0
fi
# ═══════════════════════════════════════════════════════════
# STEP 1: Check Prerequisites
# ═══════════════════════════════════════════════════════════
if [ "$RUN_ONLY" = false ]; then
step "Checking prerequisites"
# Node.js
if command -v node &>/dev/null; then
NODE_MAJOR=$(node --version | sed 's/v//' | cut -d. -f1)
if [ "$NODE_MAJOR" -ge 18 ]; then
ok "Node.js $(node --version)"
else
fail "Node.js $(node --version) is too old (need >= 18)"
exit 1
fi
else
fail "Node.js not found. Install from https://nodejs.org"
exit 1
fi
# npm
if command -v npm &>/dev/null; then
ok "npm $(npm --version)"
else
fail "npm not found"
exit 1
fi
# Wine (only for Windows cross-compile)
if [ "$BUILD_WIN" = true ] || [ "$BUILD_ALL" = true ]; then
if command -v wine64 &>/dev/null; then
ok "Wine found (for Windows cross-compile)"
else
warn "Wine not found — Windows build may still work without it"
info "Install if needed: brew install --cask wine-stable"
fi
fi
# ═══════════════════════════════════════════════════════════
# STEP 2: Install Dependencies
# ═══════════════════════════════════════════════════════════
step "Installing dependencies"
if [ -d node_modules ] && [ -f node_modules/.package-lock.json ]; then
if [ package.json -nt node_modules/.package-lock.json ]; then
info "package.json changed — reinstalling…"
npm install
else
ok "node_modules up to date"
fi
else
info "Running npm install…"
npm install
fi
ok "Dependencies ready"
# ═══════════════════════════════════════════════════════════
# STEP 3: Build
# ═══════════════════════════════════════════════════════════
step "Building"
# electron-builder outputs to src/dist by default (configured in package.json)
[ -d dist ] && rm -rf dist
if [ "$BUILD_ALL" = true ]; then
info "Building macOS + Windows…"
npx electron-builder --mac --win
elif [ "$BUILD_WIN" = true ]; then
info "Building Windows portable .exe…"
npx electron-builder --win
elif [ "$DIST" = true ]; then
info "Building macOS .dmg…"
npx electron-builder --mac dmg
else
info "Building macOS app…"
npx electron-builder --mac dir
fi
# Move build output to project root dist/
if [ -d dist ] && [ "$SRC_DIR/dist" != "$DIST_DIR" ]; then
rm -rf "$DIST_DIR"
mv dist "$DIST_DIR"
fi
# Clean intermediate artifacts
rm -f "$DIST_DIR/builder-effective-config.yaml" 2>/dev/null
rm -f "$DIST_DIR/builder-debug.yml" 2>/dev/null
ok "Build complete → dist/"
# ═══════════════════════════════════════════════════════════
# STEP 4: Show what was built
# ═══════════════════════════════════════════════════════════
step "Build output"
echo ""
find "$DIST_DIR" -maxdepth 1 -name "*.dmg" 2>/dev/null | sort | while read f; do
SIZE=$(du -h "$f" | awk '{print $1}')
echo -e " ${GREEN}●${NC} macOS installer ${GREEN}$f${NC} ($SIZE)"
done
find "$DIST_DIR" -maxdepth 1 -name "*.exe" 2>/dev/null | sort | while read f; do
SIZE=$(du -h "$f" | awk '{print $1}')
echo -e " ${GREEN}●${NC} Windows portable ${GREEN}$f${NC} ($SIZE)"
done
find "$DIST_DIR" -maxdepth 2 -name "*.app" -type d 2>/dev/null | sort | while read f; do
SIZE=$(du -sh "$f" | awk '{print $1}')
echo -e " ${GREEN}●${NC} macOS app ${GREEN}$f${NC} ($SIZE)"
done
echo ""
fi # end of !RUN_ONLY
# ═══════════════════════════════════════════════════════════
# STEP 5: Run
# ═══════════════════════════════════════════════════════════
if [ "$BUILD_ONLY" = true ]; then
step "Done"
ok "Build complete. Run with: ./build.sh --run-only"
exit 0
fi
step "Launching ${APP_NAME}"
# Kill any running instance so macOS launches the freshly-built version
if pgrep -f "${APP_NAME}.app" > /dev/null 2>&1; then
info "Stopping running ${APP_NAME}…"
pkill -f "${APP_NAME}.app" 2>/dev/null || true
sleep 0.5
ok "Stopped previous instance"
fi
APP_PATH=""
for candidate in \
"$DIST_DIR/mac-arm64/${APP_NAME}.app" \
"$DIST_DIR/mac/${APP_NAME}.app" \
"$DIST_DIR/mac-x64/${APP_NAME}.app"; do
if [ -d "$candidate" ]; then
APP_PATH="$candidate"
break
fi
done
if [ -z "$APP_PATH" ]; then
APP_PATH=$(find "$DIST_DIR" -name "${APP_NAME}.app" -type d 2>/dev/null | head -1)
fi
if [ -n "$APP_PATH" ] && [ -d "$APP_PATH" ]; then
ok "Found: $APP_PATH"
open "$APP_PATH"
else
warn "No built .app found — running with Electron directly…"
npx electron .
fi
echo ""
ok "Done."
echo ""
echo -e "${YELLOW}${BOLD}Note:${NC} If you get ${RED}EHOSTUNREACH${NC} when syncing, go to:"
echo -e " ${BOLD}System Settings → Privacy & Security → Local Network${NC}"
echo -e " and toggle ${BOLD}${APP_NAME}${NC} off then on again."
echo -e " This happens because macOS ties the Local Network permission to the"
echo -e " app binary, which changes on every rebuild."