Skip to content

Commit 7241904

Browse files
committed
refactor(plugins): remove metadata export requirement
- Plugins now only need to export commands object - Remove metadata validation from listPlugins - Simplify plugin detection to check for c8ctl-plugin.js/ts file - Update all tests to remove metadata checks - Update documentation and examples This simplifies plugin development by removing unnecessary boilerplate.
1 parent 87ecf13 commit 7241904

File tree

7 files changed

+11
-69
lines changed

7 files changed

+11
-69
lines changed

EXAMPLES.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ c8 list plugins
386386

387387
**Plugin Development:**
388388

389-
Plugins must be regular Node.js modules with a `c8ctl-plugin.js` or `c8ctl-plugin.ts` file in the root directory. The plugin name must be in the package.json metadata. The `c8ctl` runtime object provides environment information:
389+
Plugins must be regular Node.js modules with a `c8ctl-plugin.js` or `c8ctl-plugin.ts` file in the root directory. The plugin file must export a `commands` object. The `c8ctl` runtime object provides environment information:
390390

391391
```typescript
392392
// c8ctl-plugin.ts
@@ -399,12 +399,6 @@ export const commands = {
399399
// Custom analysis logic here
400400
}
401401
};
402-
403-
export const metadata = {
404-
name: 'my-plugin',
405-
version: '1.0.0',
406-
description: 'My custom c8ctl plugin'
407-
};
408402
```
409403

410404
---

README.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ c8 list plugins
143143
**Plugin Requirements:**
144144
- Plugin packages must be regular Node.js modules
145145
- They must include a `c8ctl-plugin.js` or `c8ctl-plugin.ts` file in the root directory
146-
- The plugin name must be in the package.json metadata
147-
- The plugin file should export custom commands
146+
- The plugin file must export a `commands` object
148147
- Plugins are installed in `node_modules` like regular npm packages
149148
- The runtime object `c8ctl` provides environment information to plugins
150149

@@ -156,12 +155,6 @@ export const commands = {
156155
console.log('Analyzing...', args);
157156
}
158157
};
159-
160-
export const metadata = {
161-
name: 'my-plugin',
162-
version: '1.0.0',
163-
description: 'My custom c8ctl plugin'
164-
};
165158
```
166159

167160
### Resource Aliases

src/commands/plugins.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import { getLogger } from '../logger.ts';
66
import { execSync } from 'node:child_process';
7-
import { readFileSync } from 'node:fs';
7+
import { readFileSync, existsSync } from 'node:fs';
88
import { join } from 'node:path';
99

1010
/**
@@ -85,16 +85,13 @@ export function listPlugins(): void {
8585
for (const [name, version] of Object.entries(allDeps)) {
8686
try {
8787
// Try to resolve the package
88-
const packagePath = join(process.cwd(), 'node_modules', name, 'package.json');
89-
const pkgJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
88+
const packageDir = join(process.cwd(), 'node_modules', name);
9089

91-
// Check if package exports c8ctl-plugin.js or c8ctl-plugin.ts
92-
const hasPlugin = pkgJson.main === 'c8ctl-plugin.js' ||
93-
pkgJson.main === 'c8ctl-plugin.ts' ||
94-
pkgJson.exports?.['./c8ctl-plugin.js'] ||
95-
pkgJson.exports?.['./c8ctl-plugin.ts'];
90+
// Check if package has c8ctl-plugin.js or c8ctl-plugin.ts file in root
91+
const hasPluginFile = existsSync(join(packageDir, 'c8ctl-plugin.js')) ||
92+
existsSync(join(packageDir, 'c8ctl-plugin.ts'));
9693

97-
if (hasPlugin) {
94+
if (hasPluginFile) {
9895
plugins.push({
9996
Name: name,
10097
Version: version as string,

tests/fixtures/plugins/README.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ TypeScript implementation demonstrating:
1010
- TypeScript type annotations
1111
- Access to c8ctl runtime object
1212
- Multiple command exports (analyze, validate)
13-
- Metadata export
1413

1514
**Usage in plugins:**
1615
```typescript
@@ -29,7 +28,6 @@ JavaScript implementation demonstrating:
2928
- Command with hyphens ('deploy-all')
3029
- Argument handling
3130
- Multiple commands (deploy-all, status, report)
32-
- Metadata with command list
3331

3432
**Usage in plugins:**
3533
```javascript
@@ -45,17 +43,14 @@ export const commands = {
4543
For a package to be recognized as a c8ctl plugin:
4644

4745
1. Must be a regular Node.js module with proper package.json
48-
2. Plugin name must be defined in package.json metadata
49-
3. Must have either `c8ctl-plugin.js` or `c8ctl-plugin.ts` file in root directory
50-
4. Must export a `commands` object with async functions
51-
5. Should export `metadata` with name, version, description
52-
6. Can access c8ctl runtime via `import { c8ctl } from 'c8ctl/runtime'`
46+
2. Must have either `c8ctl-plugin.js` or `c8ctl-plugin.ts` file in root directory
47+
3. Must export a `commands` object with async functions
48+
4. Can access c8ctl runtime via `import { c8ctl } from 'c8ctl/runtime'`
5349

5450
## Testing
5551

5652
These fixtures are used by `tests/unit/plugins.test.ts` to verify:
5753
- Plugin structure validation
5854
- Command export format
59-
- Metadata format
6055
- Dynamic import capability
6156
- Runtime object access

tests/fixtures/plugins/c8ctl-plugin.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,3 @@ export const commands = {
3737
console.log(`Output format: ${format}`);
3838
},
3939
};
40-
41-
export const metadata = {
42-
name: 'sample-js-plugin',
43-
version: '2.0.0',
44-
description: 'A sample JavaScript plugin for c8ctl',
45-
commands: ['deploy-all', 'status', 'report'],
46-
};

tests/fixtures/plugins/c8ctl-plugin.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,3 @@ export const commands = {
2929
console.log(`Validating files: ${args.join(', ')}`);
3030
},
3131
};
32-
33-
export const metadata = {
34-
name: 'sample-ts-plugin',
35-
version: '1.0.0',
36-
description: 'A sample TypeScript plugin for c8ctl',
37-
};

tests/unit/plugins.test.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,6 @@ describe('Plugin Structure', () => {
5555
assert.ok(pluginContent.includes('c8ctl.env'), 'Plugin uses c8ctl.env');
5656
});
5757

58-
test('should have metadata export', async () => {
59-
const pluginPath = join(process.cwd(), 'tests/fixtures/plugins/c8ctl-plugin.ts');
60-
const pluginContent = readFileSync(pluginPath, 'utf-8');
61-
62-
// Verify plugin exports metadata
63-
assert.ok(pluginContent.includes('export const metadata'), 'Plugin exports metadata');
64-
assert.ok(pluginContent.includes('name:'), 'Metadata has name');
65-
assert.ok(pluginContent.includes('version:'), 'Metadata has version');
66-
assert.ok(pluginContent.includes('description:'), 'Metadata has description');
67-
});
68-
6958
test('should be valid TypeScript syntax', async () => {
7059
const pluginPath = join(process.cwd(), 'tests/fixtures/plugins/c8ctl-plugin.ts');
7160
const pluginContent = readFileSync(pluginPath, 'utf-8');
@@ -90,17 +79,6 @@ describe('Plugin Structure', () => {
9079
assert.ok(pluginContent.includes('report:'), 'Plugin has report command');
9180
});
9281

93-
test('should have metadata export', async () => {
94-
const pluginPath = join(process.cwd(), 'tests/fixtures/plugins/c8ctl-plugin.js');
95-
const pluginContent = readFileSync(pluginPath, 'utf-8');
96-
97-
// Verify plugin exports metadata
98-
assert.ok(pluginContent.includes('export const metadata'), 'Plugin exports metadata');
99-
assert.ok(pluginContent.includes('name:'), 'Metadata has name');
100-
assert.ok(pluginContent.includes('version:'), 'Metadata has version');
101-
assert.ok(pluginContent.includes('commands:'), 'Metadata lists commands');
102-
});
103-
10482
test('should use ES6 module syntax', async () => {
10583
const pluginPath = join(process.cwd(), 'tests/fixtures/plugins/c8ctl-plugin.js');
10684
const pluginContent = readFileSync(pluginPath, 'utf-8');
@@ -130,7 +108,6 @@ describe('Plugin Structure', () => {
130108
assert.ok(plugin.commands, 'Plugin has commands export');
131109
assert.ok(typeof plugin.commands.analyze === 'function', 'analyze is a function');
132110
assert.ok(typeof plugin.commands.validate === 'function', 'validate is a function');
133-
assert.ok(plugin.metadata, 'Plugin has metadata export');
134111
} catch (error) {
135112
// If import fails, just verify the file exists
136113
const pluginPath = join(process.cwd(), 'tests/fixtures/plugins/c8ctl-plugin.ts');
@@ -149,7 +126,6 @@ describe('Plugin Structure', () => {
149126
assert.ok(typeof plugin.commands['deploy-all'] === 'function', 'deploy-all is a function');
150127
assert.ok(typeof plugin.commands.status === 'function', 'status is a function');
151128
assert.ok(typeof plugin.commands.report === 'function', 'report is a function');
152-
assert.ok(plugin.metadata, 'Plugin has metadata export');
153129
} catch (error) {
154130
// If import fails, just verify the file exists
155131
const pluginPath = join(process.cwd(), 'tests/fixtures/plugins/c8ctl-plugin.js');

0 commit comments

Comments
 (0)