querysub 0.657.0 → 0.658.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.657.0",
3
+ "version": "0.658.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -80,12 +80,12 @@ function extractChangedLines(diff: string): string {
80
80
  const rowButtonStyle = css.pad2(12, 8).button.bord2(0, 0, 20).fontWeight("bold");
81
81
 
82
82
  export class CommitModal extends qreact.Component<{
83
- /** True for the querysub repo, false for the main service repo. */
84
- isQuerysub?: boolean;
83
+ /** True when the commit also publishes querysub, so the diff covers both repos and the labels say so. */
84
+ includeQuerysub?: boolean;
85
85
  /** The `git status --porcelain` lines, shown as a file list. */
86
86
  changes: string[];
87
- /** Performs the actual commit + push (and publish, for querysub). */
88
- onCommit: (message: string) => Promise<void>;
87
+ /** Performs the actual commit + push (and publish, for querysub). Calls setStep as it moves through its steps, which is shown on the commit button. */
88
+ onCommit: (message: string, setStep: (step: string) => void) => Promise<void>;
89
89
  }> {
90
90
  state = t.state({
91
91
  message: t.string,
@@ -96,6 +96,7 @@ export class CommitModal extends qreact.Component<{
96
96
  diffLoading: t.boolean(true),
97
97
  summarizing: t.boolean(false),
98
98
  committing: t.boolean(false),
99
+ step: t.string,
99
100
  error: t.string,
100
101
  lastCost: t.number,
101
102
  });
@@ -108,9 +109,13 @@ export class CommitModal extends qreact.Component<{
108
109
 
109
110
  private async loadDiff() {
110
111
  try {
111
- let isQuerysub = Querysub.localRead(() => this.props.isQuerysub);
112
+ let includeQuerysub = Querysub.localRead(() => this.props.includeQuerysub);
112
113
  let controller = MachineServiceController(SocketFunction.browserNodeId());
113
- let diff = await controller.getGitDiff.promise({ useQuerysub: isQuerysub });
114
+ let diffs = await Promise.all([
115
+ includeQuerysub && controller.getGitDiff.promise({ useQuerysub: true }) || "",
116
+ controller.getGitDiff.promise({ useQuerysub: false }),
117
+ ]);
118
+ let diff = diffs.filter(x => x).join("\n");
114
119
  console.log("Received commit diff, changed lines:\n" + extractChangedLines(diff));
115
120
  Querysub.localCommit(() => {
116
121
  this.state.diff = diff;
@@ -172,22 +177,28 @@ export class CommitModal extends qreact.Component<{
172
177
  }
173
178
  Querysub.localCommit(() => {
174
179
  this.state.committing = true;
180
+ this.state.step = "";
175
181
  this.state.error = "";
176
182
  });
177
183
  try {
178
- await this.props.onCommit(message);
184
+ await this.props.onCommit(message, step => {
185
+ Querysub.localCommit(() => {
186
+ this.state.step = step;
187
+ });
188
+ });
179
189
  closeAllModals();
180
190
  } catch (e: any) {
181
191
  Querysub.localCommit(() => {
182
192
  this.state.error = `Commit failed: ${e.stack ?? e}`;
183
193
  this.state.committing = false;
194
+ this.state.step = "";
184
195
  });
185
196
  }
186
197
  }
187
198
 
188
199
  render() {
189
200
  let { diff, diffLoading, summarizing, committing } = this.state;
190
- let commitLabel = this.props.isQuerysub ? "Publish & Commit & Push" : "Commit & Push";
201
+ let commitLabel = this.props.includeQuerysub && "Publish Querysub & Commit & Push" || "Commit & Push";
191
202
 
192
203
  let summarizeLabel: string;
193
204
  if (diffLoading) {
@@ -274,7 +285,7 @@ export class CommitModal extends qreact.Component<{
274
285
  disabled={committing}
275
286
  onClick={() => void this.doCommit()}
276
287
  >
277
- {committing ? `⏳ Running ${commitLabel}…` : `⬆️ ${commitLabel}`}
288
+ {committing && `⏳ ${this.state.step || `Running ${commitLabel}…`}` || `⬆️ ${commitLabel}`}
278
289
  </button>
279
290
  </div>
280
291
 
@@ -145,46 +145,45 @@ export class UpdateButtons extends qreact.Component<{
145
145
  });
146
146
  let outdatedRefs = unique(outdatedServices.map(service => service.parameters.gitRef));
147
147
 
148
+ let querysubChanges = gitInfo?.querysubUncommitted ?? [];
149
+ let serviceChanges = gitInfo?.uncommitted ?? [];
150
+ let allChanges = [
151
+ ...querysubChanges.map(change => `querysub: ${change}`),
152
+ ...serviceChanges,
153
+ ];
154
+ let includeQuerysub = !!querysubChanges.length;
155
+
148
156
  return <>
149
- {!!gitInfo?.querysubUncommitted.length && <button
157
+ {!!allChanges.length && gitInfo && <button
150
158
  className={buttonStyle.hsl(260, 60, 90)}
151
- title={gitInfo?.querysubUncommitted.join("\n")}
159
+ title={allChanges.join("\n")}
152
160
  onClick={() => {
153
161
  showFullscreenModal({
154
162
  content: <CommitModal
155
- isQuerysub
156
- changes={gitInfo?.querysubUncommitted ?? []}
157
- onCommit={async message => {
158
- await controller.commitPushAndPublishQuerysub.promise(message);
163
+ includeQuerysub={includeQuerysub}
164
+ changes={allChanges}
165
+ onCommit={async (message, setStep) => {
166
+ if (includeQuerysub) {
167
+ setStep("Step 1/2: Publishing querysub (version bump, npm publish, commit & push, package.json update)…");
168
+ await controller.commitPushAndPublishQuerysub.promise(message);
169
+ setStep("Step 2/2: Committing & pushing the service repo…");
170
+ } else {
171
+ setStep("Committing & pushing the service repo…");
172
+ }
173
+ await controller.commitPushService.promise(message);
159
174
  }}
160
175
  />
161
176
  });
162
177
  }}
163
178
  >
164
179
  <div>
165
- {bigEmoji("📚", -5)}
166
- Publish & Commit & Push Querysub & Update Package.json ({gitInfo?.querysubUncommitted.length} Files Changed)
180
+ {bigEmoji(includeQuerysub && "📚" || "⬆️", -5)}
181
+ {includeQuerysub && "Publish Querysub & " || ""}Commit & Push All ({includeQuerysub && `${querysubChanges.length} querysub + ` || ""}{serviceChanges.length} Files Changed)
167
182
  </div>
168
- <div className={css.hbox(5)}>
183
+ {includeQuerysub && <div className={css.hbox(5)}>
169
184
  <b>Current</b>
170
185
  <RenderGitRefInfo gitRef={gitInfo.querysubRef} isQuerysub />
171
- </div>
172
- </button>}
173
- {!!gitInfo?.uncommitted.length && <button
174
- className={buttonStyle.hsl(210, 40, 90)}
175
- title={gitInfo?.uncommitted.join("\n")}
176
- onClick={() => {
177
- showFullscreenModal({
178
- content: <CommitModal
179
- changes={gitInfo?.uncommitted ?? []}
180
- onCommit={async message => {
181
- await controller.commitPushService.promise(message);
182
- }}
183
- />
184
- });
185
- }}
186
- >
187
- {bigEmoji("⬆️")} <span>Commit & Push ({gitInfo?.uncommitted.length} Files Changed)</span>
186
+ </div>}
188
187
  </button>}
189
188
 
190
189
  {outdatedServices.length > 0 && gitInfo && <>
@@ -439,6 +439,17 @@ async function main() {
439
439
  console.log("✅ Build tools installed");
440
440
  }
441
441
 
442
+ // The daemon runs everything in tmux screens, so setup cannot get by without it
443
+ console.log("Ensuring tmux is installed...");
444
+ try {
445
+ await runPromise(`ssh ${sshRemote} "which tmux"`);
446
+ console.log("✅ Tmux already installed");
447
+ } catch {
448
+ console.log("Installing tmux...");
449
+ await runPromise(`ssh ${sshRemote} "sudo apt install -y tmux"`);
450
+ console.log("✅ Tmux installed");
451
+ }
452
+
442
453
  // 3. Ensure nodejs is installed on remote server
443
454
  console.log("Ensuring Node.js is installed...");
444
455
  try {
@@ -467,8 +478,9 @@ async function main() {
467
478
  await runPromise(`ssh ${sshRemote} "sudo timedatectl set-timezone America/New_York"`);
468
479
  console.log("✅ Timezone set to America/New_York");
469
480
 
481
+ // Via .tmux.conf rather than set-option, as set-option needs a running tmux server and there is none on a fresh machine
470
482
  console.log(`Setting tmux scrollback history to 100000...`);
471
- await runPromise(`ssh ${sshRemote} "tmux set-option -g history-limit 100000"`);
483
+ await runPromise(`ssh ${sshRemote} "grep -qxF 'set-option -g history-limit 100000' ~/.tmux.conf 2>/dev/null || echo 'set-option -g history-limit 100000' >> ~/.tmux.conf"`);
472
484
  console.log("✅ Tmux scrollback history set to 100000");
473
485
 
474
486
  // 5. Clone current repo into ~/machine-alwaysup with SSH key handling for private repos
@@ -16,6 +16,8 @@ export function shimConsoleLogs() {
16
16
  console.error(`Uncaught exception: ${String(error.stack || error)}`);
17
17
  });
18
18
  }
19
+ // Shared across log/warn/error/info, as writing one type can log another
20
+ let insideLogDisk = false;
19
21
  function hookConsoleFnc(fncName: "log" | "warn" | "error" | "info") {
20
22
  let console = globalThis.console;
21
23
  let originalFnc = console[fncName];
@@ -28,10 +30,17 @@ export function shimConsoleLogs() {
28
30
  if (
29
31
  args.length > 0
30
32
  && String(args[0]).trim().length > 0
33
+ // Writing a log can itself log (ex, building the log path generates the identity CA on a fresh machine, which logs), which would recurse forever. Those inner logs only go to the real console below, skipping the disk.
34
+ && !insideLogDisk
31
35
  ) {
32
- // Assign to a variable, so it isn't shimmed by injectFileLocationToConsole
33
- const logDiskThatIsntShimmed = diskLogger.logDisk;
34
- logDiskThatIsntShimmed(fncName, ...args);
36
+ insideLogDisk = true;
37
+ try {
38
+ // Assign to a variable, so it isn't shimmed by injectFileLocationToConsole
39
+ const logDiskThatIsntShimmed = diskLogger.logDisk;
40
+ logDiskThatIsntShimmed(fncName, ...args);
41
+ } finally {
42
+ insideLogDisk = false;
43
+ }
35
44
  }
36
45
 
37
46
  // Filter out objects added by injectFileLocationToConsole