@sqlanvil/cli 1.25.2 → 1.26.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/bundle.js +207 -22
- package/package.json +1 -1
package/bundle.js
CHANGED
|
@@ -50646,7 +50646,7 @@ function collectEvaluationQueries(queryOrAction, concatenate, queryModifier = (q
|
|
|
50646
50646
|
.filter(validationQuery => !!validationQuery.query);
|
|
50647
50647
|
}
|
|
50648
50648
|
|
|
50649
|
-
const version = "1.
|
|
50649
|
+
const version = "1.26.1";
|
|
50650
50650
|
const dataformVersion = "3.0.61";
|
|
50651
50651
|
|
|
50652
50652
|
async function build(compiledGraph, runConfig, dbadapter) {
|
|
@@ -54722,7 +54722,7 @@ function readSourceConfig(srcDir) {
|
|
|
54722
54722
|
};
|
|
54723
54723
|
}
|
|
54724
54724
|
async function migrateDataform(opts) {
|
|
54725
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
54725
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
54726
54726
|
const srcDir = path__namespace.resolve(opts.srcDir);
|
|
54727
54727
|
const outDir = path__namespace.resolve(opts.outDir);
|
|
54728
54728
|
if (containsPath(srcDir, outDir)) {
|
|
@@ -54770,12 +54770,15 @@ async function migrateDataform(opts) {
|
|
|
54770
54770
|
const declarationSchemas = new Set();
|
|
54771
54771
|
const targetSchemas = new Set();
|
|
54772
54772
|
const connectionMap = new Map();
|
|
54773
|
+
const introspectCommands = [];
|
|
54773
54774
|
for (const f of isBigQueryTarget ? [] : sqlxFiles) {
|
|
54774
54775
|
if (f.parsed.type === "declaration") {
|
|
54775
54776
|
const dataset = (_d = f.parsed.schema) !== null && _d !== void 0 ? _d : sourceConfig.defaultDataset;
|
|
54776
54777
|
const project = resolveDatabase(f.parsed.database);
|
|
54777
54778
|
declarationSchemas.add(dataset);
|
|
54778
54779
|
const name = connectionNameFor(project);
|
|
54780
|
+
const tableName = (_e = f.parsed.name) !== null && _e !== void 0 ? _e : path__namespace.basename(f.rel, ".sqlx");
|
|
54781
|
+
introspectCommands.push(`sqlanvil introspect ${name} ${JSON.stringify(`${dataset}.${tableName}`)} --output ${JSON.stringify(f.rel)}`);
|
|
54779
54782
|
const existing = connectionMap.get(name);
|
|
54780
54783
|
if (existing) {
|
|
54781
54784
|
existing.declarationCount++;
|
|
@@ -54793,7 +54796,7 @@ async function migrateDataform(opts) {
|
|
|
54793
54796
|
}
|
|
54794
54797
|
}
|
|
54795
54798
|
else if (f.parsed.type) {
|
|
54796
|
-
targetSchemas.add((
|
|
54799
|
+
targetSchemas.add((_f = f.parsed.schema) !== null && _f !== void 0 ? _f : sourceConfig.defaultDataset);
|
|
54797
54800
|
}
|
|
54798
54801
|
}
|
|
54799
54802
|
report.connections = [...connectionMap.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -54811,14 +54814,14 @@ async function migrateDataform(opts) {
|
|
|
54811
54814
|
report.files.push({
|
|
54812
54815
|
file: rel,
|
|
54813
54816
|
action: info.parsed.type === "declaration" ? "declaration" : "target",
|
|
54814
|
-
type: (
|
|
54817
|
+
type: (_g = info.parsed.type) !== null && _g !== void 0 ? _g : "(none)",
|
|
54815
54818
|
status: findings.length === 0 ? "clean" : "rewritten",
|
|
54816
54819
|
findings,
|
|
54817
54820
|
});
|
|
54818
54821
|
continue;
|
|
54819
54822
|
}
|
|
54820
54823
|
if (info.parsed.type === "declaration") {
|
|
54821
|
-
const dataset = (
|
|
54824
|
+
const dataset = (_h = info.parsed.schema) !== null && _h !== void 0 ? _h : sourceConfig.defaultDataset;
|
|
54822
54825
|
const project = resolveDatabase(info.parsed.database);
|
|
54823
54826
|
const connection = connectionNameFor(project);
|
|
54824
54827
|
const { content, findings } = convertDeclaration(info.source, info.parsed, connection, dataset, rel);
|
|
@@ -54838,7 +54841,7 @@ async function migrateDataform(opts) {
|
|
|
54838
54841
|
report.files.push({
|
|
54839
54842
|
file: rel,
|
|
54840
54843
|
action: "target",
|
|
54841
|
-
type: (
|
|
54844
|
+
type: (_j = info.parsed.type) !== null && _j !== void 0 ? _j : "(none)",
|
|
54842
54845
|
status: findings.length === 0
|
|
54843
54846
|
? "clean"
|
|
54844
54847
|
: findings.some(f => f.kind === "flag")
|
|
@@ -54875,14 +54878,17 @@ async function migrateDataform(opts) {
|
|
|
54875
54878
|
report.files.push({ file: rel, action: "copied", status: "clean", findings: [] });
|
|
54876
54879
|
}
|
|
54877
54880
|
const settings = isBigQueryTarget
|
|
54878
|
-
? Object.assign(Object.assign(Object.assign({}, (sourceConfig.defaultProject ? { defaultProject: sourceConfig.defaultProject } : {})), (sourceConfig.defaultLocation ? { defaultLocation: sourceConfig.defaultLocation } : {})), { defaultDataset: sourceConfig.defaultDataset, defaultAssertionDataset: (
|
|
54881
|
+
? Object.assign(Object.assign(Object.assign({}, (sourceConfig.defaultProject ? { defaultProject: sourceConfig.defaultProject } : {})), (sourceConfig.defaultLocation ? { defaultLocation: sourceConfig.defaultLocation } : {})), { defaultDataset: sourceConfig.defaultDataset, defaultAssertionDataset: (_k = sourceConfig.defaultAssertionDataset) !== null && _k !== void 0 ? _k : "sqlanvil_assertions", sqlanvilCoreVersion: (_l = opts.coreVersion) !== null && _l !== void 0 ? _l : version }) : {
|
|
54879
54882
|
warehouse: targetWarehouse,
|
|
54880
54883
|
defaultDataset: sourceConfig.defaultDataset.toLowerCase(),
|
|
54881
|
-
defaultAssertionDataset: ((
|
|
54882
|
-
sqlanvilCoreVersion: (
|
|
54884
|
+
defaultAssertionDataset: ((_m = sourceConfig.defaultAssertionDataset) !== null && _m !== void 0 ? _m : "sqlanvil_assertions").toLowerCase(),
|
|
54885
|
+
sqlanvilCoreVersion: (_o = opts.coreVersion) !== null && _o !== void 0 ? _o : version,
|
|
54883
54886
|
};
|
|
54884
54887
|
if (sourceConfig.vars)
|
|
54885
54888
|
settings.vars = sourceConfig.vars;
|
|
54889
|
+
if (isBigQueryTarget) {
|
|
54890
|
+
settings.environments = { test: { schemaSuffix: "test" } };
|
|
54891
|
+
}
|
|
54886
54892
|
if (report.connections.length > 0) {
|
|
54887
54893
|
settings.connections = Object.fromEntries(report.connections.map(c => {
|
|
54888
54894
|
var _a;
|
|
@@ -54898,11 +54904,53 @@ async function migrateDataform(opts) {
|
|
|
54898
54904
|
}));
|
|
54899
54905
|
}
|
|
54900
54906
|
writer.write("workflow_settings.yaml", jsYaml.dump(settings));
|
|
54907
|
+
if (!isBigQueryTarget && introspectCommands.length > 0) {
|
|
54908
|
+
writer.write("scripts/introspect_all.sh", `#!/bin/sh\n` +
|
|
54909
|
+
`# Generated by sqlanvil migrate-dataform: scaffold columnTypes for every converted\n` +
|
|
54910
|
+
`# declaration (${introspectCommands.length} commands). Requires BigQuery read access\n` +
|
|
54911
|
+
`# (gcloud auth application-default login). Re-runnable; then commit the changes.\n` +
|
|
54912
|
+
`set -e\n` +
|
|
54913
|
+
introspectCommands.join("\n") +
|
|
54914
|
+
`\n`);
|
|
54915
|
+
report.files.push({
|
|
54916
|
+
file: "scripts/introspect_all.sh",
|
|
54917
|
+
action: "generated",
|
|
54918
|
+
status: "clean",
|
|
54919
|
+
findings: []
|
|
54920
|
+
});
|
|
54921
|
+
}
|
|
54922
|
+
if (isBigQueryTarget && sourceConfig.defaultProject) {
|
|
54923
|
+
const adcCredentials = { projectId: sourceConfig.defaultProject };
|
|
54924
|
+
if (sourceConfig.defaultLocation) {
|
|
54925
|
+
adcCredentials.location = sourceConfig.defaultLocation;
|
|
54926
|
+
}
|
|
54927
|
+
writer.write(".df-credentials.json", `${JSON.stringify(adcCredentials, null, 2)}\n`);
|
|
54928
|
+
report.files.push({
|
|
54929
|
+
file: ".df-credentials.json",
|
|
54930
|
+
action: "generated",
|
|
54931
|
+
status: "clean",
|
|
54932
|
+
findings: []
|
|
54933
|
+
});
|
|
54934
|
+
const gitignorePath = path__namespace.join(outDir, ".gitignore");
|
|
54935
|
+
const existingGitignore = fs__namespace$1.existsSync(gitignorePath)
|
|
54936
|
+
? fs__namespace$1.readFileSync(gitignorePath, "utf8")
|
|
54937
|
+
: "";
|
|
54938
|
+
if (!existingGitignore.includes(".df-credentials")) {
|
|
54939
|
+
const separator = existingGitignore === "" || existingGitignore.endsWith("\n") ? "" : "\n";
|
|
54940
|
+
fs__namespace$1.writeFileSync(gitignorePath, `${existingGitignore}${separator}.df-credentials*.json\n`);
|
|
54941
|
+
report.files.push({
|
|
54942
|
+
file: ".gitignore",
|
|
54943
|
+
action: existingGitignore === "" ? "generated" : "updated",
|
|
54944
|
+
status: "clean",
|
|
54945
|
+
findings: []
|
|
54946
|
+
});
|
|
54947
|
+
}
|
|
54948
|
+
}
|
|
54901
54949
|
if (!fs__namespace$1.existsSync(path__namespace.join(outDir, "AGENTS.md"))) {
|
|
54902
54950
|
writer.write("AGENTS.md", agentsMdContents({
|
|
54903
54951
|
warehouse: targetWarehouse,
|
|
54904
54952
|
defaultDataset: settings.defaultDataset,
|
|
54905
|
-
version: (
|
|
54953
|
+
version: (_p = opts.coreVersion) !== null && _p !== void 0 ? _p : version,
|
|
54906
54954
|
converted: true
|
|
54907
54955
|
}));
|
|
54908
54956
|
report.files.push({ file: "AGENTS.md", action: "generated", status: "clean", findings: [] });
|
|
@@ -54953,7 +55001,13 @@ function renderReportMd(r) {
|
|
|
54953
55001
|
lines.push("");
|
|
54954
55002
|
lines.push(`Declarations keep reading BigQuery through named \`connections:\` in workflow_settings.yaml ` +
|
|
54955
55003
|
`(mode: runner-extract — no Vault, no wrappers). Each declaration needs \`columnTypes\` ` +
|
|
54956
|
-
`before it can extract
|
|
55004
|
+
`before it can extract. **Every concrete command is in the generated ` +
|
|
55005
|
+
`\`scripts/introspect_all.sh\`** — run it on a machine with BigQuery read access ` +
|
|
55006
|
+
`(\`gcloud auth application-default login\`), then commit what it writes:`);
|
|
55007
|
+
lines.push("");
|
|
55008
|
+
lines.push("```sh");
|
|
55009
|
+
lines.push("sh scripts/introspect_all.sh && git add -A && git commit -m 'columnTypes' && git push");
|
|
55010
|
+
lines.push("```");
|
|
54957
55011
|
lines.push("");
|
|
54958
55012
|
for (const c of r.connections) {
|
|
54959
55013
|
lines.push(`- **${c.name}** — project \`${c.project}\`, ${c.declarationCount} declaration(s) across ` +
|
|
@@ -55008,16 +55062,23 @@ function renderReportMd(r) {
|
|
|
55008
55062
|
lines.push("");
|
|
55009
55063
|
if (r.targetWarehouse === "bigquery") {
|
|
55010
55064
|
lines.push(`1. \`sqlanvil compile\` — should already succeed.`);
|
|
55011
|
-
lines.push(`2.
|
|
55012
|
-
`
|
|
55013
|
-
|
|
55014
|
-
|
|
55015
|
-
lines.push(`
|
|
55065
|
+
lines.push(`2. Authenticate the same way Dataform runs locally: \`gcloud auth application-default ` +
|
|
55066
|
+
`login\` (ADC). A secretless \`.df-credentials.json\` (project + location only) was ` +
|
|
55067
|
+
`generated for you — nothing else is needed. Service-account keys and keyless ` +
|
|
55068
|
+
`\`accessToken\` auth are supported for CI (see the BigQuery guide).`);
|
|
55069
|
+
lines.push(`3. \`sqlanvil validate\` — read-only: dry-runs every model against BigQuery without ` +
|
|
55070
|
+
`executing; all-PASS means the swap is complete.`);
|
|
55071
|
+
lines.push(`4. First real run in the scaffolded TEST environment — \`sqlanvil run . --environment ` +
|
|
55072
|
+
`test\` writes to \`<dataset>_test\` datasets, leaving production untouched. To land ` +
|
|
55073
|
+
`tests in a separate GCP project instead, set \`environments.test.defaultDatabase\` in ` +
|
|
55074
|
+
`workflow_settings.yaml. Once verified: \`sqlanvil run .\`.`);
|
|
55075
|
+
lines.push(`5. Compare \`sqlanvil compile\` output with \`dataform compile\` on the source for a ` +
|
|
55016
55076
|
`sample of actions — they should match apart from the compile-global rename.`);
|
|
55017
55077
|
}
|
|
55018
55078
|
else {
|
|
55019
55079
|
lines.push(`1. \`sqlanvil compile\` — should already succeed.`);
|
|
55020
|
-
lines.push(`2. Scaffold \`columnTypes\`
|
|
55080
|
+
lines.push(`2. Scaffold \`columnTypes\`: \`sh scripts/introspect_all.sh\` (every declaration's ` +
|
|
55081
|
+
`concrete command, generated), then commit what it writes.`);
|
|
55021
55082
|
lines.push(`3. \`sqlanvil validate\` against your Postgres/Supabase warehouse — PASS/FAILURE/BLOCKED per ` +
|
|
55022
55083
|
`model is the migration to-do list. Work the flagged files until validate is green.`);
|
|
55023
55084
|
lines.push(`4. This report is machine-readable (migration-report.json) — pointing an AI agent at it plus ` +
|
|
@@ -55564,6 +55625,14 @@ const CREDS_SSLMODE_QUESTION = "SSL mode? (disable/require)";
|
|
|
55564
55625
|
const CONVERT_SOURCE_QUESTION = "Path to the Dataform project to convert (read-only, never modified)?";
|
|
55565
55626
|
const CONVERT_OUT_QUESTION = "Directory for the converted sqlanvil project (created; must be empty)?";
|
|
55566
55627
|
const CONVERT_TARGET_QUESTION = "Target warehouse? (bigquery = keep running on BigQuery, tooling swap only; supabase/postgres = move off BigQuery)";
|
|
55628
|
+
const BQ_AUTH_QUESTION = "How should local runs authenticate to BigQuery? (adc = gcloud Application Default " +
|
|
55629
|
+
"Credentials, like Dataform local runs; key = service-account key file; later)";
|
|
55630
|
+
const BQ_AUTH_LOGIN_QUESTION = "No Application Default Credentials found. Run `gcloud auth application-default login` now?";
|
|
55631
|
+
const BQ_KEY_PATH_QUESTION = "Path to the service-account key JSON file?";
|
|
55632
|
+
const BQ_TEST_TARGET_QUESTION = "Where should test runs land before you touch production? (suffix = same project, " +
|
|
55633
|
+
"`<dataset>_test` datasets; project = a separate GCP project; none = no test environment)";
|
|
55634
|
+
const BQ_TEST_SUFFIX_QUESTION = "Dataset suffix for the test environment?";
|
|
55635
|
+
const BQ_TEST_PROJECT_QUESTION = "GCP project ID for the test environment?";
|
|
55567
55636
|
const SUPABASE_POOLER_HINT = "Use the SESSION POOLER connection (Supabase Dashboard -> Connect -> Session pooler): host " +
|
|
55568
55637
|
"aws-<n>-<region>.pooler.supabase.com, user postgres.<project-ref>. The direct " +
|
|
55569
55638
|
"db.<ref>.supabase.co host is IPv6-only and unreachable from most networks.";
|
|
@@ -55668,7 +55737,104 @@ function ensureGitignoreCoversCredentials(dir) {
|
|
|
55668
55737
|
const separator = existing === "" || existing.endsWith("\n") ? "" : "\n";
|
|
55669
55738
|
fs__namespace$1.writeFileSync(gitignorePath, `${existing}${separator}.df-credentials*.json\n`);
|
|
55670
55739
|
}
|
|
55740
|
+
function detectAdc() {
|
|
55741
|
+
if (process.env.DATAFORM_CLI_TEST_INPUTS !== undefined) {
|
|
55742
|
+
return false;
|
|
55743
|
+
}
|
|
55744
|
+
try {
|
|
55745
|
+
const result = childProcess.spawnSync("gcloud", ["auth", "application-default", "print-access-token"], {
|
|
55746
|
+
stdio: "ignore",
|
|
55747
|
+
timeout: 15000
|
|
55748
|
+
});
|
|
55749
|
+
return result.status === 0;
|
|
55750
|
+
}
|
|
55751
|
+
catch (e) {
|
|
55752
|
+
return false;
|
|
55753
|
+
}
|
|
55754
|
+
}
|
|
55755
|
+
function runBigQueryAuthStep(projectDir) {
|
|
55756
|
+
const mode = askChoice(BQ_AUTH_QUESTION, ["adc", "key", "later"], "adc");
|
|
55757
|
+
if (mode === "adc") {
|
|
55758
|
+
if (detectAdc()) {
|
|
55759
|
+
printSuccess("Application Default Credentials detected — runs authenticate as your gcloud account.");
|
|
55760
|
+
return;
|
|
55761
|
+
}
|
|
55762
|
+
if (askYesNo(BQ_AUTH_LOGIN_QUESTION, true)) {
|
|
55763
|
+
childProcess.spawnSync("gcloud", ["auth", "application-default", "login"], { stdio: "inherit" });
|
|
55764
|
+
if (detectAdc()) {
|
|
55765
|
+
printSuccess("ADC configured — runs authenticate as your gcloud account.");
|
|
55766
|
+
return;
|
|
55767
|
+
}
|
|
55768
|
+
}
|
|
55769
|
+
print("Run `gcloud auth application-default login` before `sqlanvil validate` / `run` — no " +
|
|
55770
|
+
"other credential setup is needed.");
|
|
55771
|
+
return;
|
|
55772
|
+
}
|
|
55773
|
+
if (mode === "key") {
|
|
55774
|
+
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
55775
|
+
const keyPath = actuallyResolve(askRequired(BQ_KEY_PATH_QUESTION));
|
|
55776
|
+
if (!fs__namespace$1.existsSync(keyPath)) {
|
|
55777
|
+
printError(`${keyPath} does not exist.`);
|
|
55778
|
+
continue;
|
|
55779
|
+
}
|
|
55780
|
+
try {
|
|
55781
|
+
const keyContents = fs__namespace$1.readFileSync(keyPath, "utf8");
|
|
55782
|
+
const parsed = JSON.parse(keyContents);
|
|
55783
|
+
if (!parsed.client_email) {
|
|
55784
|
+
printError(`${keyPath} does not look like a service-account key (no client_email).`);
|
|
55785
|
+
continue;
|
|
55786
|
+
}
|
|
55787
|
+
const credentialsPath = path__namespace.join(projectDir, CREDENTIALS_FILENAME);
|
|
55788
|
+
const existing = fs__namespace$1.existsSync(credentialsPath)
|
|
55789
|
+
? JSON.parse(fs__namespace$1.readFileSync(credentialsPath, "utf8"))
|
|
55790
|
+
: {};
|
|
55791
|
+
ensureGitignoreCoversCredentials(projectDir);
|
|
55792
|
+
fs__namespace$1.writeFileSync(credentialsPath, `${JSON.stringify(Object.assign(Object.assign({}, existing), { credentials: keyContents }), null, 2)}\n`);
|
|
55793
|
+
printSuccess(`Runs authenticate as ${parsed.client_email} (key embedded in the gitignored ` +
|
|
55794
|
+
`${CREDENTIALS_FILENAME}).`);
|
|
55795
|
+
return;
|
|
55796
|
+
}
|
|
55797
|
+
catch (e) {
|
|
55798
|
+
printError(`Could not read ${keyPath}: ${e instanceof Error ? e.message : e}`);
|
|
55799
|
+
}
|
|
55800
|
+
}
|
|
55801
|
+
return;
|
|
55802
|
+
}
|
|
55803
|
+
print("Skipped. Before `sqlanvil validate` / `run`: `gcloud auth application-default login`, or " +
|
|
55804
|
+
`add a service-account key as the \`credentials\` field of ${CREDENTIALS_FILENAME}.`);
|
|
55805
|
+
}
|
|
55806
|
+
function runBigQueryTestTargetStep(projectDir) {
|
|
55807
|
+
var _a;
|
|
55808
|
+
const choice = askChoice(BQ_TEST_TARGET_QUESTION, ["suffix", "project", "none"], "suffix");
|
|
55809
|
+
const settingsPath = path__namespace.join(projectDir, "workflow_settings.yaml");
|
|
55810
|
+
const settings = (jsYaml.load(fs__namespace$1.readFileSync(settingsPath, "utf8")) || {});
|
|
55811
|
+
if (choice === "none") {
|
|
55812
|
+
if ((_a = settings.environments) === null || _a === void 0 ? void 0 : _a.test) {
|
|
55813
|
+
delete settings.environments.test;
|
|
55814
|
+
if (Object.keys(settings.environments).length === 0) {
|
|
55815
|
+
delete settings.environments;
|
|
55816
|
+
}
|
|
55817
|
+
fs__namespace$1.writeFileSync(settingsPath, jsYaml.dump(settings));
|
|
55818
|
+
}
|
|
55819
|
+
print("No test environment — runs go straight to the configured datasets.");
|
|
55820
|
+
return;
|
|
55821
|
+
}
|
|
55822
|
+
const testEnv = {};
|
|
55823
|
+
if (choice === "suffix") {
|
|
55824
|
+
testEnv.schemaSuffix = ask(BQ_TEST_SUFFIX_QUESTION, "test");
|
|
55825
|
+
}
|
|
55826
|
+
else {
|
|
55827
|
+
testEnv.defaultDatabase = askRequired(BQ_TEST_PROJECT_QUESTION);
|
|
55828
|
+
}
|
|
55829
|
+
settings.environments = Object.assign(Object.assign({}, (settings.environments || {})), { test: testEnv });
|
|
55830
|
+
fs__namespace$1.writeFileSync(settingsPath, jsYaml.dump(settings));
|
|
55831
|
+
printSuccess(choice === "suffix"
|
|
55832
|
+
? `Test runs write to \`<dataset>_${testEnv.schemaSuffix}\` datasets ` +
|
|
55833
|
+
`(sqlanvil run . --environment test).`
|
|
55834
|
+
: `Test runs land in project ${testEnv.defaultDatabase} (sqlanvil run . --environment test).`);
|
|
55835
|
+
}
|
|
55671
55836
|
async function runConvertFlow() {
|
|
55837
|
+
var _a;
|
|
55672
55838
|
let srcDir = "";
|
|
55673
55839
|
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
55674
55840
|
const candidate = actuallyResolve(askRequired(CONVERT_SOURCE_QUESTION));
|
|
@@ -55687,11 +55853,23 @@ async function runConvertFlow() {
|
|
|
55687
55853
|
const report = await migrateDataform({ srcDir, outDir, targetWarehouse });
|
|
55688
55854
|
printMigrationSummary(report, outDir);
|
|
55689
55855
|
if (targetWarehouse === "bigquery") {
|
|
55856
|
+
print("");
|
|
55857
|
+
runBigQueryAuthStep(outDir);
|
|
55858
|
+
print("");
|
|
55859
|
+
runBigQueryTestTargetStep(outDir);
|
|
55860
|
+
const hasTestEnv = fs__namespace$1.existsSync(path__namespace.join(outDir, "workflow_settings.yaml"))
|
|
55861
|
+
? !!((_a = (jsYaml.load(fs__namespace$1.readFileSync(path__namespace.join(outDir, "workflow_settings.yaml"), "utf8")) || {}).environments) === null || _a === void 0 ? void 0 : _a.test)
|
|
55862
|
+
: false;
|
|
55690
55863
|
print("\nNext steps:");
|
|
55691
55864
|
print(` 1. sqlanvil compile ${outDir}`);
|
|
55692
|
-
print(
|
|
55693
|
-
|
|
55694
|
-
|
|
55865
|
+
print(` 2. sqlanvil validate ${outDir} (read-only dry-run of every model; all-PASS = swap complete)`);
|
|
55866
|
+
if (hasTestEnv) {
|
|
55867
|
+
print(` 3. sqlanvil run ${outDir} --environment test (first real run — production untouched)`);
|
|
55868
|
+
print(` 4. sqlanvil run ${outDir} (once the test run is verified)`);
|
|
55869
|
+
}
|
|
55870
|
+
else {
|
|
55871
|
+
print(` 3. sqlanvil run ${outDir}`);
|
|
55872
|
+
}
|
|
55695
55873
|
return 0;
|
|
55696
55874
|
}
|
|
55697
55875
|
if (askYesNo(INIT_CONFIGURE_CREDS_QUESTION, true)) {
|
|
@@ -55730,10 +55908,17 @@ async function runFreshFlow(defaultProjectDir) {
|
|
|
55730
55908
|
credentialsJson
|
|
55731
55909
|
});
|
|
55732
55910
|
printInitResult(result);
|
|
55733
|
-
const steps = [];
|
|
55734
55911
|
if (warehouse === "bigquery") {
|
|
55735
|
-
|
|
55912
|
+
const credentialsPath = path__namespace.join(projectDir, CREDENTIALS_FILENAME);
|
|
55913
|
+
if (!fs__namespace$1.existsSync(credentialsPath)) {
|
|
55914
|
+
ensureGitignoreCoversCredentials(projectDir);
|
|
55915
|
+
fs__namespace$1.writeFileSync(credentialsPath, `${JSON.stringify(Object.assign({ projectId: projectConfig.defaultDatabase }, (projectConfig.defaultLocation ? { location: projectConfig.defaultLocation } : {})), null, 2)}\n`);
|
|
55916
|
+
}
|
|
55917
|
+
print("");
|
|
55918
|
+
runBigQueryAuthStep(projectDir);
|
|
55736
55919
|
}
|
|
55920
|
+
const steps = [];
|
|
55921
|
+
if (warehouse === "bigquery") ;
|
|
55737
55922
|
else if (!credentialsJson) {
|
|
55738
55923
|
steps.push(`Edit ${CREDENTIALS_FILENAME} (gitignored) with your warehouse credentials.`);
|
|
55739
55924
|
}
|