Skip to content

Commit

Permalink
Add --once and --prefer
Browse files Browse the repository at this point in the history
  • Loading branch information
scott-rc committed Dec 13, 2023
1 parent 69dedaf commit bc65f33
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 16 deletions.
6 changes: 4 additions & 2 deletions spec/services/command/__snapshots__/command.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ ARGUMENTS
DIRECTORY The directory to sync files to (default: \\".\\")
FLAGS
-a, --app=<name> The Gadget application to sync files to
--force Sync regardless of local file state
-a, --app=<name> The Gadget application to sync files to
--prefer=<local|gadget> Conflict resolution strategy
--once Sync once and exit
--force Sync regardless of local file state
DESCRIPTION
Sync allows you to synchronize your Gadget application's source
Expand Down
17 changes: 13 additions & 4 deletions src/commands/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Command, Usage } from "../services/command/command.js";
import { config } from "../services/config/config.js";
import { Changes } from "../services/filesync/changes.js";
import { YarnNotFoundError } from "../services/filesync/error.js";
import { FileSync } from "../services/filesync/filesync.js";
import { ConflictPreferenceArg, FileSync } from "../services/filesync/filesync.js";
import { notify } from "../services/output/notify.js";
import { reportErrorAndExit } from "../services/output/report.js";
import { sprint } from "../services/output/sprint.js";
Expand All @@ -29,8 +29,10 @@ export const usage: Usage = () => sprint`
DIRECTORY The directory to sync files to (default: ".")
{bold FLAGS}
-a, --app=<name> The Gadget application to sync files to
--force Sync regardless of local file state
-a, --app=<name> The Gadget application to sync files to
--prefer=<local|gadget> Conflict resolution strategy
--once Sync once and exit
--force Sync regardless of local file state
{bold DESCRIPTION}
Sync allows you to synchronize your Gadget application's source
Expand Down Expand Up @@ -91,6 +93,8 @@ export const usage: Usage = () => sprint`
export const args = {
"--app": { type: AppArg, alias: "-a" },
"--force": Boolean,
"--once": Boolean,
"--prefer": ConflictPreferenceArg,
"--file-push-delay": { type: Number, default: ms("100ms") },
"--file-watch-debounce": { type: Number, default: ms("300ms") },
"--file-watch-poll-interval": { type: Number, default: ms("3s") },
Expand All @@ -109,7 +113,12 @@ export const command: Command<typeof args> = async (ctx) => {
force: ctx.args["--force"],
});

await filesync.sync();
await filesync.sync({ preference: ctx.args["--prefer"] });

if (ctx.args["--once"]) {
ctx.log.println("Done!");
return;
}

if (!which.sync("yarn", { nothrow: true })) {
throw new YarnNotFoundError();
Expand Down
39 changes: 29 additions & 10 deletions src/services/filesync/filesync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ export class FileSync {
* local changes or keep Gadget's changes.
* - This function will not return until the filesystem is in sync.
*/
async sync({ attempt = 0 }: { attempt?: number } = {}): Promise<void> {
async sync({ attempt = 0, preference }: { attempt?: number; preference?: ConflictPreference } = {}): Promise<void> {
if (attempt > 10) {
throw new TooManySyncAttemptsError(attempt);
}
Expand All @@ -355,15 +355,18 @@ export class FileSync {
const conflicts = getConflicts({ localChanges, gadgetChanges });
if (conflicts.size > 0) {
this.log.debug("conflicts detected", { conflicts });
printConflicts({
message: sprint`{bold You have conflicting changes with Gadget}`,
conflicts,
});

const preference = await select({
message: "How would you like to resolve these conflicts?",
choices: Object.values(ConflictPreference),
});
if (!preference) {
printConflicts({
message: sprint`{bold You have conflicting changes with Gadget}`,
conflicts,
});

preference = await select({
message: "How would you like to resolve these conflicts?",
choices: Object.values(ConflictPreference),
});
}

switch (preference) {
case ConflictPreference.CANCEL: {
Expand Down Expand Up @@ -392,7 +395,7 @@ export class FileSync {
}

// recursively call this function until we're in sync
return this.sync({ attempt: ++attempt });
return this.sync({ attempt: ++attempt, preference });
}

private async _getChangesFromGadget({
Expand Down Expand Up @@ -679,3 +682,19 @@ export const ConflictPreference = Object.freeze({
LOCAL: "Keep my conflicting changes",
GADGET: "Keep Gadget's conflicting changes",
});

export type ConflictPreference = (typeof ConflictPreference)[keyof typeof ConflictPreference];

export const ConflictPreferenceArg = (value: string, name: string): ConflictPreference => {
if (["local", "gadget"].includes(value)) {
return ConflictPreference[value.toUpperCase() as keyof typeof ConflictPreference];
}

throw new ArgError(sprint`
${name} must be {bold local} or {bold gadget}
{bold EXAMPLES:}
${name} local
${name} gadget
`);
};

0 comments on commit bc65f33

Please sign in to comment.