kirby-deploy 0.3.3 → 0.4.1

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/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import { defineCommand as defineCommand4 } from "citty";
8
8
  import { consola as consola9 } from "consola";
9
9
  import { colors as colors6 } from "consola/utils";
10
10
  import { readFileSync } from "fs";
11
- import { join as join6, relative } from "path/posix";
11
+ import { join as join7, relative } from "path/posix";
12
12
  import { cwd as cwd2 } from "process";
13
13
 
14
14
  // src/config.ts
@@ -57,6 +57,7 @@ var ConfigSchema = object({
57
57
  callWebhooks: optional(boolean()),
58
58
  dryRun: optional(boolean()),
59
59
  verbose: optional(boolean()),
60
+ force: optional(boolean()),
60
61
  parallel: optional(number()),
61
62
  exclude: optional(array(string())),
62
63
  excludeGlob: optional(array(string())),
@@ -126,6 +127,7 @@ ${info}`);
126
127
  remoteDir: "./",
127
128
  dryRun: true,
128
129
  verbose: false,
130
+ force: false,
129
131
  parallel: 10,
130
132
  checkComposerLock: true,
131
133
  callWebhooks: true,
@@ -148,15 +150,15 @@ ${info}`);
148
150
  // src/lftp/cat.ts
149
151
  import { spawnSync } from "child_process";
150
152
  import { consola as consola2 } from "consola";
153
+ import { join } from "path";
151
154
  import { platform } from "os";
152
- var cat = (file, { host, user, password, lftpSettings }) => {
155
+ var cat = (file, { host, user, password, remoteDir, lftpSettings }) => {
153
156
  const commands = [
154
157
  ...Object.entries(lftpSettings).map(
155
158
  ([key, value]) => `set ${key} ${value}`
156
159
  ),
157
- `open ${host}`,
158
- `user ${user} ${password}`,
159
- `cat ${file}`,
160
+ `open -u ${user},${password} ${host}`,
161
+ `cat ${join(remoteDir, file)}`,
160
162
  "bye"
161
163
  ];
162
164
  const isWindows = platform() === "win32";
@@ -164,7 +166,8 @@ var cat = (file, { host, user, password, lftpSettings }) => {
164
166
  encoding: "utf-8"
165
167
  }) : spawnSync("lftp", ["-c", commands.join("; ")], { encoding: "utf-8" });
166
168
  if (child.stderr) {
167
- if (child.stderr.includes("550")) return void 0;
169
+ if (child.stderr.includes("550") || child.stderr.includes("No such file"))
170
+ return void 0;
168
171
  consola2.error(child.stderr);
169
172
  return void 0;
170
173
  }
@@ -173,7 +176,7 @@ var cat = (file, { host, user, password, lftpSettings }) => {
173
176
 
174
177
  // src/sync.ts
175
178
  import { consola as consola5 } from "consola";
176
- import { join as join2 } from "path/posix";
179
+ import { join as join3 } from "path/posix";
177
180
 
178
181
  // src/lftp/mirror.ts
179
182
  import { consola as consola3 } from "consola";
@@ -185,9 +188,7 @@ var mirror = (source, destination, flags, { lftpSettings, host, user, password,
185
188
  ...Object.entries(lftpSettings).map(
186
189
  ([key, value]) => `set ${key} ${value}`
187
190
  ),
188
- `open ${host}`,
189
- `user ${user} ${password}`,
190
- // mask credentials
191
+ `open -u ${user},${password} ${host}`,
191
192
  `mirror ${flags.join(" ")} ${source} ${destination}`,
192
193
  "bye"
193
194
  ];
@@ -203,6 +204,9 @@ var mirror = (source, destination, flags, { lftpSettings, host, user, password,
203
204
  if (match = line.match(/Transferring file `(.*)'/)) {
204
205
  hasChanges = true;
205
206
  consola3.log(colors.blue(`\u2192 ${match[1]}`));
207
+ } else if (match = line.match(/Making directory `(.*)'/)) {
208
+ hasChanges = true;
209
+ consola3.log(colors.blue(`\u2192 ${match[1]}`));
206
210
  } else if (match = line.match(/Removing old (?:file|directory) `(.*)'/)) {
207
211
  hasChanges = true;
208
212
  consola3.log(colors.red(`\u2A2F ${match[1]}`));
@@ -240,11 +244,11 @@ import { consola as consola4 } from "consola";
240
244
  import { colors as colors2 } from "consola/utils";
241
245
  import { spawnSync as spawnSync2 } from "child_process";
242
246
  import { existsSync } from "fs";
243
- import { join } from "path";
247
+ import { join as join2 } from "path";
244
248
  import { cwd, stdin as input, stdout as output } from "process";
245
249
  import * as readline from "readline";
246
250
  var upperFirst = (string2) => string2.charAt(0).toUpperCase() + string2.slice(1);
247
- var isGit = () => existsSync(join(cwd(), ".git"));
251
+ var isGit = () => existsSync(join2(cwd(), ".git"));
248
252
  var getBranch = () => {
249
253
  if (!isGit()) return;
250
254
  const { stderr, stdout } = spawnSync2("git", ["branch", "--show-current"], {
@@ -286,7 +290,7 @@ var sync = async (source, mode, config) => {
286
290
  const targetName = mode === "push" ? "remote" : "local";
287
291
  const webhookBase = `${config.url}/plugin-kirby-deploy`;
288
292
  const shouldCallWebhooks = mode === "push" && config.callWebhooks;
289
- const destination = source === "./" ? config.remoteDir : join2(config.remoteDir, source);
293
+ const destination = source === "./" ? config.remoteDir : join3(config.remoteDir, source);
290
294
  if (shouldCallWebhooks && !config.token) {
291
295
  consola5.error("token needed to call webhooks");
292
296
  return false;
@@ -297,11 +301,11 @@ var sync = async (source, mode, config) => {
297
301
  }
298
302
  const flags = [
299
303
  "--continue",
300
- "--only-newer",
301
304
  "--overwrite",
302
- "--use-cache",
303
305
  "--delete",
304
306
  "--verbose",
307
+ !config.force && "--use-cache",
308
+ config.force && "--transfer-all",
305
309
  reverse && "--reverse",
306
310
  ...config.exclude.map((path) => `--exclude ${path}`),
307
311
  ...config.excludeGlob.map((path) => `--exclude-glob ${path}`),
@@ -365,8 +369,8 @@ var sync = async (source, mode, config) => {
365
369
  import { defineCommand } from "citty";
366
370
  import { consola as consola6 } from "consola";
367
371
  import { colors as colors3 } from "consola/utils";
368
- import { join as join3 } from "path/posix";
369
- var syncAccounts = async (mode) => {
372
+ import { join as join4 } from "path/posix";
373
+ var syncAccounts = async (mode, force = false) => {
370
374
  const config = await loadConfig();
371
375
  if (!config) return;
372
376
  const { accounts } = config.folderStructure;
@@ -376,7 +380,7 @@ var syncAccounts = async (mode) => {
376
380
  `${source}${branch ? colors3.cyan(` (${branch})`) : ""}`
377
381
  );
378
382
  const displayDestination = colors3.magenta(
379
- join3(config.host, config.remoteDir, source)
383
+ join4(config.host, config.remoteDir, source)
380
384
  );
381
385
  const direction = mode === "pull" ? "from" : "to";
382
386
  consola6.log(
@@ -391,18 +395,30 @@ var syncAccounts = async (mode) => {
391
395
  excludeGlob: [".*", ".*/"],
392
396
  include: [".htpasswd"],
393
397
  // Make sure account passwords are synced.
394
- includeGlob: []
398
+ includeGlob: [],
399
+ force
395
400
  });
396
401
  };
397
- var accountsPush = defineCommand({ run: () => syncAccounts("push") });
398
- var accountsPull = defineCommand({ run: () => syncAccounts("pull") });
402
+ var forceArg = {
403
+ type: "boolean",
404
+ description: "Transfer all files unconditionally, ignoring timestamps and cache",
405
+ default: false
406
+ };
407
+ var accountsPush = defineCommand({
408
+ args: { force: forceArg },
409
+ run: ({ args }) => syncAccounts("push", args.force)
410
+ });
411
+ var accountsPull = defineCommand({
412
+ args: { force: forceArg },
413
+ run: ({ args }) => syncAccounts("pull", args.force)
414
+ });
399
415
 
400
416
  // src/commands/content.ts
401
417
  import { defineCommand as defineCommand2 } from "citty";
402
418
  import { consola as consola7 } from "consola";
403
419
  import { colors as colors4 } from "consola/utils";
404
- import { join as join4 } from "path/posix";
405
- var syncContent = async (mode) => {
420
+ import { join as join5 } from "path/posix";
421
+ var syncContent = async (mode, force = false) => {
406
422
  const config = await loadConfig();
407
423
  if (!config) return;
408
424
  const { content } = config.folderStructure;
@@ -412,7 +428,7 @@ var syncContent = async (mode) => {
412
428
  `${source}${branch ? colors4.cyan(` (${branch})`) : ""}`
413
429
  );
414
430
  const displayDestination = colors4.magenta(
415
- join4(config.host, config.remoteDir, source)
431
+ join5(config.host, config.remoteDir, source)
416
432
  );
417
433
  const direction = mode === "pull" ? "from" : "to";
418
434
  consola7.log(
@@ -426,18 +442,30 @@ var syncContent = async (mode) => {
426
442
  exclude: [],
427
443
  excludeGlob: [".*", ".*/"],
428
444
  include: [],
429
- includeGlob: []
445
+ includeGlob: [],
446
+ force
430
447
  });
431
448
  };
432
- var contentPush = defineCommand2({ run: () => syncContent("push") });
433
- var contentPull = defineCommand2({ run: () => syncContent("pull") });
449
+ var forceArg2 = {
450
+ type: "boolean",
451
+ description: "Transfer all files unconditionally, ignoring timestamps and cache",
452
+ default: false
453
+ };
454
+ var contentPush = defineCommand2({
455
+ args: { force: forceArg2 },
456
+ run: ({ args }) => syncContent("push", args.force)
457
+ });
458
+ var contentPull = defineCommand2({
459
+ args: { force: forceArg2 },
460
+ run: ({ args }) => syncContent("pull", args.force)
461
+ });
434
462
 
435
463
  // src/commands/languages.ts
436
464
  import { defineCommand as defineCommand3 } from "citty";
437
465
  import { consola as consola8 } from "consola";
438
466
  import { colors as colors5 } from "consola/utils";
439
- import { join as join5 } from "path/posix";
440
- var syncLanguages = async (mode) => {
467
+ import { join as join6 } from "path/posix";
468
+ var syncLanguages = async (mode, force = false) => {
441
469
  const config = await loadConfig();
442
470
  if (!config) return;
443
471
  const { site } = config.folderStructure;
@@ -447,7 +475,7 @@ var syncLanguages = async (mode) => {
447
475
  `${source}${branch ? colors5.cyan(` (${branch})`) : ""}`
448
476
  );
449
477
  const displayDestination = colors5.magenta(
450
- join5(config.host, config.remoteDir, source)
478
+ join6(config.host, config.remoteDir, source)
451
479
  );
452
480
  const direction = mode === "pull" ? "from" : "to";
453
481
  consola8.log(
@@ -461,15 +489,34 @@ var syncLanguages = async (mode) => {
461
489
  exclude: [],
462
490
  excludeGlob: [".*", ".*/"],
463
491
  include: [],
464
- includeGlob: []
492
+ includeGlob: [],
493
+ force
465
494
  });
466
495
  };
467
- var languagesPush = defineCommand3({ run: () => syncLanguages("push") });
468
- var languagesPull = defineCommand3({ run: () => syncLanguages("pull") });
496
+ var forceArg3 = {
497
+ type: "boolean",
498
+ description: "Transfer all files unconditionally, ignoring timestamps and cache",
499
+ default: false
500
+ };
501
+ var languagesPush = defineCommand3({
502
+ args: { force: forceArg3 },
503
+ run: ({ args }) => syncLanguages("push", args.force)
504
+ });
505
+ var languagesPull = defineCommand3({
506
+ args: { force: forceArg3 },
507
+ run: ({ args }) => syncLanguages("pull", args.force)
508
+ });
469
509
 
470
510
  // src/commands/main.ts
471
511
  var main = defineCommand4({
472
- run: async ({ rawArgs, cmd }) => {
512
+ args: {
513
+ force: {
514
+ type: "boolean",
515
+ description: "Transfer all files unconditionally, ignoring timestamps and cache",
516
+ default: false
517
+ }
518
+ },
519
+ run: async ({ args, rawArgs, cmd }) => {
473
520
  const [firstArg] = rawArgs;
474
521
  const subCommands = Object.keys(cmd.subCommands ?? {});
475
522
  const isSubCommand = subCommands.includes(firstArg);
@@ -480,13 +527,13 @@ var main = defineCommand4({
480
527
  const exclude = [
481
528
  ...config.exclude,
482
529
  "^node_modules/",
483
- `^${relative(cwd2(), folderStructure.content)}`,
484
- `^${relative(cwd2(), folderStructure.media)}`,
485
- `^${relative(cwd2(), folderStructure.accounts)}`,
486
- `^${relative(cwd2(), folderStructure.sessions)}`,
487
- `^${relative(cwd2(), folderStructure.cache)}`,
488
- `^${relative(cwd2(), folderStructure.logs)}`,
489
- `^${relative(cwd2(), join6(folderStructure.site, "languages"))}`
530
+ `^${relative(cwd2(), folderStructure.content)}/.`,
531
+ `^${relative(cwd2(), folderStructure.media)}/.`,
532
+ `^${relative(cwd2(), folderStructure.accounts)}/.`,
533
+ `^${relative(cwd2(), folderStructure.sessions)}/.`,
534
+ `^${relative(cwd2(), folderStructure.cache)}/.`,
535
+ `^${relative(cwd2(), folderStructure.logs)}/.`,
536
+ `^${relative(cwd2(), join7(folderStructure.site, "languages"))}/.`
490
537
  ];
491
538
  const excludeGlob = [...config.excludeGlob, ".*", ".*/"];
492
539
  const include = config.include;
@@ -494,7 +541,7 @@ var main = defineCommand4({
494
541
  const branch = getBranch();
495
542
  const displaySource = branch ? colors6.cyan(` ${branch} `) : " ";
496
543
  const displayDestination = colors6.magenta(
497
- join6(config.host, config.remoteDir)
544
+ join7(config.host, config.remoteDir)
498
545
  );
499
546
  consola9.log(`\u{1F680} Deploy${displaySource}to ${displayDestination}
500
547
  `);
@@ -514,7 +561,8 @@ var main = defineCommand4({
514
561
  exclude,
515
562
  excludeGlob,
516
563
  include,
517
- includeGlob
564
+ includeGlob,
565
+ force: args.force
518
566
  });
519
567
  },
520
568
  subCommands: {
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ declare const ConfigSchema: valibot.ObjectSchema<{
21
21
  readonly callWebhooks: valibot.OptionalSchema<valibot.BooleanSchema<undefined>, undefined>;
22
22
  readonly dryRun: valibot.OptionalSchema<valibot.BooleanSchema<undefined>, undefined>;
23
23
  readonly verbose: valibot.OptionalSchema<valibot.BooleanSchema<undefined>, undefined>;
24
+ readonly force: valibot.OptionalSchema<valibot.BooleanSchema<undefined>, undefined>;
24
25
  readonly parallel: valibot.OptionalSchema<valibot.NumberSchema<undefined>, undefined>;
25
26
  readonly exclude: valibot.OptionalSchema<valibot.ArraySchema<valibot.StringSchema<undefined>, undefined>, undefined>;
26
27
  readonly excludeGlob: valibot.OptionalSchema<valibot.ArraySchema<valibot.StringSchema<undefined>, undefined>, undefined>;
@@ -51,6 +52,7 @@ declare const defineConfig: (config: Config) => {
51
52
  callWebhooks?: boolean | undefined;
52
53
  dryRun?: boolean | undefined;
53
54
  verbose?: boolean | undefined;
55
+ force?: boolean | undefined;
54
56
  parallel?: number | undefined;
55
57
  exclude?: string[] | undefined;
56
58
  excludeGlob?: string[] | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kirby-deploy",
3
- "version": "0.3.3",
3
+ "version": "0.4.1",
4
4
  "main": "./dist/index.js",
5
5
  "type": "module",
6
6
  "bin": {
@@ -6,7 +6,7 @@ import { loadConfig } from '../config'
6
6
  import { sync } from '../sync'
7
7
  import { getBranch, upperFirst } from '../utils'
8
8
 
9
- const syncAccounts = async (mode: 'pull' | 'push') => {
9
+ const syncAccounts = async (mode: 'pull' | 'push', force = false) => {
10
10
  const config = await loadConfig()
11
11
  if (!config) return
12
12
 
@@ -33,8 +33,22 @@ const syncAccounts = async (mode: 'pull' | 'push') => {
33
33
  excludeGlob: ['.*', '.*/'],
34
34
  include: ['.htpasswd'], // Make sure account passwords are synced.
35
35
  includeGlob: [],
36
+ force,
36
37
  })
37
38
  }
38
39
 
39
- export const accountsPush = defineCommand({ run: () => syncAccounts('push') })
40
- export const accountsPull = defineCommand({ run: () => syncAccounts('pull') })
40
+ const forceArg = {
41
+ type: 'boolean',
42
+ description:
43
+ 'Transfer all files unconditionally, ignoring timestamps and cache',
44
+ default: false,
45
+ } as const
46
+
47
+ export const accountsPush = defineCommand({
48
+ args: { force: forceArg },
49
+ run: ({ args }) => syncAccounts('push', args.force),
50
+ })
51
+ export const accountsPull = defineCommand({
52
+ args: { force: forceArg },
53
+ run: ({ args }) => syncAccounts('pull', args.force),
54
+ })
@@ -6,7 +6,7 @@ import { loadConfig } from '../config'
6
6
  import { sync } from '../sync'
7
7
  import { getBranch, upperFirst } from '../utils'
8
8
 
9
- const syncContent = async (mode: 'pull' | 'push') => {
9
+ const syncContent = async (mode: 'pull' | 'push', force = false) => {
10
10
  const config = await loadConfig()
11
11
  if (!config) return
12
12
 
@@ -33,8 +33,22 @@ const syncContent = async (mode: 'pull' | 'push') => {
33
33
  excludeGlob: ['.*', '.*/'],
34
34
  include: [],
35
35
  includeGlob: [],
36
+ force,
36
37
  })
37
38
  }
38
39
 
39
- export const contentPush = defineCommand({ run: () => syncContent('push') })
40
- export const contentPull = defineCommand({ run: () => syncContent('pull') })
40
+ const forceArg = {
41
+ type: 'boolean',
42
+ description:
43
+ 'Transfer all files unconditionally, ignoring timestamps and cache',
44
+ default: false,
45
+ } as const
46
+
47
+ export const contentPush = defineCommand({
48
+ args: { force: forceArg },
49
+ run: ({ args }) => syncContent('push', args.force),
50
+ })
51
+ export const contentPull = defineCommand({
52
+ args: { force: forceArg },
53
+ run: ({ args }) => syncContent('pull', args.force),
54
+ })
@@ -6,7 +6,7 @@ import { loadConfig } from '../config'
6
6
  import { sync } from '../sync'
7
7
  import { getBranch, upperFirst } from '../utils'
8
8
 
9
- const syncLanguages = async (mode: 'pull' | 'push') => {
9
+ const syncLanguages = async (mode: 'pull' | 'push', force = false) => {
10
10
  const config = await loadConfig()
11
11
  if (!config) return
12
12
 
@@ -33,8 +33,22 @@ const syncLanguages = async (mode: 'pull' | 'push') => {
33
33
  excludeGlob: ['.*', '.*/'],
34
34
  include: [],
35
35
  includeGlob: [],
36
+ force,
36
37
  })
37
38
  }
38
39
 
39
- export const languagesPush = defineCommand({ run: () => syncLanguages('push') })
40
- export const languagesPull = defineCommand({ run: () => syncLanguages('pull') })
40
+ const forceArg = {
41
+ type: 'boolean',
42
+ description:
43
+ 'Transfer all files unconditionally, ignoring timestamps and cache',
44
+ default: false,
45
+ } as const
46
+
47
+ export const languagesPush = defineCommand({
48
+ args: { force: forceArg },
49
+ run: ({ args }) => syncLanguages('push', args.force),
50
+ })
51
+ export const languagesPull = defineCommand({
52
+ args: { force: forceArg },
53
+ run: ({ args }) => syncLanguages('pull', args.force),
54
+ })
@@ -13,7 +13,15 @@ import { contentPull, contentPush } from './content'
13
13
  import { languagesPull, languagesPush } from './languages'
14
14
 
15
15
  export const main = defineCommand({
16
- run: async ({ rawArgs, cmd }) => {
16
+ args: {
17
+ force: {
18
+ type: 'boolean',
19
+ description:
20
+ 'Transfer all files unconditionally, ignoring timestamps and cache',
21
+ default: false,
22
+ },
23
+ },
24
+ run: async ({ args, rawArgs, cmd }) => {
17
25
  // Todo: find a cleaner way to prevent the main command from running when
18
26
  // when a sub command is run.
19
27
  const [firstArg] = rawArgs
@@ -28,13 +36,13 @@ export const main = defineCommand({
28
36
  const exclude = [
29
37
  ...config.exclude,
30
38
  '^node_modules/',
31
- `^${relative(cwd(), folderStructure.content)}`,
32
- `^${relative(cwd(), folderStructure.media)}`,
33
- `^${relative(cwd(), folderStructure.accounts)}`,
34
- `^${relative(cwd(), folderStructure.sessions)}`,
35
- `^${relative(cwd(), folderStructure.cache)}`,
36
- `^${relative(cwd(), folderStructure.logs)}`,
37
- `^${relative(cwd(), join(folderStructure.site, 'languages'))}`,
39
+ `^${relative(cwd(), folderStructure.content)}/.`,
40
+ `^${relative(cwd(), folderStructure.media)}/.`,
41
+ `^${relative(cwd(), folderStructure.accounts)}/.`,
42
+ `^${relative(cwd(), folderStructure.sessions)}/.`,
43
+ `^${relative(cwd(), folderStructure.cache)}/.`,
44
+ `^${relative(cwd(), folderStructure.logs)}/.`,
45
+ `^${relative(cwd(), join(folderStructure.site, 'languages'))}/.`,
38
46
  ]
39
47
  const excludeGlob = [...config.excludeGlob, '.*', '.*/']
40
48
  const include = config.include
@@ -67,6 +75,7 @@ export const main = defineCommand({
67
75
  excludeGlob,
68
76
  include,
69
77
  includeGlob,
78
+ force: args.force,
70
79
  })
71
80
  },
72
81
  subCommands: {
package/src/config.ts CHANGED
@@ -69,6 +69,7 @@ export const loadConfig = async (): Promise<ConfigResolved | null> => {
69
69
  remoteDir: './',
70
70
  dryRun: true,
71
71
  verbose: false,
72
+ force: false,
72
73
  parallel: 10,
73
74
  checkComposerLock: true,
74
75
  callWebhooks: true,
package/src/lftp/cat.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  import { spawnSync } from 'child_process'
2
2
  import { consola } from 'consola'
3
+ import { join } from 'path'
3
4
  import { platform } from 'os'
4
5
  import { ConfigResolved } from '../types'
5
6
 
6
7
  export const cat = (
7
8
  file: string,
8
- { host, user, password, lftpSettings }: ConfigResolved,
9
+ { host, user, password, remoteDir, lftpSettings }: ConfigResolved,
9
10
  ) => {
10
11
  const commands = [
11
12
  ...Object.entries(lftpSettings).map(
12
13
  ([key, value]) => `set ${key} ${value}`,
13
14
  ),
14
- `open ${host}`,
15
- `user ${user} ${password}`,
16
- `cat ${file}`,
15
+ `open -u ${user},${password} ${host}`,
16
+ `cat ${join(remoteDir, file)}`,
17
17
  'bye',
18
18
  ]
19
19
 
@@ -25,8 +25,9 @@ export const cat = (
25
25
  : spawnSync('lftp', ['-c', commands.join('; ')], { encoding: 'utf-8' })
26
26
 
27
27
  if (child.stderr) {
28
- // 550 means the file doesn't exist, silently return undefined
29
- if (child.stderr.includes('550')) return undefined
28
+ // 550 or "No such file" means the file doesn't exist, silently return undefined
29
+ if (child.stderr.includes('550') || child.stderr.includes('No such file'))
30
+ return undefined
30
31
  consola.error(child.stderr)
31
32
  return undefined
32
33
  }
@@ -19,8 +19,7 @@ export const mirror = (
19
19
  ...Object.entries(lftpSettings).map(
20
20
  ([key, value]) => `set ${key} ${value}`,
21
21
  ),
22
- `open ${host}`,
23
- `user ${user} ${password}`, // mask credentials
22
+ `open -u ${user},${password} ${host}`,
24
23
  `mirror ${flags.join(' ')} ${source} ${destination}`,
25
24
  'bye',
26
25
  ]
@@ -42,6 +41,9 @@ export const mirror = (
42
41
  if ((match = line.match(/Transferring file `(.*)'/))) {
43
42
  hasChanges = true
44
43
  consola.log(colors.blue(`→ ${match[1]}`))
44
+ } else if ((match = line.match(/Making directory `(.*)'/))) {
45
+ hasChanges = true
46
+ consola.log(colors.blue(`→ ${match[1]}`))
45
47
  } else if (
46
48
  (match = line.match(/Removing old (?:file|directory) `(.*)'/))
47
49
  ) {
package/src/sync.ts CHANGED
@@ -28,11 +28,11 @@ export const sync = async (
28
28
 
29
29
  const flags = [
30
30
  '--continue',
31
- '--only-newer',
32
31
  '--overwrite',
33
- '--use-cache',
34
32
  '--delete',
35
33
  '--verbose',
34
+ !config.force && '--use-cache',
35
+ config.force && '--transfer-all',
36
36
  reverse && '--reverse',
37
37
  ...config.exclude.map((path: string) => `--exclude ${path}`),
38
38
  ...config.excludeGlob.map((path: string) => `--exclude-glob ${path}`),
package/src/types.ts CHANGED
@@ -43,6 +43,7 @@ export const ConfigSchema = object({
43
43
  callWebhooks: optional(boolean()),
44
44
  dryRun: optional(boolean()),
45
45
  verbose: optional(boolean()),
46
+ force: optional(boolean()),
46
47
  parallel: optional(number()),
47
48
  exclude: optional(array(string())),
48
49
  excludeGlob: optional(array(string())),