@peterseibel/hug 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEVELOPMENT.md +5 -2
- package/README.md +42 -0
- package/bin/hug +40 -7
- package/lib/common.sh +35 -0
- package/package.json +1 -1
package/DEVELOPMENT.md
CHANGED
|
@@ -66,8 +66,11 @@ npm version patch # or minor / major
|
|
|
66
66
|
git push --follow-tags
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
`npm version` bumps `package.json`, commits, and creates a `v*` tag. Pushing
|
|
70
|
-
|
|
69
|
+
`npm version` bumps `package.json`, commits, and creates a `v*` tag. Pushing the
|
|
70
|
+
tag triggers the workflow in `.github/workflows/publish.yml`. (You can also use
|
|
71
|
+
`git config push.followTags true` to configure the repo to always push tags and
|
|
72
|
+
then `npm version patch && git push` will do the trick.)
|
|
73
|
+
|
|
71
74
|
|
|
72
75
|
## Dependencies
|
|
73
76
|
|
package/README.md
CHANGED
|
@@ -54,6 +54,47 @@ hug fork
|
|
|
54
54
|
|
|
55
55
|
Creates a new Apps Script project from the current local code. Useful with git branches — fork on a branch to get a separate Apps Script project you can develop against independently. If you're using `hug config` to manage resources like spreadsheet IDs, you'll probably want to update them after forking so the new project points at its own resources.
|
|
56
56
|
|
|
57
|
+
#### Forking a container-bound project
|
|
58
|
+
|
|
59
|
+
If your project is a container-bound script (created via Extensions > Apps Script inside a Google Sheet, Doc, etc.), `hug fork` will refuse by default since the forked standalone copy can't call `getActiveSpreadsheet()` and similar container APIs.
|
|
60
|
+
|
|
61
|
+
Use `--detach` to fork anyway and automatically save the original container's ID to `config.js`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
hug fork --detach
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This sets `CONTAINER_ID` in `config.js` to the original container's ID. You'll then need to update your code to open the container explicitly instead of relying on the bound context. For example:
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// Before (container-bound only)
|
|
71
|
+
const ss = SpreadsheetApp.getActiveSpreadsheet();
|
|
72
|
+
const sheet = SpreadsheetApp.getActiveSheet();
|
|
73
|
+
const range = SpreadsheetApp.getActiveRange();
|
|
74
|
+
|
|
75
|
+
// After (works in standalone fork)
|
|
76
|
+
const ss = SpreadsheetApp.openById(CONFIG.CONTAINER_ID);
|
|
77
|
+
const sheet = ss.getActiveSheet(); // or ss.getSheetByName("Sheet1")
|
|
78
|
+
const range = sheet.getActiveRange(); // or sheet.getRange(...)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Similarly for other container types:
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
// Google Doc
|
|
85
|
+
const doc = DocumentApp.openById(CONFIG.CONTAINER_ID);
|
|
86
|
+
|
|
87
|
+
// Google Form
|
|
88
|
+
const form = FormApp.openById(CONFIG.CONTAINER_ID);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
After updating the code, push it and optionally set up a fresh deployment:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
hug push
|
|
95
|
+
hug deploy "detach from container"
|
|
96
|
+
```
|
|
97
|
+
|
|
57
98
|
### Configure
|
|
58
99
|
|
|
59
100
|
```bash
|
|
@@ -116,5 +157,6 @@ git switch -c staging
|
|
|
116
157
|
hug fork # new Apps Script project, updates .clasp.json
|
|
117
158
|
hug config set SPREADSHEET_ID=1Bx.. # point at a staging spreadsheet
|
|
118
159
|
hug deploy # deploys to the staging project
|
|
160
|
+
git commit # Commit work in branch.
|
|
119
161
|
git switch main # .clasp.json and config.js switch back to production
|
|
120
162
|
```
|
package/bin/hug
CHANGED
|
@@ -22,7 +22,7 @@ Usage: hug <command> [options]
|
|
|
22
22
|
Project commands:
|
|
23
23
|
init [--template blank|webapp] [name] Create a new project from a template
|
|
24
24
|
init --scriptId <id> [name] Import an existing Apps Script project
|
|
25
|
-
fork
|
|
25
|
+
fork [--detach] Create a new Apps Script project from current code
|
|
26
26
|
|
|
27
27
|
Development commands:
|
|
28
28
|
push Push local files to Apps Script
|
|
@@ -98,6 +98,7 @@ cmd_init() {
|
|
|
98
98
|
# Import mode: clone an existing project
|
|
99
99
|
echo "Importing project $script_id..."
|
|
100
100
|
run_clasp "$clasp" clone "$script_id"
|
|
101
|
+
patch_parent_id
|
|
101
102
|
|
|
102
103
|
echo ""
|
|
103
104
|
echo "Project imported. Next steps:"
|
|
@@ -139,16 +140,23 @@ cmd_init() {
|
|
|
139
140
|
|
|
140
141
|
cmd_fork() {
|
|
141
142
|
local force=false
|
|
143
|
+
local detach=false
|
|
142
144
|
while [ $# -gt 0 ]; do
|
|
143
145
|
case "$1" in
|
|
144
146
|
-f|--force) force=true; shift ;;
|
|
147
|
+
--detach) detach=true; shift ;;
|
|
145
148
|
--help)
|
|
146
|
-
echo "Usage: hug fork [-f|--force]"
|
|
149
|
+
echo "Usage: hug fork [-f|--force] [--detach]"
|
|
147
150
|
echo ""
|
|
148
151
|
echo "Creates a new Apps Script project from the current local code."
|
|
149
152
|
echo "Replaces .clasp.json with a new project, then pushes code to it."
|
|
150
153
|
echo ""
|
|
151
|
-
echo "Refuses if the current project is container-bound (use -f to override
|
|
154
|
+
echo "Refuses if the current project is container-bound (use -f to override,"
|
|
155
|
+
echo "or --detach to fork and save the container ID to config)."
|
|
156
|
+
echo ""
|
|
157
|
+
echo " --detach Fork a container-bound project and set CONTAINER_ID in"
|
|
158
|
+
echo " config.js to the original container's ID, so code can"
|
|
159
|
+
echo " open it via SpreadsheetApp.openById() etc."
|
|
152
160
|
echo ""
|
|
153
161
|
echo "Useful with git branches: fork on a branch to get a separate"
|
|
154
162
|
echo "Apps Script project for each branch."
|
|
@@ -162,16 +170,21 @@ cmd_fork() {
|
|
|
162
170
|
return 1
|
|
163
171
|
fi
|
|
164
172
|
|
|
165
|
-
|
|
166
|
-
|
|
173
|
+
# Capture parentId before we replace .clasp.json
|
|
174
|
+
local parent_id=""
|
|
175
|
+
if grep -q '"parentId"' .clasp.json 2>/dev/null; then
|
|
167
176
|
parent_id=$(grep '"parentId"' .clasp.json | sed 's/.*"parentId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
if [ -n "$parent_id" ] && [ "$force" = false ] && [ "$detach" = false ]; then
|
|
168
180
|
echo "Error: this is a container-bound script. Forking will create a standalone" >&2
|
|
169
181
|
echo "project, but the code may depend on its container (e.g. by calling." >&2
|
|
170
182
|
echo "getActiveSpreadsheet())." >&2
|
|
171
183
|
echo "" >&2
|
|
172
184
|
echo "Container: https://drive.google.com/file/d/$parent_id" >&2
|
|
173
185
|
echo "" >&2
|
|
174
|
-
echo "Use 'hug fork --force' to fork anyway
|
|
186
|
+
echo "Use 'hug fork --force' to fork anyway, or '--detach' to fork and" >&2
|
|
187
|
+
echo "save the container ID to config.js as CONTAINER_ID." >&2
|
|
175
188
|
return 1
|
|
176
189
|
fi
|
|
177
190
|
|
|
@@ -183,10 +196,30 @@ cmd_fork() {
|
|
|
183
196
|
|
|
184
197
|
echo "Creating new Apps Script project '$title'..."
|
|
185
198
|
rm -f .clasp.json
|
|
199
|
+
# Preserve appsscript.json because clasp create overwrites it with server defaults
|
|
200
|
+
local saved_manifest=""
|
|
201
|
+
if [ -f appsscript.json ]; then
|
|
202
|
+
saved_manifest=$(cat appsscript.json)
|
|
203
|
+
fi
|
|
186
204
|
run_clasp "$clasp" create --type standalone --title "$title"
|
|
205
|
+
if [ -n "$saved_manifest" ]; then
|
|
206
|
+
echo "$saved_manifest" > appsscript.json
|
|
207
|
+
fi
|
|
187
208
|
|
|
188
209
|
echo "Pushing code to new project..."
|
|
189
|
-
run_clasp "$clasp" push
|
|
210
|
+
run_clasp "$clasp" push --force
|
|
211
|
+
|
|
212
|
+
# If detaching, save the original container ID to config
|
|
213
|
+
if [ "$detach" = true ] && [ -n "$parent_id" ]; then
|
|
214
|
+
local existing=""
|
|
215
|
+
if [ -f config.js ]; then
|
|
216
|
+
existing=$(_read_config)
|
|
217
|
+
fi
|
|
218
|
+
existing=$(echo "$existing" | grep -v "^CONTAINER_ID=" || true)
|
|
219
|
+
{ printf '%s\nCONTAINER_ID=%s\n' "$existing" "$parent_id" | grep -v '^$' || true; } | _write_config
|
|
220
|
+
echo "Set CONTAINER_ID=$parent_id in config.js."
|
|
221
|
+
echo "Push will include config.js. Use SpreadsheetApp.openById(CONFIG.CONTAINER_ID) etc."
|
|
222
|
+
fi
|
|
190
223
|
|
|
191
224
|
echo ""
|
|
192
225
|
echo "Fork complete. This directory now points to a new Apps Script project."
|
package/lib/common.sh
CHANGED
|
@@ -43,6 +43,41 @@ run_clasp() {
|
|
|
43
43
|
return $exit_code
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
# If the project is container-bound, patch parentId into .clasp.json
|
|
47
|
+
patch_parent_id() {
|
|
48
|
+
local script_id
|
|
49
|
+
script_id=$(grep '"scriptId"' .clasp.json | sed 's/.*"scriptId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
50
|
+
if [ -z "$script_id" ]; then
|
|
51
|
+
return
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
local token
|
|
55
|
+
token=$(sed -n 's/.*"access_token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' ~/.clasprc.json 2>/dev/null)
|
|
56
|
+
if [ -z "$token" ]; then
|
|
57
|
+
return
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
local response
|
|
61
|
+
response=$(curl -sf -H "Authorization: Bearer $token" \
|
|
62
|
+
"https://script.googleapis.com/v1/projects/$script_id" 2>/dev/null) || return 0
|
|
63
|
+
|
|
64
|
+
local parent_id
|
|
65
|
+
parent_id=$(echo "$response" | sed -n 's/.*"parentId"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
|
|
66
|
+
if [ -z "$parent_id" ]; then
|
|
67
|
+
return
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Already has parentId
|
|
71
|
+
if grep -q '"parentId"' .clasp.json 2>/dev/null; then
|
|
72
|
+
return
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Inject parentId into .clasp.json before the closing brace
|
|
76
|
+
local tmp
|
|
77
|
+
tmp=$(mktemp)
|
|
78
|
+
sed '$s/}$/,"parentId":"'"$parent_id"'"}/' .clasp.json > "$tmp" && mv "$tmp" .clasp.json
|
|
79
|
+
}
|
|
80
|
+
|
|
46
81
|
# Resolve the hug package root (where templates/ lives)
|
|
47
82
|
hug_root() {
|
|
48
83
|
local source="${BASH_SOURCE[0]}"
|