Skip to content

Commit b797bba

Browse files
refactor(core): Workspace commands + passthrough (#591)
**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
1 parent 5ee9c67 commit b797bba

File tree

33 files changed

+657
-242
lines changed

33 files changed

+657
-242
lines changed

.changeset/dry-days-beg.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
'onerepo': minor
3+
---
4+
5+
Workspace-specific commands will require `workspace` or `ws` before the workspace name when running.
6+
7+
**Before:**
8+
9+
```sh
10+
one docs start
11+
```
12+
13+
**After:**
14+
15+
```sh
16+
one workspace docs start
17+
```

.changeset/modern-vans-try.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'onerepo': minor
3+
---
4+
5+
Added `passthrough` command ability to Workspace configurations. Use with caution.

docs/.astro/types.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,13 @@ declare module 'astro:content' {
409409
collection: "docs";
410410
data: InferEntrySchema<"docs">
411411
} & { render(): Render[".mdx"] };
412+
"core/workspace.mdx": {
413+
id: "core/workspace.mdx";
414+
slug: "core/workspace";
415+
body: string;
416+
collection: "docs";
417+
data: InferEntrySchema<"docs">
418+
} & { render(): Render[".mdx"] };
412419
"docs/commands.mdx": {
413420
id: "docs/commands.mdx";
414421
slug: "docs/commands";

docs/astro.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default defineConfig({
6565
sidebar: [
6666
{ label: 'Core concepts', autogenerate: { directory: 'concepts' } },
6767
{ label: 'Documentation', autogenerate: { directory: 'docs' } },
68-
{ label: 'Core utilities', autogenerate: { directory: 'core' } },
68+
{ label: 'Core commands', autogenerate: { directory: 'core' } },
6969
{ label: 'Plugins', autogenerate: { directory: 'plugins' } },
7070
{ label: 'Project', autogenerate: { directory: 'project' } },
7171
{

docs/commands/astro.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.

docs/commands/start.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.

docs/onerepo.config.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
import type { Config } from 'onerepo';
22

33
export default {
4+
commands: {
5+
passthrough: {
6+
start: { description: 'Start the Astro dev server.', command: 'astro dev --host' },
7+
build: { description: 'Build the documentation site for production.', command: 'astro build' },
8+
check: { description: 'Check Astro pages for errors.', command: 'astro check' },
9+
astro: { description: 'Run Astro directly.' },
10+
},
11+
},
412
tasks: {
513
'pre-commit': {
614
serial: [
7-
{ match: '**/*.{astro}', cmd: '$0 ws docs astro -- check' },
15+
{ match: '**/*.{astro}', cmd: '$0 ws docs check' },
816
{ match: '../modules/**/*.ts', cmd: '$0 ws docs typedoc --add' },
917
{ match: '../**/*', cmd: '$0 ws docs collect-content -w ${workspaces} --add' },
1018
{ match: '../**/CHANGELOG.md', cmd: '$0 ws docs pull-changelogs --add' },
1119
],
1220
},
1321
'pre-merge': {
14-
serial: [{ match: '**/*.{astro}', cmd: '$0 ws docs astro -- check' }],
22+
serial: [{ match: '**/*.{astro}', cmd: '$0 ws docs check' }],
1523
},
1624
build: {
17-
serial: ['$0 ws docs astro -- build'],
25+
serial: ['$0 ws docs build'],
1826
},
1927
},
2028
} satisfies Config;

docs/src/content/docs/api/index.md

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ oneRepo is in currently in public beta. Some APIs may not be specifically necess
88
:::
99

1010
<!-- start-onerepo-sentinel -->
11-
<!-- @generated SignedSource<<80605613200b1f52b9703314f7b8ff85>> -->
11+
<!-- @generated SignedSource<<edaa1c35e634eaa62235c1d001defd76>> -->
1212

1313
## Namespaces
1414

@@ -926,6 +926,12 @@ serial?: Task[];
926926
```ts
927927
type WorkspaceConfig<CustomLifecycles>: {
928928
codeowners: Record<string, string[]>;
929+
commands: {
930+
passthrough: Record<string, {
931+
command: string;
932+
description: string;
933+
}>;
934+
};
929935
meta: Record<string, unknown>;
930936
tasks: TaskConfig<CustomLifecycles>;
931937
};
@@ -959,6 +965,43 @@ export default {
959965
};
960966
```
961967

968+
##### commands?
969+
970+
```ts
971+
commands?: {
972+
passthrough: Record<string, {
973+
command: string;
974+
description: string;
975+
}>;
976+
};
977+
```
978+
979+
Configuration for custom commands. To configure the commands directory, see [`RootConfig` `commands.directory`](#commandsdirectory).
980+
981+
##### commands.passthrough
982+
983+
```ts
984+
commands.passthrough: Record<string, {
985+
command: string;
986+
description: string;
987+
}>;
988+
```
989+
990+
**Default:** `{}`
991+
992+
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.
993+
994+
```ts title="onerepo.config.ts"
995+
export default {
996+
commands: {
997+
passthrough: {
998+
astro: { description: 'Run Astro commands directly.' },
999+
start: { description: 'Run the Astro dev server.', command: 'astro dev --port=8000' },
1000+
},
1001+
},
1002+
};
1003+
```
1004+
9621005
##### meta?
9631006

9641007
```ts
@@ -1312,12 +1355,12 @@ get codeowners(): Required<Record<string, string[]>>
13121355
##### config
13131356

13141357
```ts
1315-
get config(): WorkspaceConfig
1358+
get config(): Required<WorkspaceConfig | RootConfig>
13161359
```
13171360

13181361
Get the workspace's configuration
13191362

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

13231366
##### dependencies
@@ -2641,7 +2684,7 @@ versions: string[];
26412684
### Plugin
26422685
26432686
```ts
2644-
type Plugin: PluginObject | (config) => PluginObject;
2687+
type Plugin: PluginObject | (config, graph) => PluginObject;
26452688
```
26462689
26472690
**Source:** [modules/onerepo/src/types/plugin.ts](https://github.com/paularmstrong/onerepo/blob/main/modules/onerepo/src/types/plugin.ts)
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
---
2+
title: Workspace commands
3+
description: Run commands in Workspaces.
4+
meta:
5+
stability: stable
6+
---
7+
8+
import FileTree from '../../../components/FileTree.astro';
9+
10+
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.
11+
12+
## Custom commands
13+
14+
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.
15+
16+
By default, the `commands.directory` is set to `'commands'`.
17+
18+
```ts title="onerepo.config.ts"
19+
import type { Config } from 'onerepo';
20+
21+
export default {
22+
commands: {
23+
directory: 'commands',
24+
},
25+
} satisfies Config;
26+
```
27+
28+
This setting will automatically enable each Workspace to add command files:
29+
30+
<FileTree>
31+
32+
- apps
33+
- public-app
34+
- commands/
35+
- start.ts # one ws public-app start
36+
- build.ts
37+
- private-app
38+
- commands/
39+
- start.ts # one ws private-app start
40+
- build.ts
41+
42+
</FileTree>
43+
44+
And in turn, our custom commands will be exposed on the `one workspace` (or `one ws` alias, for short) command:
45+
46+
```sh title="Run public-app commands."
47+
# Run the `start` command
48+
one workspace public-app start
49+
50+
# Run the `build` command
51+
one workspace public-app build
52+
```
53+
54+
```sh title="Build private-app commands."
55+
one workspace private-app build
56+
# ↑ Equivalent to ↓
57+
one ws private-app build
58+
```
59+
60+
Read the [writing commands documentation](/docs/commands/) for a tutorial and in-depth information on the structure, shape, and strategies for commands.
61+
62+
## Passthrough commands
63+
64+
Alternatively, for quick access to third-party commands that don't require extra configuration, we can configure _passthrough_ commands in Workspace configuration files:
65+
66+
```ts title="apps/public-app/onerepo.config.ts"
67+
export default {
68+
commands: {
69+
passthrough: {
70+
start: { command: 'astro dev', description: 'Start the Astro dev server.' },
71+
build: { command: 'astro build', description: 'Build the app using Astro.' },
72+
},
73+
},
74+
} satisfies WorkspaceConfig;
75+
```
76+
77+
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.
78+
79+
:::danger
80+
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.
81+
:::
82+
83+
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 …`:
84+
85+
```sh title="Run the Astro dev server."
86+
one workspace public-app start
87+
# ↑ Equivalent to ↓
88+
one ws public-app start
89+
```
90+
91+
```sh title="Build the app using Astro."
92+
one workspace public-app build
93+
# ↑ Equivalent to ↓
94+
one ws public-app build
95+
```
96+
97+
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 (`--`):
98+
99+
```sh title="Pass arguments to Astro"
100+
one workspace public app start -- --port=8000 --open
101+
```
102+
103+
## Command usage
104+
105+
{/* start-auto-generated-from-cli-workspace */}
106+
{/* @generated SignedSource<<88b5edb9556a0953b6fc2f856d4b6c5d>> */}
107+
108+
### `one workspace`
109+
110+
Aliases: `one ws`
111+
112+
Run commands within individual Workspaces.
113+
114+
```sh
115+
one workspace <workspace-name> <command...> [options...] -- [passthrough...]
116+
```
117+
118+
This enables running both custom commands as defined via the `commands.directory` configuration option within each Workspace as well as `commands.passthrough` aliases.
119+
120+
Arguments for passthrough commands meant for the underlying command must be sent after `--`.
121+
122+
| Positional | Type | Description |
123+
| ---------------- | -------- | --------------------------------- |
124+
| `command` | `string` | Command to run. |
125+
| `workspace-name` | `string` | The name or alias of a Workspace. |
126+
127+
{/* end-auto-generated-from-cli-workspace */}

0 commit comments

Comments
 (0)