Skip to content

Commit

Permalink
feat(core): add one change show (#663)
Browse files Browse the repository at this point in the history
**Problem:**

While it's easy to inspect the files in the `.changes` folder(s), it
would be more helpful to have a command that could list and preview the
changes together, including dependencies that need versioning.

**Solution:**

Adds `one change show` to preview versions and changelogs. Minimal for
now, ripe for making prettier.

**Related issues:**

Fixes #656

**Checklist:**

- [x] Added or updated tests
- [x] Added or updated documentation
- [x] Ensured the pre-commit hooks ran successfully
  • Loading branch information
paularmstrong committed Mar 10, 2024
1 parent f22e04d commit 15bff1b
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 7 deletions.
18 changes: 17 additions & 1 deletion docs/src/content/docs/core/changes.mdx
Expand Up @@ -207,7 +207,7 @@ Eventually, we will need to publish one or more Workspaces to our registry for u
## Commands

{/* start-auto-generated-from-cli-changes */}
{/* @generated SignedSource<<3b021d1d2d6206998de70671056ad043>> */}
{/* @generated SignedSource<<f529fa58fee56452257f226f54831a72>> */}

### `one change`

Expand Down Expand Up @@ -326,6 +326,22 @@ one change publish --all

---

#### `one change show`

Preview the next versions and changelogs for Workspaces.

```sh
one change show
```

| Option | Type | Description |
| ------------------ | --------------------------------------- | ---------------------------------------- |
| `--all, -a` | `boolean` | Run across all workspaces |
| `--format` | `"json"`, `"plain"`, default: `"plain"` | Choose how the results will be returned. |
| `--workspaces, -w` | `array` | List of Workspace names to run against |

---

#### `one change snapshot`

Aliases: `one change snap`
Expand Down
18 changes: 17 additions & 1 deletion docs/src/content/docs/plugins/docgen/example.mdx
Expand Up @@ -13,7 +13,7 @@ The following content is auto-generated using the [official documentation plugin
:::

{/* start-auto-generated-from-cli */}
{/* @generated SignedSource<<953a87825b511982869a1afa4ab8557b>> */}
{/* @generated SignedSource<<08893ba03b34cdb9ab05787ac817a439>> */}

## `one`

Expand Down Expand Up @@ -205,6 +205,22 @@ one change publish --all

---

#### `one change show`

Preview the next versions and changelogs for Workspaces.

```sh
one change show
```

| Option | Type | Description |
| ------------------ | --------------------------------------- | ---------------------------------------- |
| `--all, -a` | `boolean` | Run across all workspaces |
| `--format` | `"json"`, `"plain"`, default: `"plain"` | Choose how the results will be returned. |
| `--workspaces, -w` | `array` | List of Workspace names to run against |

---

#### `one change snapshot`

Aliases: `one change snap`
Expand Down
5 changes: 5 additions & 0 deletions modules/onerepo/.changes/002-curvy-donkeys-cut.md
@@ -0,0 +1,5 @@
---
type: minor
---

Adds `one change show` to help preview changes in Workspaces"
20 changes: 20 additions & 0 deletions modules/onerepo/src/core/changes/__tests__/show.test.ts
@@ -0,0 +1,20 @@
import path from 'node:path';
import { getCommand } from '@onerepo/test-cli';
import { getGraph } from '@onerepo/graph';
import * as show from '../show';

const graph = getGraph(path.join(__dirname, '__fixtures__/with-entries'));
const { run } = getCommand(show, graph);

describe('show changes', () => {
test('adds change files', async () => {
vi.spyOn(process.stdout, 'write').mockReturnValue(true);
await run('-w tacos --format json');

expect(process.stdout.write).toHaveBeenCalledWith(
expect.stringContaining(
'{"cheese":{"type":"minor","version":"2.1.0","entries":[{"type":"minor","content":"A minor change\\n"',
),
);
});
});
3 changes: 3 additions & 0 deletions modules/onerepo/src/core/changes/index.ts
Expand Up @@ -2,6 +2,7 @@ import type { Plugin } from '../../types';
import * as Add from './add';
import * as Migrate from './migrate';
import * as Publish from './publish';
import * as Show from './show';
import * as Snapshot from './snapshot';
import * as Verify from './verify';
import * as Version from './version';
Expand All @@ -13,6 +14,7 @@ export const changes: Plugin = function codeowners(config) {
const add = visitor(Add);
const migrate = visitor(Migrate);
const publish = visitor(Publish);
const show = visitor(Show);
const snapshot = visitor(Snapshot);
const verify = visitor(Verify);
const version = visitor(Version);
Expand Down Expand Up @@ -40,6 +42,7 @@ export const changes: Plugin = function codeowners(config) {
migrate.handler,
)
.command(publish.command, publish.description, publish.builder, publish.handler)
.command(show.command, show.description, show.builder, show.handler)
.command(snapshot.command, snapshot.description, snapshot.builder, snapshot.handler)
.command(verify.command, verify.description, verify.builder, verify.handler)
.command(version.command, version.description, version.builder, version.handler)
Expand Down
72 changes: 72 additions & 0 deletions modules/onerepo/src/core/changes/show.ts
@@ -0,0 +1,72 @@
import cliui from 'cliui';
import pc from 'picocolors';
import type { WithWorkspaces } from '@onerepo/builders';
import { withWorkspaces } from '@onerepo/builders';
import type { Workspace } from '@onerepo/graph';
import type { Builder, Handler } from '@onerepo/yargs';
import type { VersionPlan } from './utils';
import { buildChangelog, getVersionable } from './utils';

export const command = ['show'];

export const description = 'Preview the next versions and changelogs for Workspaces.';

type Argv = WithWorkspaces & {
format: 'json' | 'plain';
};

export const builder: Builder<Argv> = (yargs) =>
withWorkspaces(yargs.usage(`$0 ${command[0]}`)).option('format', {
type: 'string',
choices: ['json', 'plain'] as const,
default: 'plain' as const,
description: 'Choose how the results will be returned.',
});

export const handler: Handler<Argv> = async (argv, { getWorkspaces, graph }) => {
const { format } = argv;

const workspaces = await getWorkspaces();

const versionPlans = await getVersionable(graph);

const deps = graph.dependencies(workspaces, true);

const toVersion: Array<Workspace> = Array.from(versionPlans.keys()).filter((ws) => deps.includes(ws));

if (format === 'json') {
process.stdout.write(
JSON.stringify(
toVersion.reduce(
(memo, ws) => {
memo[ws.name] = versionPlans.get(ws)!;
return memo;
},
{} as Record<string, VersionPlan>,
),
) + '\n',
);
return;
}

const ui = cliui({ width: Math.min(160, process.stdout.columns) });
for (const ws of toVersion) {
const plan = versionPlans.get(ws)!;
ui.div(
{ text: pc.cyan(pc.bold(pc.underline(ws.name))), padding: [1, 0, 0, 0] },
{ text: `${ws.version} ${pc.dim('→')} ${pc.bold(plan.version)}`, padding: [1, 0, 0, 0] },
);

const deps = graph.dependencies(ws);
const depPlans = new Map<Workspace, VersionPlan>();
for (const dep of deps) {
const depPlan = versionPlans.get(dep);
if (depPlan) {
depPlans.set(dep, depPlan);
}
}

ui.div({ text: await buildChangelog(plan, depPlans), padding: [0, 2, 0, 2] });
}
process.stdout.write(ui.toString() + '\n');
};
2 changes: 1 addition & 1 deletion modules/onerepo/src/core/changes/utils/changelog.ts
Expand Up @@ -7,7 +7,7 @@ import type { ChangeEntry, ReleaseType, VersionPlan } from './get-versionable';

type Formatting = Required<Required<RootConfig>['changes']>['formatting'];

async function buildChangelog(
export async function buildChangelog(
plan: VersionPlan,
dependencies: Map<Workspace, VersionPlan>,
formatting: Formatting = {},
Expand Down
11 changes: 7 additions & 4 deletions modules/onerepo/src/core/changes/utils/get-versionable.ts
Expand Up @@ -118,10 +118,13 @@ async function getVersionPlan(
runDry: true,
});

const logs = rawLogs.split('\u0000').map((str) => {
const [ref, subject] = str.split('\u0003\u0002');
return { ref, subject };
});
const logs = rawLogs
.split('\u0000')
.map((str) => {
const [ref, subject] = str.split('\u0003\u0002');
return { ref, subject };
})
.filter(({ subject }) => !!subject);

const version = options.snapshot
? `0.0.0-${options.identifier}-${options.snapshot}`
Expand Down

0 comments on commit 15bff1b

Please sign in to comment.