update message
This commit is contained in:
parent
cb0b7a04ca
commit
9e6e7e3550
@ -19,6 +19,7 @@ import {
|
||||
validateMinVersion,
|
||||
isVersionCompatible,
|
||||
checkPackageHasContent,
|
||||
checkPackageHasContentWithContext,
|
||||
validateRealpathInsideRoot,
|
||||
resolvePackConfigPath,
|
||||
} from '../../features/ensemble/takt-pack-config.js';
|
||||
@ -247,6 +248,14 @@ describe('checkPackageHasContent', () => {
|
||||
expect(() => checkPackageHasContent(tempDir)).toThrow();
|
||||
});
|
||||
|
||||
it('should include manifest/path/hint details in contextual error', () => {
|
||||
const manifestPath = join(tempDir, '.takt', 'takt-package.yaml');
|
||||
expect(() => checkPackageHasContentWithContext(tempDir, {
|
||||
manifestPath,
|
||||
configuredPath: '.',
|
||||
})).toThrow(/path: \.takt/);
|
||||
});
|
||||
|
||||
it('should not throw when only faceted/ exists', () => {
|
||||
// Given: package with faceted/ only
|
||||
mkdirSync(join(tempDir, 'faceted'), { recursive: true });
|
||||
|
||||
@ -10,6 +10,7 @@ import { mkdirSync, copyFileSync, existsSync, readFileSync, writeFileSync, rmSyn
|
||||
import { join, dirname } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { createRequire } from 'node:module';
|
||||
import { stringify as stringifyYaml } from 'yaml';
|
||||
import { getEnsemblePackageDir } from '../../infra/config/paths.js';
|
||||
import { parseGithubSpec } from '../../features/ensemble/github-spec.js';
|
||||
@ -18,7 +19,7 @@ import {
|
||||
validateTaktPackPath,
|
||||
validateMinVersion,
|
||||
isVersionCompatible,
|
||||
checkPackageHasContent,
|
||||
checkPackageHasContentWithContext,
|
||||
validateRealpathInsideRoot,
|
||||
resolvePackConfigPath,
|
||||
} from '../../features/ensemble/takt-pack-config.js';
|
||||
@ -33,7 +34,7 @@ import { confirm } from '../../shared/prompt/index.js';
|
||||
import { info, success } from '../../shared/ui/index.js';
|
||||
import { createLogger, getErrorMessage } from '../../shared/utils/index.js';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const require = createRequire(import.meta.url);
|
||||
const { version: TAKT_VERSION } = require('../../../package.json') as { version: string };
|
||||
|
||||
const log = createLogger('ensemble-add');
|
||||
@ -63,16 +64,15 @@ export async function ensembleAddCommand(spec: string): Promise<void> {
|
||||
mkdirSync(tmpExtractDir, { recursive: true });
|
||||
|
||||
info(`📦 ${owner}/${repo} @${ref} をダウンロード中...`);
|
||||
execFileSync(
|
||||
const tarballBuffer = execFileSync(
|
||||
'gh',
|
||||
[
|
||||
'api',
|
||||
`/repos/${owner}/${repo}/tarball/${ref}`,
|
||||
'--header', 'Accept: application/octet-stream',
|
||||
'--output', tmpTarPath,
|
||||
],
|
||||
{ stdio: ['inherit', 'pipe', 'pipe'] },
|
||||
);
|
||||
writeFileSync(tmpTarPath, tarballBuffer);
|
||||
|
||||
const tarVerboseList = execFileSync('tar', ['tvzf', tmpTarPath], {
|
||||
encoding: 'utf-8',
|
||||
@ -112,7 +112,10 @@ export async function ensembleAddCommand(spec: string): Promise<void> {
|
||||
|
||||
validateRealpathInsideRoot(packageRoot, tmpExtractDir);
|
||||
|
||||
checkPackageHasContent(packageRoot);
|
||||
checkPackageHasContentWithContext(packageRoot, {
|
||||
manifestPath: packConfigPath,
|
||||
configuredPath: config.path,
|
||||
});
|
||||
|
||||
const targets = collectCopyTargets(packageRoot);
|
||||
const facetFiles = targets.filter(t => t.relativePath.startsWith('faceted/'));
|
||||
|
||||
@ -23,6 +23,11 @@ export interface TaktPackConfig {
|
||||
};
|
||||
}
|
||||
|
||||
interface PackageContentCheckContext {
|
||||
manifestPath?: string;
|
||||
configuredPath?: string;
|
||||
}
|
||||
|
||||
const SEMVER_PATTERN = /^\d+\.\d+\.\d+$/;
|
||||
|
||||
/**
|
||||
@ -113,6 +118,41 @@ export function checkPackageHasContent(packageRoot: string): void {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check package content and include user-facing diagnostics when empty.
|
||||
*
|
||||
* Adds manifest/configured-path details and a practical hint for nested layouts
|
||||
* (e.g. when actual content is under ".takt/" but path remains ".").
|
||||
*/
|
||||
export function checkPackageHasContentWithContext(
|
||||
packageRoot: string,
|
||||
context: PackageContentCheckContext,
|
||||
): void {
|
||||
const hasFaceted = existsSync(join(packageRoot, 'faceted'));
|
||||
const hasPieces = existsSync(join(packageRoot, 'pieces'));
|
||||
if (hasFaceted || hasPieces) return;
|
||||
|
||||
const checkedFaceted = join(packageRoot, 'faceted');
|
||||
const checkedPieces = join(packageRoot, 'pieces');
|
||||
const configuredPath = context.configuredPath ?? '.';
|
||||
const manifestPath = context.manifestPath ?? '(unknown)';
|
||||
const hint = configuredPath === '.'
|
||||
? `hint: If your package content is under ".takt/", set "path: .takt" in ${TAKT_PACKAGE_MANIFEST_FILENAME}.`
|
||||
: `hint: Verify "path: ${configuredPath}" points to a directory containing faceted/ or pieces/.`;
|
||||
|
||||
throw new Error(
|
||||
[
|
||||
'Package content not found.',
|
||||
`manifest: ${manifestPath}`,
|
||||
`configured path: ${configuredPath}`,
|
||||
`resolved package root: ${packageRoot}`,
|
||||
`checked: ${checkedFaceted}`,
|
||||
`checked: ${checkedPieces}`,
|
||||
hint,
|
||||
].join('\n'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the path to takt-package.yaml within an extracted tarball directory.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user