pulled store art never goes into the app repo: art pull --write, init and onboard add the renders folder (relative to the repo root, e.g. /store/renders/) to the repo's .gitignore when git check-ignore says it is not ignored yet, with one line saying so; tests
This commit is contained in:
parent
81915651bd
commit
fb3a7c186b
6 changed files with 69 additions and 3 deletions
|
|
@ -30,6 +30,7 @@ import {
|
|||
posix, type Pulled, PULLED_FILE, readPulled, type RemoteArt, sha256Of, slotOf, sniffExt, storeEmptySets, summarize, thumbSize,
|
||||
} from './lib/art-pull';
|
||||
import { playClient } from './play/client';
|
||||
import { ignoreInRepo } from './lib/git-ignore';
|
||||
import { decodePng, hashGray, imageSimilarity } from './lib/imagehash';
|
||||
import { IMAGE_SPECS, checkImage, imageInfo } from './shots/spec';
|
||||
|
||||
|
|
@ -260,6 +261,8 @@ export interface PullReport {
|
|||
storeEmpty: string[];
|
||||
notes: string[];
|
||||
written: boolean;
|
||||
/** The line added to the app repo's ignore file (pulled art is never committed), or null. */
|
||||
gitignored?: string | null;
|
||||
manifest: string;
|
||||
}
|
||||
|
||||
|
|
@ -365,6 +368,8 @@ export async function artPull(ctx: Ctx, o: { store?: string; write: boolean; for
|
|||
writeFileSync(join(p.renders, PULLED_FILE), JSON.stringify(next, null, 2) + '\n');
|
||||
report.written = true;
|
||||
}
|
||||
// pulled store art never goes into the app's repo
|
||||
if (existsSync(p.renders)) report.gitignored = ignoreInRepo(p.renders, 'storebound: store art (rendered or pulled from the stores), never committed');
|
||||
if (failed.length) { report.notes.push(...failed.map(f => `failed: ${f}`)); process.exitCode = 1; }
|
||||
return report;
|
||||
}
|
||||
|
|
@ -387,6 +392,7 @@ export function printPull(r: PullReport, write: boolean): void {
|
|||
for (const s of r.stores) (s.ok ? log : warn)(TAG, s.ok ? `${s.store === 'apple' ? 'App Store' : 'Google Play'}: ${s.images} image(s)${s.version ? `, version ${s.version}` : ''}` : `${s.store}: could not read: ${s.error}`);
|
||||
if (r.steps.length) console.log(textTable(['action', 'files', 'why'], groupSteps(r.steps)));
|
||||
for (const u of r.unmapped) log(TAG, `${u}: no language in the config has this locale (not pulled)`);
|
||||
if (r.gitignored) log(TAG, `.gitignore: added ${r.gitignored} (store art stays out of the repo)`);
|
||||
for (const n of r.notes) warn(TAG, n);
|
||||
if (r.conflicts.length) warn(TAG, `${r.conflicts.length} local file(s) differ from the store and are kept: ${r.conflicts.slice(0, 8).join(', ')}${r.conflicts.length > 8 ? ', ...' : ''} (--force replaces them with the store's)`);
|
||||
const s = r.summary;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } fr
|
|||
import { dirname, join, relative, resolve } from 'node:path';
|
||||
import type { Args } from './lib/args';
|
||||
import { type AppProfile, PROFILES } from './lib/config';
|
||||
import { ignoreInRepo } from './lib/git-ignore';
|
||||
import { log } from './lib/log';
|
||||
import { TEMPLATE_TEXT } from './lib/template-files';
|
||||
import * as rt from './lib/rt';
|
||||
|
|
@ -70,5 +71,8 @@ export async function run(args: Args): Promise<void> {
|
|||
else writeFileSync(gi, '# storebound: credentials, fonts, temp files\n.storebound/\n');
|
||||
log('init', '.gitignore: added .storebound/');
|
||||
}
|
||||
// store art (rendered or pulled from the stores) is never committed
|
||||
const art = ignoreInRepo(join(root, 'store', 'renders'), 'storebound: store art (rendered or pulled from the stores), never committed');
|
||||
if (art) log('init', `.gitignore: added ${art}`);
|
||||
log('init', 'next: edit storebound.config.ts, store/*.md and .storebound/credentials.json, then `storebound check`; store/workflows/*.yml: storebound flow list');
|
||||
}
|
||||
|
|
|
|||
28
cli/lib/git-ignore.ts
Normal file
28
cli/lib/git-ignore.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Keep a folder out of the app's git repo: store art pulled from the stores (and renders) is never committed.
|
||||
import { appendFileSync, existsSync, readFileSync, realpathSync, writeFileSync } from 'node:fs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import { join, relative, sep } from 'node:path';
|
||||
|
||||
const git = (cwd: string, args: string[]) => spawnSync('git', args, { cwd, encoding: 'utf8', timeout: 15_000 });
|
||||
|
||||
/** When `dir` is inside a git repo and not ignored yet, adds `/<dir relative to the repo root>/` to the repo root's
|
||||
* .gitignore. Returns the line added, or null (no repo, no git, already ignored). `dry`: only says what it would add. */
|
||||
export function ignoreInRepo(dir: string, comment: string, dry = false): string | null {
|
||||
let probe = dir;
|
||||
while (!existsSync(probe)) { const up = join(probe, '..'); if (up === probe) return null; probe = up; }
|
||||
const top = git(probe, ['rev-parse', '--show-toplevel']);
|
||||
if (top.status !== 0) return null;
|
||||
const root = realpathSync(top.stdout.trim());
|
||||
let real: string;
|
||||
try { real = realpathSync(probe) + dir.slice(probe.length); } catch { return null; }
|
||||
const rel = relative(root, real).split(sep).join('/');
|
||||
if (!rel || rel.startsWith('..')) return null;
|
||||
if (git(root, ['check-ignore', '-q', `${rel}/`]).status === 0) return null;
|
||||
const line = `/${rel}/`;
|
||||
if (dry) return line;
|
||||
const gi = join(root, '.gitignore');
|
||||
const cur = existsSync(gi) ? readFileSync(gi, 'utf8') : '';
|
||||
const add = `# ${comment}\n${line}\n`;
|
||||
if (cur) appendFileSync(gi, `${cur.endsWith('\n') ? '' : '\n'}${add}`); else writeFileSync(gi, add);
|
||||
return line;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue