Skip to content

Commit

Permalink
init: Run Prettier after templating (#1337)
Browse files Browse the repository at this point in the history
This Markdown table is not pretty after templating, but we swallowed the
command failure in the `test-template` script:

https://github.com/seek-oss/skuba/blob/83ccc1bd424222570373cac19dc38b69646d8785/template/oss-npm-package/README.md?plain=1#L115

---------

Co-authored-by: skuba <[email protected]>
  • Loading branch information
72636c and seek-oss-ci authored Dec 13, 2023
1 parent 0f0090b commit 347b0bc
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/plenty-rings-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'skuba': patch
---

init: Run Prettier after templating
4 changes: 4 additions & 0 deletions docs/cli/init.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Creates a new local project from a starter [template].
and only requires a connection to the public npm registry.
Most of its built-in templates start you off with a [Buildkite pipeline] that should be ready to go once you push your repository to GitHub and configure Buildkite.

| Option | Description |
| :-------- | :-------------------------- |
| `--debug` | Enable debug console output |

### Interactive walkthrough

Let's start by running the command:
Expand Down
4 changes: 4 additions & 0 deletions scripts/test-template.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env sh

set -e

template="${1}"
if [ -z "$template" ]; then
echo "Usage: yarn test:template <template_name>"
Expand Down Expand Up @@ -53,12 +55,14 @@ yarn skuba version
yarn skuba -v
yarn skuba --version

set +e
echo "--- skuba build ${template}"
output=$(yarn build 2>&1)
echo $output
if [[ $? -ne 0 && $output != *"Command \"build\" not found"* ]]; then
exit 1
fi
set -e

echo "--- skuba lint ${template}"
yarn lint
Expand Down
92 changes: 91 additions & 1 deletion src/cli/adapter/prettier.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { inferParser } from './prettier';
/* eslint-disable no-console */

import path from 'path';

import { log } from '../../utils/logging';

import { inferParser, runPrettier } from './prettier';

describe('inferParser', () => {
test.each`
Expand All @@ -15,3 +21,87 @@ describe('inferParser', () => {
await expect(inferParser(filepath)).resolves.toBe(parser),
);
});

describe('runPrettier', () => {
const originalCwd = process.cwd();

afterAll(() =>
// Restore the original working directory to avoid confusion in other tests.
process.chdir(originalCwd),
);

const originalConsoleLog = console.log;

beforeAll(() => (console.log = () => undefined));
afterAll(() => (console.log = originalConsoleLog));

it('handles a custom directory with a common root', async () => {
process.chdir(path.join(__dirname, '../../..'));

await expect(
runPrettier(
'lint',
log,
path.join(__dirname, '../../../integration/base/fixable'),
),
).resolves.toMatchInlineSnapshot(`
{
"ok": false,
"result": {
"count": 8,
"errored": [
{
"filepath": "integration/base/fixable/b.md",
},
{
"filepath": "integration/base/fixable/c.json",
},
{
"filepath": "integration/base/fixable/d.js",
},
{
"filepath": "integration/base/fixable/package.json",
},
],
"touched": [],
"unparsed": [],
},
}
`);
});

it('handles a custom directory with a different root', async () => {
process.chdir(__dirname);

await expect(
runPrettier(
'lint',
log,
path.join(__dirname, '../../../integration/base/fixable'),
),
).resolves.toMatchInlineSnapshot(`
{
"ok": false,
"result": {
"count": 8,
"errored": [
{
"filepath": "../../../integration/base/fixable/b.md",
},
{
"filepath": "../../../integration/base/fixable/c.json",
},
{
"filepath": "../../../integration/base/fixable/d.js",
},
{
"filepath": "../../../integration/base/fixable/package.json",
},
],
"touched": [],
"unparsed": [],
},
}
`);
});
});
23 changes: 14 additions & 9 deletions src/cli/adapter/prettier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,15 @@ export interface PrettierOutput {
export const runPrettier = async (
mode: 'format' | 'lint',
logger: Logger,
cwd = process.cwd(),
): Promise<PrettierOutput> => {
logger.debug('Initialising Prettier...');

const start = process.hrtime.bigint();

let directory = process.cwd();
const manifest = await getConsumerManifest(cwd);

const manifest = await getConsumerManifest();
if (manifest) {
directory = path.dirname(manifest.path);
}
const directory = manifest ? path.dirname(manifest.path) : cwd;

logger.debug(
manifest ? 'Detected project root:' : 'Detected working directory:',
Expand All @@ -178,23 +176,30 @@ export const runPrettier = async (
// This avoids exhibiting different behaviour than a Prettier IDE integration,
// though it may present headaches if `.gitignore` and `.prettierignore` rules
// conflict.
const filepaths = await crawlDirectory(directory, [
const relativeFilepaths = await crawlDirectory(directory, [
'.gitignore',
'.prettierignore',
]);

logger.debug(`Discovered ${pluralise(filepaths.length, 'file')}.`);
logger.debug(`Discovered ${pluralise(relativeFilepaths.length, 'file')}.`);

const result: Result = {
count: filepaths.length,
count: relativeFilepaths.length,
errored: [],
touched: [],
unparsed: [],
};

logger.debug(mode === 'format' ? 'Formatting' : 'Linting', 'files...');

for (const filepath of filepaths) {
for (const relativeFilepath of relativeFilepaths) {
// Use relative paths to keep log output cleaner, particularly in the common
// case where we are executing against the current working directory.
const filepath = path.relative(
process.cwd(),
path.join(directory, relativeFilepath),
);

// Infer parser upfront so we can skip unsupported files.
const parser = await inferParser(filepath);

Expand Down
22 changes: 19 additions & 3 deletions src/cli/init/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import path from 'path';
import { inspect } from 'util';

import { commitAllChanges } from '../../api/git';
import { hasDebugFlag } from '../../utils/args';
import { copyFiles, createEjsRenderer } from '../../utils/copy';
import { createInclusionFilter } from '../../utils/dir';
import { createExec, ensureCommands } from '../../utils/exec';
import { log } from '../../utils/logging';
import { createLogger, log } from '../../utils/logging';
import { showLogoAndVersionInfo } from '../../utils/logo';
import {
BASE_TEMPLATE_DIR,
ensureTemplateConfigDeletion,
} from '../../utils/template';
import { runPrettier } from '../adapter/prettier';
import { tryPatchRenovateConfig } from '../configure/patchRenovateConfig';

import { getConfig } from './getConfig';
import { initialiseRepo } from './git';
import type { Input } from './types';
import { writePackageJson } from './writePackageJson';

export const init = async () => {
export const init = async (args = process.argv.slice(2)) => {
const opts: Input = {
debug: hasDebugFlag(args),
};

const skubaVersionInfo = await showLogoAndVersionInfo();

await ensureCommands('yarn');
Expand Down Expand Up @@ -86,8 +94,15 @@ export const init = async () => {
let depsInstalled = false;
try {
await exec('yarn', 'add', '--dev', skubaSlug);

// Templating can initially leave certain files in an unformatted state;
// consider a Markdown table with columns sized based on content length.
await runPrettier('format', createLogger(opts.debug), destinationDir);

depsInstalled = true;
} catch {}
} catch (err) {
log.warn(inspect(err));
}

await commitAllChanges({
dir: destinationDir,
Expand All @@ -114,6 +129,7 @@ export const init = async () => {
log.plain('Then, resume initialisation:');
log.ok('cd', destinationDir);
log.ok('yarn add --dev', skubaSlug);
log.ok('yarn format');
log.ok('git add --all');
log.ok('git commit --message', `'Pin ${skubaSlug}'`);
log.ok(`git push --set-upstream origin ${templateData.defaultBranch}`);
Expand Down
9 changes: 9 additions & 0 deletions src/cli/init/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { z } from 'zod';

import { projectTypeSchema } from '../../utils/manifest';

export interface Input {
/**
* Whether to enable verbose debug logging.
*
* Defaults to `false`.
*/
debug: boolean;
}

export type InitConfigInput = z.infer<typeof initConfigInputSchema>;

export const initConfigInputSchema = z.object({
Expand Down
2 changes: 1 addition & 1 deletion src/utils/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const getSkubaManifest = async (): Promise<NormalizedPackageJson> => {
return (skubaManifest = result.packageJson);
};

export const getConsumerManifest = () => readPkgUp();
export const getConsumerManifest = (cwd?: string) => readPkgUp({ cwd });

export const getPropFromConsumerManifest = async <
T extends string,
Expand Down

0 comments on commit 347b0bc

Please sign in to comment.