Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/tmp
node_modules
coverage
oclif.manifest.json
259 changes: 259 additions & 0 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# Developing Flarum CLI

This guide covers how to set up and work with the Flarum CLI codebase locally.

## Prerequisites

- Node.js >= 18.0.0
- Yarn package manager

## Initial Setup

1. **Clone the repository** (if you haven't already)

2. **Install dependencies:**

```bash
yarn install
```

3. **Build the TypeScript source:**

```bash
yarn prepack
```

This command:

- Compiles TypeScript from `src/` to `lib/`
- Generates the oclif manifest
- Updates the README with command documentation

## Running Locally

You have several options for running the CLI during development:

### Option 1: Direct execution via bin/run

```bash
./bin/run [command]
```

Example:

```bash
./bin/run --help
./bin/run init
./bin/run make model
```

### Option 2: Create a development alias (recommended)

Add an alias to your shell configuration file without affecting existing installations:

**For zsh** (add to `~/.zshrc`):

```bash
alias fl-dev='/path/to/cli/bin/run'
```

**For bash** (add to `~/.bashrc` or `~/.bash_profile`):

```bash
alias fl-dev='/path/to/cli/bin/run'
```

After adding the alias, reload your shell:

```bash
source ~/.zshrc # or source ~/.bashrc
```

Then use:

```bash
fl-dev [command]
```

This allows you to keep your existing `fl1`, `fl2`, etc. aliases intact while having a dedicated `fl-dev` for local development.

### Option 3: Link globally for development

```bash
yarn link
```

After linking, you can use any of these commands:

- `flarum-cli [command]`
- `fl [command]`
- `fl2 [command]`

**Warning:** This will override any globally installed version of `@flarum/cli`.

## Development Workflow

### Making Changes

1. **Edit TypeScript source files** in `src/`
2. **Rebuild the project:**
```bash
yarn prepack
```
3. **Test your changes:**
```bash
./bin/run [command]
```

### Testing

Run the test suite:

```bash
yarn test
```

This will:

- Run Jest tests
- Check code formatting with Prettier
- Lint code with ESLint
- Perform a TypeScript dry-run build

### Code Formatting

Format code automatically:

```bash
yarn format
```

This runs ESLint with auto-fix and Prettier.

## Project Structure

```
.
├── bin/ # Executable entry points
│ └── run # Main CLI entry point
├── src/ # TypeScript source code
│ ├── commands/ # CLI command definitions
│ ├── steps/ # Reusable step implementations
│ ├── boilersmith/ # Scaffolding system
│ └── base-command.ts # Base command class
├── lib/ # Compiled JavaScript (gitignored)
├── test/ # Test files
├── boilerplate/ # Scaffolding templates
├── stubs/ # Code generation templates
├── php-subsystem/ # PHP parser for extend.php
└── package.json
```

## Architecture Overview

### Technology Stack

- **oclif**: CLI framework
- **TypeScript**: Primary language
- **PHP subsystem**: Uses `nikic/php-parser` for PHP code manipulation
- **mem-fs**: In-memory filesystem for atomic operations

### Key Concepts

**Commands** (in `src/commands/`)

- User-facing CLI commands
- Built on oclif framework
- Orchestrate step execution

**Steps** (in `src/steps/`)

- Granular, reusable operations
- Modify in-memory filesystem
- Can be composed atomically
- Support parameter sharing between steps

**Step Manager**

- Fluent API for chaining steps
- Handles optional steps
- Manages parameter passing between steps
- Supports atomic groups for transactional changes

**Scaffolding System** (`src/boilersmith/`)

- Manages extension infrastructure modules
- Supports initialization and updates
- Module-based file and config ownership

## Debugging

### Running with Node Inspector

```bash
node --inspect ./bin/run [command]
```

### Verbose Output

Most commands support flags for additional output. Check command help:

```bash
./bin/run [command] --help
```

## Common Tasks

### Adding a New Command

1. Create command file in `src/commands/`
2. Extend from `BaseCommand` class
3. Define steps using Step Manager
4. Rebuild with `yarn prepack`
5. Test with `./bin/run [your-command]`

### Adding a New Step

1. Create step class in appropriate `src/steps/` subdirectory
2. Implement required methods (`run`, `getExposedParams`, etc.)
3. Add unit tests
4. Use step in command's `steps()` method

### Updating Boilerplate Templates

1. Edit files in `boilerplate/skeleton/extension/`
2. Update module definitions in scaffolding system
3. Test with `./bin/run init` or `./bin/run infra`

## Troubleshooting

### "Command not found" after changes

- Ensure you've run `yarn prepack` to rebuild
- Check that `lib/` directory exists and contains compiled code

### TypeScript errors

- Run `yarn posttest` to see type checking output
- Ensure `tsconfig.json` includes your new files

### Tests failing

- Run `yarn test` to see full output
- Check that step unit tests match your changes

## Contributing

When making changes:

1. Follow existing code patterns
2. Add unit tests for new steps and functionality
3. Update documentation as needed
4. Run `yarn format` before committing
5. Ensure `yarn test` passes

## Additional Resources

- [oclif Documentation](https://oclif.io/)
- [README.md](README.md) - User-facing documentation
- Main README "For Maintainers" section - Architecture deep-dive
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ $ npm install -g @flarum/cli
$ flarum-cli COMMAND
running command...
$ flarum-cli (-v|--version|version)
@flarum/cli/3.0.11 linux-x64 node-v18.19.1
@flarum/cli/3.0.11-dev darwin-arm64 node-v25.1.0
$ flarum-cli --help [COMMAND]
USAGE
$ flarum-cli COMMAND
Expand Down
Binary file added bin/libgit2.1.5.dylib
Binary file not shown.
Binary file added bin/splitsh-lite-darwin-arm64
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@flarum/cli",
"description": "A CLI for developing Flarum extensions",
"version": "3.0.11",
"version": "3.0.12-dev",
"author": "Flarum Team",
"flarum": "2.x",
"bin": {
Expand Down
9 changes: 8 additions & 1 deletion src/steps/monorepo/split.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export class MonorepoSplit implements Step<FlarumProviders> {

async run(fs: Store, paths: Paths, io: IO, _providers: FlarumProviders): Promise<Store> {
const platform = process.platform;
const arch = process.arch;

if (platform !== 'linux' && platform !== 'darwin') {
io.error(`Your platform, "${platform}", is not supported. Split can only be run on linux and mac`, true);
return fs;
Expand All @@ -74,7 +76,12 @@ export class MonorepoSplit implements Step<FlarumProviders> {
return fs;
}

const splitExec = resolve(__dirname, `../../../bin/splitsh-lite-${platform}`);
// Select the appropriate binary based on platform and architecture
let splitExec: string;
splitExec =
platform === 'darwin' && arch === 'arm64'
? resolve(__dirname, `../../../bin/splitsh-lite-darwin-arm64`)
: resolve(__dirname, `../../../bin/splitsh-lite-${platform}`);

const target = paths.requestedDir() ?? paths.package();

Expand Down
4 changes: 2 additions & 2 deletions src/steps/upgrade/twopointoh/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ export default class Dependencies extends BaseUpgradeStep {
'flarum-webpack-config': '^3.0.0',
'flarum-tsconfig': '^2.0.0',
'@flarum/jest-config': '^2.0.0',
'webpack': "^5.65.0",
'webpack-cli': "^4.9.1",
webpack: '^5.65.0',
'webpack-cli': '^4.9.1',
};

const dependencies = advanced.dependencies || advanced.devDependencies;
Expand Down