feat: make incremental indexing configurable via CLI and workflow

Added full control over incremental indexing behavior:

**CLI Changes:**
- Added `--incremental` flag (default: true)
- Added `--full` flag to disable incremental mode
- Updated interactive prompt to ask about incremental mode

**Function Changes:**
- Updated buildIndex(force, mode, incremental) signature
- Added incremental parameter with default value true
- Conditional logic: if incremental=true, skip unchanged repos; else re-index all
- Added console logging to show incremental mode status

**Workflow Changes:**
- Added `incremental` input (boolean, default: true)
- Passes incremental setting to buildIndex via environment variable
- Defaults to true for scheduled (cron) runs

**Usage Examples:**
```bash
# CLI - incremental mode (default)
./awesome index

# CLI - force full re-index
./awesome index --full

# CLI - explicit incremental
./awesome index --incremental

# Workflow - incremental (default)
gh workflow run build-database.yml

# Workflow - full re-index
gh workflow run build-database.yml -f incremental=false
```

This makes incremental indexing opt-out instead of hardcoded, giving users full control over indexing behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
valknarness
2025-10-28 09:59:47 +01:00
parent 98ddac97e8
commit 99cf83330c
3 changed files with 51 additions and 12 deletions

View File

@@ -14,6 +14,11 @@ on:
options: options:
- full - full
- sample - sample
incremental:
description: 'Incremental mode (skip unchanged repos)'
required: false
default: true
type: boolean
permissions: permissions:
contents: read contents: read
@@ -49,6 +54,7 @@ jobs:
env: env:
CI: true CI: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INCREMENTAL: ${{ github.event.inputs.incremental || 'true' }}
run: | run: |
# Pass env vars! # Pass env vars!
CI=${CI:-false} CI=${CI:-false}
@@ -56,9 +62,15 @@ jobs:
START_TIME=$(date -u +"%Y-%m-%d %H:%M:%S UTC") START_TIME=$(date -u +"%Y-%m-%d %H:%M:%S UTC")
echo "start_time=$START_TIME" >> $GITHUB_OUTPUT echo "start_time=$START_TIME" >> $GITHUB_OUTPUT
# Determine index mode # Determine index mode and incremental setting
INDEX_MODE="${{ github.event.inputs.index_mode || 'full' }}" INDEX_MODE="${{ github.event.inputs.index_mode || 'full' }}"
INCREMENTAL="${{ github.event.inputs.incremental }}"
# Default to true if not specified (for scheduled runs)
if [ -z "$INCREMENTAL" ]; then
INCREMENTAL="true"
fi
echo "Index mode: $INDEX_MODE" echo "Index mode: $INDEX_MODE"
echo "Incremental: $INCREMENTAL"
# Build the index in non-interactive mode (350m timeout, job timeout is 360m) # Build the index in non-interactive mode (350m timeout, job timeout is 360m)
timeout 350m node -e " timeout 350m node -e "
@@ -79,8 +91,9 @@ jobs:
console.warn('⚠️ WARNING: No GitHub token found! Rate limit will be 60/hour instead of 5000/hour'); console.warn('⚠️ WARNING: No GitHub token found! Rate limit will be 60/hour instead of 5000/hour');
} }
// Build index // Build index with incremental flag
await indexer.buildIndex(false, '${INDEX_MODE}'); const incremental = process.env.INCREMENTAL === 'true';
await indexer.buildIndex(false, '${INDEX_MODE}', incremental);
// Close database // Close database
db.close(); db.close();

View File

@@ -23,9 +23,13 @@ program
.command('index') .command('index')
.description('Build or rebuild the index from awesome lists') .description('Build or rebuild the index from awesome lists')
.option('-f, --force', 'Force rebuild, clearing existing data') .option('-f, --force', 'Force rebuild, clearing existing data')
.option('-i, --incremental', 'Incremental mode: only update changed repositories (default: true)')
.option('--full', 'Full mode: re-index all repositories even if unchanged')
.action(async (options) => { .action(async (options) => {
const indexer = require('./lib/indexer'); const indexer = require('./lib/indexer');
await indexer.buildIndex(options.force); // Determine incremental mode: default true unless --full is specified
const incremental = options.full ? false : (options.incremental !== false);
await indexer.buildIndex(options.force, null, incremental);
}); });
program program

View File

@@ -89,7 +89,7 @@ function isAwesomeList(url, name, description) {
} }
// Build the complete index // Build the complete index
async function buildIndex(force = false, mode = null) { async function buildIndex(force = false, mode = null, incremental = true) {
console.clear(); console.clear();
console.log(purpleGold('\n🚀 AWESOME INDEX BUILDER 🚀\n')); console.log(purpleGold('\n🚀 AWESOME INDEX BUILDER 🚀\n'));
@@ -146,6 +146,7 @@ async function buildIndex(force = false, mode = null) {
console.log(chalk.green(`✓ Found ${awesomeLists.length} awesome lists!\n`)); console.log(chalk.green(`✓ Found ${awesomeLists.length} awesome lists!\n`));
let indexChoice = mode; let indexChoice = mode;
let incrementalChoice = incremental;
// Ask user what to index (only if interactive) // Ask user what to index (only if interactive)
if (!isNonInteractive) { if (!isNonInteractive) {
@@ -161,9 +162,19 @@ async function buildIndex(force = false, mode = null) {
{ name: '🔍 Select specific categories', value: 'select' }, { name: '🔍 Select specific categories', value: 'select' },
{ name: '← Back', value: 'cancel' } { name: '← Back', value: 'cancel' }
] ]
},
{
type: 'confirm',
name: 'incremental',
message: 'Use incremental mode? (only update changed repos, faster)',
default: true,
when: (answers) => answers.indexChoice === 'full' || answers.indexChoice === 'sample'
} }
]); ]);
indexChoice = result.indexChoice; indexChoice = result.indexChoice;
if (result.incremental !== undefined) {
incrementalChoice = result.incremental;
}
} }
if (indexChoice === 'cancel') return; if (indexChoice === 'cancel') return;
@@ -171,7 +182,12 @@ async function buildIndex(force = false, mode = null) {
// Default to 'full' if no mode specified // Default to 'full' if no mode specified
if (!indexChoice) indexChoice = 'full'; if (!indexChoice) indexChoice = 'full';
console.log(chalk.cyan(`Index mode: ${indexChoice}\n`)); console.log(chalk.cyan(`Index mode: ${indexChoice}`));
if (indexChoice === 'full' || indexChoice === 'sample') {
console.log(chalk.cyan(`Incremental: ${incrementalChoice ? 'Yes (skip unchanged repos)' : 'No (re-index all)'}\n`));
} else {
console.log('');
}
let listsToIndex = awesomeLists; let listsToIndex = awesomeLists;
@@ -274,6 +290,8 @@ async function buildIndex(force = false, mode = null) {
// Determine if we need to fetch README // Determine if we need to fetch README
let shouldFetchReadme = false; let shouldFetchReadme = false;
if (indexChoice === 'full' || indexChoice === 'sample') { if (indexChoice === 'full' || indexChoice === 'sample') {
if (incrementalChoice) {
// Incremental mode: only fetch if new or changed
if (!existingRepo) { if (!existingRepo) {
// New repo - fetch README // New repo - fetch README
shouldFetchReadme = true; shouldFetchReadme = true;
@@ -282,6 +300,10 @@ async function buildIndex(force = false, mode = null) {
shouldFetchReadme = true; shouldFetchReadme = true;
} }
// else: repo unchanged, skip README fetch // else: repo unchanged, skip README fetch
} else {
// Full re-index mode: always fetch README
shouldFetchReadme = true;
}
} }
if (shouldFetchReadme) { if (shouldFetchReadme) {