Skip to content

Commit

Permalink
refactor(core): Workspace commands + passthrough (#591)
Browse files Browse the repository at this point in the history
**Problem:**

Looking at #554 and #555, there are too many unknowns with passing
through to commands like vite and astro (and webpack, next, etc, for
that matter). It doesn't seem sustainable to attempt to curate plugins
to every single npx command available. Nor does it seem helpful for
users of oneRepo to leave them to need to write the entire passthrough
on their own.

**Solution:**

Passthrough commands. Discussion in #590

**Related issues:**

Fixes #554
Fixes #555

**Checklist:**

- [x] Added or updated tests
- [x] Added or updated documentation
- [x] Ensured the pre-commit hooks ran successfully
  • Loading branch information
paularmstrong authored Feb 1, 2024
1 parent 5ee9c67 commit b797bba
Show file tree
Hide file tree
Showing 33 changed files with 657 additions and 242 deletions.
17 changes: 17 additions & 0 deletions .changeset/dry-days-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
'onerepo': minor
---

Workspace-specific commands will require `workspace` or `ws` before the workspace name when running.

**Before:**

```sh
one docs start
```

**After:**

```sh
one workspace docs start
```
5 changes: 5 additions & 0 deletions .changeset/modern-vans-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'onerepo': minor
---

Added `passthrough` command ability to Workspace configurations. Use with caution.
7 changes: 7 additions & 0 deletions docs/.astro/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,13 @@ declare module 'astro:content' {
collection: "docs";
data: InferEntrySchema<"docs">
} & { render(): Render[".mdx"] };
"core/workspace.mdx": {
id: "core/workspace.mdx";
slug: "core/workspace";
body: string;
collection: "docs";
data: InferEntrySchema<"docs">
} & { render(): Render[".mdx"] };
"docs/commands.mdx": {
id: "docs/commands.mdx";
slug: "docs/commands";
Expand Down
2 changes: 1 addition & 1 deletion docs/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default defineConfig({
sidebar: [
{ label: 'Core concepts', autogenerate: { directory: 'concepts' } },
{ label: 'Documentation', autogenerate: { directory: 'docs' } },
{ label: 'Core utilities', autogenerate: { directory: 'core' } },
{ label: 'Core commands', autogenerate: { directory: 'core' } },
{ label: 'Plugins', autogenerate: { directory: 'plugins' } },
{ label: 'Project', autogenerate: { directory: 'project' } },
{
Expand Down
37 changes: 0 additions & 37 deletions docs/commands/astro.ts

This file was deleted.

33 changes: 0 additions & 33 deletions docs/commands/start.ts

This file was deleted.

14 changes: 11 additions & 3 deletions docs/onerepo.config.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import type { Config } from 'onerepo';

export default {
commands: {
passthrough: {
start: { description: 'Start the Astro dev server.', command: 'astro dev --host' },
build: { description: 'Build the documentation site for production.', command: 'astro build' },
check: { description: 'Check Astro pages for errors.', command: 'astro check' },
astro: { description: 'Run Astro directly.' },
},
},
tasks: {
'pre-commit': {
serial: [
{ match: '**/*.{astro}', cmd: '$0 ws docs astro -- check' },
{ match: '**/*.{astro}', cmd: '$0 ws docs check' },
{ match: '../modules/**/*.ts', cmd: '$0 ws docs typedoc --add' },
{ match: '../**/*', cmd: '$0 ws docs collect-content -w ${workspaces} --add' },
{ match: '../**/CHANGELOG.md', cmd: '$0 ws docs pull-changelogs --add' },
],
},
'pre-merge': {
serial: [{ match: '**/*.{astro}', cmd: '$0 ws docs astro -- check' }],
serial: [{ match: '**/*.{astro}', cmd: '$0 ws docs check' }],
},
build: {
serial: ['$0 ws docs astro -- build'],
serial: ['$0 ws docs build'],
},
},
} satisfies Config;
51 changes: 47 additions & 4 deletions docs/src/content/docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ oneRepo is in currently in public beta. Some APIs may not be specifically necess
:::

<!-- start-onerepo-sentinel -->
<!-- @generated SignedSource<<80605613200b1f52b9703314f7b8ff85>> -->
<!-- @generated SignedSource<<edaa1c35e634eaa62235c1d001defd76>> -->

## Namespaces

Expand Down Expand Up @@ -926,6 +926,12 @@ serial?: Task[];
```ts
type WorkspaceConfig<CustomLifecycles>: {
codeowners: Record<string, string[]>;
commands: {
passthrough: Record<string, {
command: string;
description: string;
}>;
};
meta: Record<string, unknown>;
tasks: TaskConfig<CustomLifecycles>;
};
Expand Down Expand Up @@ -959,6 +965,43 @@ export default {
};
```

##### commands?

```ts
commands?: {
passthrough: Record<string, {
command: string;
description: string;
}>;
};
```

Configuration for custom commands. To configure the commands directory, see [`RootConfig` `commands.directory`](#commandsdirectory).

##### commands.passthrough

```ts
commands.passthrough: Record<string, {
command: string;
description: string;
}>;
```

**Default:** `{}`

Enable commands from installed dependencies. Similar to running `npx <command>`, but pulled into the oneRepo CLI and able to be limited by workspace. Passthrough commands _must_ have helpful descriptions.

```ts title="onerepo.config.ts"
export default {
commands: {
passthrough: {
astro: { description: 'Run Astro commands directly.' },
start: { description: 'Run the Astro dev server.', command: 'astro dev --port=8000' },
},
},
};
```

##### meta?

```ts
Expand Down Expand Up @@ -1312,12 +1355,12 @@ get codeowners(): Required<Record<string, string[]>>
##### config

```ts
get config(): WorkspaceConfig
get config(): Required<WorkspaceConfig | RootConfig>
```

Get the workspace's configuration

**Returns:** [`WorkspaceConfig`](#workspaceconfigcustomlifecycles)
**Returns:** `Required`\<[`WorkspaceConfig`](#workspaceconfigcustomlifecycles) \| [`RootConfig`](#rootconfigcustomlifecycles)\>
**Source:** [modules/graph/src/Workspace.ts](https://github.com/paularmstrong/onerepo/blob/main/modules/graph/src/Workspace.ts)

##### dependencies
Expand Down Expand Up @@ -2641,7 +2684,7 @@ versions: string[];
### Plugin
```ts
type Plugin: PluginObject | (config) => PluginObject;
type Plugin: PluginObject | (config, graph) => PluginObject;
```
**Source:** [modules/onerepo/src/types/plugin.ts](https://github.com/paularmstrong/onerepo/blob/main/modules/onerepo/src/types/plugin.ts)
Expand Down
127 changes: 127 additions & 0 deletions docs/src/content/docs/core/workspace.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
title: Workspace commands
description: Run commands in Workspaces.
meta:
stability: stable
---

import FileTree from '../../../components/FileTree.astro';

Your monorepo's Workspaces may end up having unique needs that differ from other Workspaces. When this occurs, you may want to have commands that are specific to an individual Workspace. There are two ways to configure oneRepo to enable Workspace-specific commands.

## Custom commands

Workspaces can have custom commands that work identically to commands at the root of your repository. The [`RootConfig.commands.directory`](/docs/config/#commandsdirectory) configuration value enables a directory within _each_ Workspace of your application, if present, to contain command files that will automatically be included in the `one` CLI when invoked.

By default, the `commands.directory` is set to `'commands'`.

```ts title="onerepo.config.ts"
import type { Config } from 'onerepo';

export default {
commands: {
directory: 'commands',
},
} satisfies Config;
```

This setting will automatically enable each Workspace to add command files:

<FileTree>

- apps
- public-app
- commands/
- start.ts # one ws public-app start
- build.ts
- private-app
- commands/
- start.ts # one ws private-app start
- build.ts

</FileTree>

And in turn, our custom commands will be exposed on the `one workspace` (or `one ws` alias, for short) command:

```sh title="Run public-app commands."
# Run the `start` command
one workspace public-app start

# Run the `build` command
one workspace public-app build
```

```sh title="Build private-app commands."
one workspace private-app build
# ↑ Equivalent to ↓
one ws private-app build
```

Read the [writing commands documentation](/docs/commands/) for a tutorial and in-depth information on the structure, shape, and strategies for commands.

## Passthrough commands

Alternatively, for quick access to third-party commands that don't require extra configuration, we can configure _passthrough_ commands in Workspace configuration files:

```ts title="apps/public-app/onerepo.config.ts"
export default {
commands: {
passthrough: {
start: { command: 'astro dev', description: 'Start the Astro dev server.' },
build: { command: 'astro build', description: 'Build the app using Astro.' },
},
},
} satisfies WorkspaceConfig;
```

Some third-party spackages expose executables for running servers and quick helpers that use configuration files instead of command-line flags, like [Astro](https://astro.build) and [Vite](https://vitejs.dev). These types of commands are great candidates for passthroughs.

:::danger
This configuration is a shortcut for quick one-offs with little to no extra options necessary. Avoid over-using this configuration to avoid [script overload](/concepts/why-onerepo/#script-overload) pitfalls.
:::

By enabling the passthrough using the above configuration for `public-app`, we add two commands to the Workspace: `start` and `build` and can be called with either form of the `workspace` command using `one workspace …` or the alias `one ws …`:

```sh title="Run the Astro dev server."
one workspace public-app start
# ↑ Equivalent to ↓
one ws public-app start
```

```sh title="Build the app using Astro."
one workspace public-app build
# ↑ Equivalent to ↓
one ws public-app build
```

If you need a little bit more and want to pass arguments through to the underlying command (in this case `astro …`), include any extra argument flags after the CLI parser stop point (`--`):

```sh title="Pass arguments to Astro"
one workspace public app start -- --port=8000 --open
```

## Command usage

{/* start-auto-generated-from-cli-workspace */}
{/* @generated SignedSource<<88b5edb9556a0953b6fc2f856d4b6c5d>> */}

### `one workspace`

Aliases: `one ws`

Run commands within individual Workspaces.

```sh
one workspace <workspace-name> <command...> [options...] -- [passthrough...]
```

This enables running both custom commands as defined via the `commands.directory` configuration option within each Workspace as well as `commands.passthrough` aliases.

Arguments for passthrough commands meant for the underlying command must be sent after `--`.

| Positional | Type | Description |
| ---------------- | -------- | --------------------------------- |
| `command` | `string` | Command to run. |
| `workspace-name` | `string` | The name or alias of a Workspace. |

{/* end-auto-generated-from-cli-workspace */}
Loading

0 comments on commit b797bba

Please sign in to comment.