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
5 changes: 4 additions & 1 deletion .php-cs-fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

$finder = Finder::create()
->in(__DIR__ . '/src')
->append([__DIR__ . '/.php-cs-fixer.php']);
->append([
__DIR__ . '/bin/readme-examples-sync',
__DIR__ . '/.php-cs-fixer.php',
]);

return PhpCsFixerConfigFactory::create(TicketSwapRuleSet::create())->setFinder($finder);
79 changes: 57 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,75 @@
# README Examples Sync Hook
# README Examples Sync

A [CaptainHook](https://github.com/captainhook-git/captainhook) action that automatically syncs PHP code examples in your README.md with actual source files. This ensures your documentation always shows up-to-date, working code examples.
A PHP script that automatically syncs code examples in your README.md with actual source files.
This ensures your documentation always shows up-to-date, working code examples.

## Installation

```bash
composer require --dev ruudk/readme-examples-sync-hook
```

## Configuration

Add the hook to your `captainhook.json` configuration file in the `pre-commit` section:

```json
{
"pre-commit": {
"enabled": true,
"actions": [
{
"action": "\\Ruudk\\ReadmeExamplesSyncHook\\SyncReadmeExamples"
}
]
}
}
## Usage

Run the script from your project root:

```bash
vendor/bin/readme-examples-sync
```

### Git Hook Integration

The easiest way to automatically sync your README on commit is using [Lefthook](https://lefthook.dev):

1. Install Lefthook (if not already installed):
```bash
# macOS
brew install lefthook
```

2. Create a `lefthook.yml` file in your project root:
```yaml
pre-commit:
parallel: false
commands:
sync-readme-examples:
glob:
- "*.php"
- "*.md"
run: vendor/bin/readme-examples-sync
stage_fixed: true
```

3. Install the hooks:
```bash
lefthook install
```

That's it! Now your README will automatically sync whenever you commit changes to PHP or Markdown files.

#### Alternative: Manual Git Hook

If you prefer not to use Lefthook, you can manually create a `.git/hooks/pre-commit` file:

```bash
#!/bin/bash
vendor/bin/readme-examples-sync
```

Don't forget to make the hook executable:

```bash
chmod +x .git/hooks/pre-commit
```

## How It Works

This hook scans your README.md file for special HTML comments that mark code examples:
This script scans your README.md file for special HTML comments that mark code examples:

1. **Source code sync**: Updates code blocks marked with `<!-- source: ... -->` with the actual content from source files
2. **Output sync** (optional): When you add `<!-- output: ... -->` comments, the hook executes PHP files and captures their output to display results
2. **Output sync** (optional): When you add `<!-- output: ... -->` comments, the script executes PHP files and captures their output to display results

The hook automatically stages the updated README.md if changes are detected, ensuring your documentation stays in sync with your code.

## Usage
The script automatically stages the updated README.md if changes are detected (when run in a git repository), ensuring your documentation stays in sync with your code.

### Syncing Source Code

Expand Down
40 changes: 40 additions & 0 deletions bin/readme-examples-sync
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

// Find and include the Composer autoloader
$autoloadPaths = [
__DIR__ . '/../../../autoload.php', // When installed as a dependency
__DIR__ . '/../vendor/autoload.php', // When in the project root
];

$autoloaded = false;
foreach ($autoloadPaths as $file) {
if (file_exists($file)) {
require $file;
$autoloaded = true;

break;
}
}

if ( ! $autoloaded) {
fwrite(STDERR, "Error: Could not find Composer autoload file.\n");
exit(1);
}

use Ruudk\ReadmeExamplesSyncHook\SyncReadmeExamples;

// Determine the repository root (current directory by default)
$repositoryRoot = getcwd();

if ($repositoryRoot === false) {
fwrite(STDERR, "Error: Could not determine current directory.\n");
exit(1);
}

$syncer = new SyncReadmeExamples();
$exitCode = $syncer->sync($repositoryRoot);

exit($exitCode);
23 changes: 0 additions & 23 deletions captainhook.json

This file was deleted.

9 changes: 8 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"php": "^8.4"
},
"require-dev": {
"captainhook/captainhook": "^5.25",
"ergebnis/composer-normalize": "^2.48",
"friendsofphp/php-cs-fixer": "^3.85",
"phpstan/extension-installer": "^1.4",
Expand All @@ -29,10 +28,18 @@
"Ruudk\\ReadmeExamplesSyncHook\\": "src/"
}
},
"bin": [
"bin/readme-examples-sync"
],
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
"phpstan/extension-installer": true
}
},
"scripts": {
"post-install-cmd": [
"command -v lefthook >/dev/null 2>&1 && lefthook install || true"
]
}
}
Loading