Skip to content

Commit de1aace

Browse files
committed
Draft: wire selective sync execution to pull-files/pull-db (guessed Reprint interface)
1 parent 293ee71 commit de1aace

2 files changed

Lines changed: 166 additions & 178 deletions

File tree

apps/cli/commands/pull-reprint.ts

Lines changed: 78 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,10 @@ export async function runCommand(
670670
}
671671

672672
if ( ! hasPullCompletedStage( studioMetadata, 'completed' ) ) {
673-
// Fetch the deferred media/uploads. The selector's media choice is not
674-
// applied yet (see runFullPull) — wired into pull-files in the follow-up.
675-
if ( hasSkippedFiles( studioMetadata.stateDirectory ) ) {
673+
// Fetch the deferred media/uploads unless the user excluded the media
674+
// library. Core, plugins, and themes already came down in the
675+
// essential-files pass; this second pass is just the media library.
676+
if ( ! studioMetadata.skipUploads && hasSkippedFiles( studioMetadata.stateDirectory ) ) {
676677
await downloadSkippedFiles(
677678
getSiteRuntime( site ),
678679
studioMetadata,
@@ -1017,26 +1018,27 @@ function readPullMetadata( metadataPath: string ): PullSessionMetadata | null {
10171018
}
10181019

10191020
/**
1020-
* Run reprint's composite `pull` command: the whole site-clone
1021-
* pipeline (preflight → files-pull → db-pull → db-apply →
1022-
* flat-docroot → apply-runtime) in a single child process, with
1023-
* reprint owning the stage ordering and, when the prior pull already
1024-
* completed, resetting its own sub-command state for a delta re-pull
1025-
* via prepare_repull().
1021+
* Run the site-clone pipeline as three high-level reprint commands so the
1022+
* selective-sync choice maps cleanly onto them:
10261023
*
1027-
* The SQLite target geometry:
1028-
* - If preflight exposed the remote `wp-content` (contentDir set),
1029-
* the database lands under `rawDirectory + contentDir`, an
1030-
* already-mounted host path that flat-docroot later symlinks into
1031-
* the flattened site.
1032-
* - Otherwise it falls back to `sitePath/wp-content`.
1024+
* 1. `pull-files` — files + flattened layout (`--only` restricts to the
1025+
* chosen wp-content folders).
1026+
* 2. `pull-db` — database download + import. **Skipped entirely** when the
1027+
* user excluded the database.
1028+
* 3. `apply-runtime` — server config, run last so it picks up the DB
1029+
* credentials `pull-db` wrote to state.
10331030
*
1034-
* The flattened site (`--flatten-to`) and runtime output
1035-
* (`--output-dir`) directories are mounted up front so the single
1036-
* fork can write them onto the host filesystem. `ensurePort` must
1037-
* run first so `--new-site-url` points at the local server.
1031+
* DRAFT — `pull-files`/`pull-db` are high-level commands Reprint is adding to
1032+
* hide the low-level orchestration (files-index/files-pull/flat-docroot and
1033+
* db-pull/db-apply). Names, arguments, and which command owns flatten/runtime
1034+
* are **guesses** (marked `TODO(reprint pull-files/pull-db)`); reconcile once
1035+
* the real interface lands. Optimized for simplicity and host-agnostic reuse:
1036+
* Studio just picks files vs db and passes `--only`; the commands own the rest.
10381037
*
1039-
* Advances the pull stage to 'pulled'.
1038+
* SQLite target geometry and the `--flatten-to`/`--output-dir` mounts carry
1039+
* over from the previous composite-`pull` call. Advances the stage to 'pulled';
1040+
* the three commands are individually resumable/idempotent, so a crash between
1041+
* them safely re-runs the lot on the next pass.
10401042
*/
10411043
export async function runFullPull(
10421044
runtime: SiteRuntime,
@@ -1050,41 +1052,67 @@ export async function runFullPull(
10501052
? `${ metadata.rawDirectory }${ contentDir }/database/.ht.sqlite`
10511053
: `${ metadata.sitePath }/wp-content/database/.ht.sqlite`;
10521054
const reprintRuntime = runtime === SITE_RUNTIME_NATIVE_PHP ? 'nginx-fpm' : 'playground-cli';
1055+
const onlyArgs = ( metadata.fileOnlyPaths ?? [] ).map( ( onlyPath ) => `--only=${ onlyPath }` );
1056+
const mounts = [
1057+
{ hostPath: metadata.sitePath, vfsPath: metadata.sitePath },
1058+
{ hostPath: metadata.runtimeDirectory, vfsPath: metadata.runtimeDirectory },
1059+
];
1060+
1061+
const runStep = ( progressLabel: string, args: string[] ) =>
1062+
runReprintCommandUntilComplete(
1063+
metadata.stateDirectory,
1064+
metadata.rawDirectory,
1065+
args,
1066+
( progress ) => logger.reportProgress( progress ),
1067+
{ progressLabel, mounts, verboseCommands: verbose, runtime }
1068+
);
10531069

10541070
logger.reportStart( LoggerAction.DOWNLOAD_FILES, __( 'Pulling site…' ) );
1055-
await runReprintCommandUntilComplete(
1056-
metadata.stateDirectory,
1057-
metadata.rawDirectory,
1058-
[
1059-
'pull',
1071+
1072+
// 1. Files (+ flattened layout). `--only` restricts to the selected folders.
1073+
// TODO(reprint pull-files): confirm command name; whether it owns flat-docroot;
1074+
// and how it expresses "defer uploads" (assumed --filter=essential-files +
1075+
// the deferred files-sync pass below).
1076+
await runStep( __( 'Pulling files' ), [
1077+
'pull-files',
1078+
apiUrl,
1079+
`--secret=${ secret }`,
1080+
'--filter=essential-files',
1081+
...onlyArgs,
1082+
`--flatten-to=${ metadata.sitePath }`,
1083+
'--no-adaptive',
1084+
`--state-dir=${ metadata.stateDirectory }`,
1085+
`--fs-root=${ metadata.rawDirectory }`,
1086+
] );
1087+
1088+
// 2. Database — only when selected. Skipping it leaves the local DB untouched
1089+
// on a re-pull (apply-runtime keeps the credentials already in state).
1090+
// TODO(reprint pull-db): confirm command name + target/rewrite args.
1091+
if ( ! metadata.skipDatabase ) {
1092+
await runStep( __( 'Pulling database' ), [
1093+
'pull-db',
10601094
apiUrl,
10611095
`--secret=${ secret }`,
1062-
'--filter=essential-files',
10631096
'--target-engine=sqlite',
10641097
`--target-sqlite-path=${ sqlitePath }`,
10651098
`--new-site-url=${ metadata.localUrl! }`,
1066-
`--flatten-to=${ metadata.sitePath }`,
1067-
`--runtime=${ reprintRuntime }`,
1068-
'--start-runtime=none',
1069-
`--output-dir=${ metadata.runtimeDirectory }`,
10701099
'--no-adaptive',
10711100
`--state-dir=${ metadata.stateDirectory }`,
10721101
`--fs-root=${ metadata.rawDirectory }`,
1073-
// NOTE: the interactive selector / `--only` / `--skip-*` choices are
1074-
// captured in metadata but NOT applied yet — this is a full pull. The
1075-
// selection is wired into `pull-files`/`pull-db` in the follow-up PR.
1076-
],
1077-
( progress ) => logger.reportProgress( progress ),
1078-
{
1079-
progressLabel: __( 'Pulling site' ),
1080-
mounts: [
1081-
{ hostPath: metadata.sitePath, vfsPath: metadata.sitePath },
1082-
{ hostPath: metadata.runtimeDirectory, vfsPath: metadata.runtimeDirectory },
1083-
],
1084-
verboseCommands: verbose,
1085-
runtime,
1086-
}
1087-
);
1102+
] );
1103+
}
1104+
1105+
// 3. Runtime config — last, so it embeds the DB credentials pull-db wrote.
1106+
await runStep( __( 'Preparing runtime' ), [
1107+
'apply-runtime',
1108+
'-',
1109+
`--runtime=${ reprintRuntime }`,
1110+
`--output-dir=${ metadata.runtimeDirectory }`,
1111+
`--flat-document-root=${ metadata.sitePath }`,
1112+
'--no-adaptive',
1113+
`--state-dir=${ metadata.stateDirectory }`,
1114+
] );
1115+
10881116
logger.reportSuccess( __( 'Site pulled' ) );
10891117
recordCompletedStage( metadata, 'pulled' );
10901118
}
@@ -1440,7 +1468,7 @@ export function getReprintApiUrlForSite( siteUrl: string ): string {
14401468
}
14411469

14421470
function buildFilesSyncArgs(
1443-
metadata: Pick< PullSessionMetadata, 'stateDirectory' | 'rawDirectory' >,
1471+
metadata: Pick< PullSessionMetadata, 'stateDirectory' | 'rawDirectory' | 'fileOnlyPaths' >,
14441472
apiUrl: string,
14451473
secret: string,
14461474
extraArgs: string[] = []
@@ -1450,6 +1478,10 @@ function buildFilesSyncArgs(
14501478
apiUrl,
14511479
`--secret=${ secret }`,
14521480
...extraArgs,
1481+
// Carry the same `--only` set as pull-files so the deferred pass stays in
1482+
// scope (files-sync's index is a union keyed by a fingerprint of the
1483+
// prefixes and refuses to resume with a different `--only`).
1484+
...( metadata.fileOnlyPaths ?? [] ).map( ( onlyPath ) => `--only=${ onlyPath }` ),
14531485
// Per-batch ceiling — one sub-process yields after 30 s and the
14541486
// client reconnects to continue. Not a total-time budget; a slow
14551487
// or high-latency sync just makes more round-trips. Kept well

0 commit comments

Comments
 (0)