Last active
December 17, 2024 18:45
-
-
Save andrialexandrou/0e49af3fb7f5c4dac2ff457869f4fe02 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
/** | |
* Pull Request Search Script | |
* | |
* Usage: node script.js <target_directory> [initial_commit] | |
* | |
* Required Arguments: | |
* - target_directory: Relative path to the directory to search for PRs | |
* Example: ./src/components | |
* | |
* Optional Arguments: | |
* - initial_commit: Commit hash to stop searching at (oldest commit to process) | |
* | |
* Prerequisites: | |
* - Node.js installed | |
* - GitHub CLI (gh) installed and authenticated | |
* | |
* Installation: | |
* 1. Ensure you're in your project's root directory | |
* 2. Save this script as 'pr-search.js' | |
* 3. Make script executable (optional on Unix-like systems): | |
* - Run 'chmod +x pr-search.js' | |
* | |
* IMPORTANT: | |
* - DO NOT COMMIT THE GENERATED OUTPUT FILE TO YOUR PROJECT | |
* | |
* Example Commands: | |
* - Basic usage: node pr-search.js ./src/components | |
* - With commit limit: node pr-search.js ./src/components abcd123 | |
* | |
* Output: | |
* - Creates 'pr_search_<directory_name>.md' | |
* - Contains list of unique PR numbers with hyperlinks | |
* - File is saved in the same directory as the script | |
* | |
* Troubleshooting: | |
* - Ensure you're in the correct git repository | |
* - Verify GitHub CLI is authenticated | |
* - Check that the directory path is correct | |
*/ | |
const { exec } = require('child_process'); | |
const fs = require('fs'); | |
// Validate directory path from command line args | |
const targetDirectory = process.argv[2]; | |
const initialCommit = process.argv[3]; // Optional initial commit to stop at | |
if (!targetDirectory) { | |
console.error('Error: Please provide the relative path, in the pattern of ./your/desired/subdirectory/root/'); | |
process.exit(1); | |
} | |
console.log(`Searching in directory: ${targetDirectory}`); | |
if (initialCommit) { | |
console.log(`Stopping at initial commit: ${initialCommit}`); | |
} | |
// Function to execute a shell command and return it as a Promise | |
const execShellCommand = (cmd) => { | |
return new Promise((resolve, reject) => { | |
exec(cmd, (error, stdout, stderr) => { | |
if (error) { | |
console.error(`Error executing command: ${cmd}`); | |
console.error(`stderr: ${stderr}`); | |
console.error('Full error:', error); | |
reject(error); | |
} | |
if (stderr) { | |
console.error(`stderr: ${stderr}`); | |
} | |
resolve(stdout ? stdout : stderr); | |
}); | |
}); | |
}; | |
// Main function to get commit logs and view PR details | |
const main = async () => { | |
try { | |
console.log('Starting the procedure...'); | |
// Construct git log command with optional initial commit | |
let gitLogCommand = initialCommit | |
? `git log --oneline ${initialCommit}..HEAD -- "${targetDirectory}"` | |
: `git log --oneline -- "${targetDirectory}"`; | |
// Get the commit logs with configurable directory | |
const logOutput = await execShellCommand(gitLogCommand); | |
const commits = logOutput.split('\n').map(line => line.split(' ')[0]).filter(Boolean); | |
const totalCommits = commits.length; | |
console.log(`Found ${totalCommits} commits to process`); | |
const uniquePrNumbers = new Set(); | |
const allPrDetails = new Map(); | |
let output = '# Pull Requests for Directory\n\n'; | |
let currentCommit = 0; | |
// Iterate over each commit and get PR details | |
for (const commit of commits) { | |
currentCommit++; | |
const prListOutput = await execShellCommand(`gh pr list --state all --search ${commit}`); | |
console.log('PR list output:', prListOutput); | |
const prNumbers = prListOutput.split('\n') | |
.filter(Boolean) // Remove empty lines | |
.map(line => { | |
const [number, title] = line.split('\t'); | |
return { number, title }; | |
}) | |
.filter(pr => pr.number && pr.title); | |
console.log('Extracted PR info:', prNumbers); | |
prNumbers.forEach(pr => { | |
uniquePrNumbers.add(pr.number); | |
allPrDetails.set(pr.number, pr.title); // Store PR details for later use | |
}); | |
console.log(`Progress: ${currentCommit}/${totalCommits} commits processed`); | |
} | |
console.log('\nUnique PR numbers found:', Array.from(uniquePrNumbers)); | |
// TODO: IMPORTANT - Replace with your actual repository details | |
// Use allPrDetails instead of prNumbers | |
for (const prNumber of uniquePrNumbers) { | |
console.log(`\nAdding PR #${prNumber} to output`); | |
const prInfo = `- [#${prNumber}: ${allPrDetails.get(prNumber) || ''}](https://github.com/YOUR_REPO_OWNER/YOUR_REPO_NAME/pull/${prNumber})\n`; | |
output += prInfo; | |
console.log('PR Info:', prInfo); | |
} | |
// Create a generic output filename based on the target directory | |
const sanitizedDirectoryName = targetDirectory | |
.replace(/[^a-z0-9]/gi, '_') // Replace non-alphanumeric characters with underscores | |
.replace(/(^_|_$)/g, '') // Remove leading/trailing underscores | |
.toLowerCase(); | |
const outputFilename = `pr_search_${sanitizedDirectoryName}.md`; | |
// Write output to file | |
fs.writeFileSync(outputFilename, output); | |
console.log(`\nOutput written to ${outputFilename}`); | |
} catch (error) { | |
console.error('Full error stack trace:'); | |
console.error(error); | |
} | |
}; | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment