From 9983b1dd0a4e271061bd51b41fd04bc6e804dcc1 Mon Sep 17 00:00:00 2001 From: Saravana Dhandapani Date: Tue, 16 Sep 2025 17:43:59 -0700 Subject: [PATCH] feat: git commit related --- README_interactive_script.md | 272 ++++++++ README_remove_user_script.md | 194 ++++++ check_i_ayushh18_collaborator.sh | 160 +++++ contributor_repos/ADPatel07.json | 7 - contributor_repos/AaronZyLee.json | 3 - contributor_repos/Aditya108786.json | 3 - contributor_repos/Amplifiyer.json | 3 - contributor_repos/ArnabhS.json | 8 - contributor_repos/DeeAndroid.json | 3 - contributor_repos/Kmann22.json | 7 - contributor_repos/ReethuVennam.json | 3 - contributor_repos/SamadritaBhattacharya.json | 5 - contributor_repos/UnleashedMind.json | 3 - contributor_repos/abhinaisai2002.json | 7 - contributor_repos/akgm3i.json | 3 - contributor_repos/akshbhu.json | 3 - contributor_repos/alexmcmanus.json | 3 - contributor_repos/ammarkarachi.json | 3 - contributor_repos/appwiz.json | 3 - contributor_repos/ashika01.json | 3 - contributor_repos/ashika112.json | 3 - contributor_repos/attilah.json | 3 - contributor_repos/awsed.json | 3 - contributor_repos/bytelyst-ai.json | 3 - contributor_repos/dabit3.json | 3 - contributor_repos/diegocstn.json | 3 - contributor_repos/edwardfoyle.json | 3 - contributor_repos/fjnoyp.json | 3 - contributor_repos/frimfram.json | 3 - contributor_repos/hirochachacha.json | 3 - contributor_repos/i-ayushh18.json | 7 - contributor_repos/jamesonwilliams.json | 3 - contributor_repos/kaustavghosh06.json | 3 - contributor_repos/khushie03.json | 4 - contributor_repos/lakshmitulasimandala.json | 3 - contributor_repos/lawmicha.json | 3 - contributor_repos/lovable-dev[bot].json | 5 - contributor_repos/mabdullahadeel.json | 3 - contributor_repos/malvika05.json | 7 - contributor_repos/malvika112.json | 3 - contributor_repos/marcvberg.json | 3 - contributor_repos/mikepschneider.json | 3 - contributor_repos/muskan901.json | 5 - contributor_repos/nikhilsharma8193.json | 3 - contributor_repos/nikhname.json | 3 - contributor_repos/odedpeer.json | 3 - contributor_repos/onlybakam.json | 3 - contributor_repos/pavellazar.json | 3 - contributor_repos/phani-srikar.json | 3 - contributor_repos/rakannimer.json | 3 - contributor_repos/rjuliano.json | 3 - contributor_repos/rougue1.json | 3 - contributor_repos/sandho.json | 6 - contributor_repos/saravanakumardb.json | 76 --- contributor_repos/saravanakumardb1.json | 10 - contributor_repos/saravanange.json | 8 - contributor_repos/seang96.json | 3 - contributor_repos/siegerts.json | 3 - contributor_repos/srinija06.json | 3 - contributor_repos/sscotth.json | 3 - contributor_repos/sundersc.json | 3 - contributor_repos/swaminator.json | 3 - contributor_repos/vercel[bot].json | 3 - contributor_repos/yuth.json | 3 - contributor_repos/zeynepsu.json | 3 - github_access_scripts/README.md | 34 + .../contributor_repos/ADPatel07.json | 8 +- .../contributor_repos/AaronZyLee.json | 4 +- .../contributor_repos/Aditya108786.json | 4 +- .../contributor_repos/Amplifiyer.json | 4 +- .../contributor_repos/ArnabhS.json | 9 +- .../contributor_repos/DeeAndroid.json | 4 +- .../contributor_repos/Kmann22.json | 8 +- .../contributor_repos/ReethuVennam.json | 4 +- .../SamadritaBhattacharya.json | 6 +- .../contributor_repos/UnleashedMind.json | 4 +- .../contributor_repos/abhinaisai2002.json | 8 +- .../contributor_repos/akgm3i.json | 4 +- .../contributor_repos/akshbhu.json | 4 +- .../contributor_repos/alexmcmanus.json | 4 +- .../contributor_repos/ammarkarachi.json | 4 +- .../contributor_repos/appwiz.json | 4 +- .../contributor_repos/ashika01.json | 4 +- .../contributor_repos/ashika112.json | 4 +- .../contributor_repos/attilah.json | 4 +- .../contributor_repos/awsed.json | 4 +- .../contributor_repos/bytelyst-ai.json | 4 +- .../contributor_repos/dabit3.json | 4 +- .../contributor_repos/diegocstn.json | 4 +- .../contributor_repos/edwardfoyle.json | 4 +- .../contributor_repos/fjnoyp.json | 4 +- .../contributor_repos/frimfram.json | 4 +- .../contributor_repos/hirochachacha.json | 4 +- .../contributor_repos/i-ayushh18.json | 8 +- .../contributor_repos/jamesonwilliams.json | 4 +- .../contributor_repos/kaustavghosh06.json | 4 +- .../contributor_repos/khushie03.json | 5 +- .../lakshmitulasimandala.json | 4 +- .../contributor_repos/lawmicha.json | 4 +- .../contributor_repos/lovable-dev[bot].json | 6 +- .../contributor_repos/mabdullahadeel.json | 4 +- .../contributor_repos/malvika05.json | 8 +- .../contributor_repos/malvika112.json | 4 +- .../contributor_repos/marcvberg.json | 4 +- .../contributor_repos/mikepschneider.json | 4 +- .../contributor_repos/muskan901.json | 6 +- .../contributor_repos/nikhilsharma8193.json | 4 +- .../contributor_repos/nikhname.json | 4 +- .../contributor_repos/odedpeer.json | 4 +- .../contributor_repos/onlybakam.json | 4 +- .../contributor_repos/pavellazar.json | 4 +- .../contributor_repos/phani-srikar.json | 4 +- .../contributor_repos/rakannimer.json | 4 +- .../contributor_repos/rjuliano.json | 4 +- .../contributor_repos/rougue1.json | 4 +- .../contributor_repos/sandho.json | 7 +- .../contributor_repos/saravanakumardb.json | 77 +-- .../contributor_repos/saravanakumardb1.json | 11 +- .../contributor_repos/saravanange.json | 9 +- .../contributor_repos/seang96.json | 4 +- .../contributor_repos/siegerts.json | 4 +- .../contributor_repos/srinija06.json | 4 +- .../contributor_repos/sscotth.json | 4 +- .../contributor_repos/sundersc.json | 4 +- .../contributor_repos/swaminator.json | 4 +- .../contributor_repos/vercel[bot].json | 4 +- .../contributor_repos/yuth.json | 4 +- .../contributor_repos/zeynepsu.json | 4 +- .../create_contributor_repo_lists.sh | 41 +- .../run_contributor_json_creation.sh | 35 + interactive_user_removal.sh | 614 ++++++++++++++++++ remove_user_from_repos.sh | 445 +++++++++++++ remove_user_guided.sh | 593 +++++++++++++++++ remove_user_i-ayushh18.sh | 32 + remove_user_interactive.sh | 373 +++++++++-- test_interactive.sh | 23 + 136 files changed, 2819 insertions(+), 671 deletions(-) create mode 100644 README_interactive_script.md create mode 100644 README_remove_user_script.md create mode 100755 check_i_ayushh18_collaborator.sh delete mode 100644 contributor_repos/ADPatel07.json delete mode 100644 contributor_repos/AaronZyLee.json delete mode 100644 contributor_repos/Aditya108786.json delete mode 100644 contributor_repos/Amplifiyer.json delete mode 100644 contributor_repos/ArnabhS.json delete mode 100644 contributor_repos/DeeAndroid.json delete mode 100644 contributor_repos/Kmann22.json delete mode 100644 contributor_repos/ReethuVennam.json delete mode 100644 contributor_repos/SamadritaBhattacharya.json delete mode 100644 contributor_repos/UnleashedMind.json delete mode 100644 contributor_repos/abhinaisai2002.json delete mode 100644 contributor_repos/akgm3i.json delete mode 100644 contributor_repos/akshbhu.json delete mode 100644 contributor_repos/alexmcmanus.json delete mode 100644 contributor_repos/ammarkarachi.json delete mode 100644 contributor_repos/appwiz.json delete mode 100644 contributor_repos/ashika01.json delete mode 100644 contributor_repos/ashika112.json delete mode 100644 contributor_repos/attilah.json delete mode 100644 contributor_repos/awsed.json delete mode 100644 contributor_repos/bytelyst-ai.json delete mode 100644 contributor_repos/dabit3.json delete mode 100644 contributor_repos/diegocstn.json delete mode 100644 contributor_repos/edwardfoyle.json delete mode 100644 contributor_repos/fjnoyp.json delete mode 100644 contributor_repos/frimfram.json delete mode 100644 contributor_repos/hirochachacha.json delete mode 100644 contributor_repos/i-ayushh18.json delete mode 100644 contributor_repos/jamesonwilliams.json delete mode 100644 contributor_repos/kaustavghosh06.json delete mode 100644 contributor_repos/khushie03.json delete mode 100644 contributor_repos/lakshmitulasimandala.json delete mode 100644 contributor_repos/lawmicha.json delete mode 100644 contributor_repos/lovable-dev[bot].json delete mode 100644 contributor_repos/mabdullahadeel.json delete mode 100644 contributor_repos/malvika05.json delete mode 100644 contributor_repos/malvika112.json delete mode 100644 contributor_repos/marcvberg.json delete mode 100644 contributor_repos/mikepschneider.json delete mode 100644 contributor_repos/muskan901.json delete mode 100644 contributor_repos/nikhilsharma8193.json delete mode 100644 contributor_repos/nikhname.json delete mode 100644 contributor_repos/odedpeer.json delete mode 100644 contributor_repos/onlybakam.json delete mode 100644 contributor_repos/pavellazar.json delete mode 100644 contributor_repos/phani-srikar.json delete mode 100644 contributor_repos/rakannimer.json delete mode 100644 contributor_repos/rjuliano.json delete mode 100644 contributor_repos/rougue1.json delete mode 100644 contributor_repos/sandho.json delete mode 100644 contributor_repos/saravanakumardb.json delete mode 100644 contributor_repos/saravanakumardb1.json delete mode 100644 contributor_repos/saravanange.json delete mode 100644 contributor_repos/seang96.json delete mode 100644 contributor_repos/siegerts.json delete mode 100644 contributor_repos/srinija06.json delete mode 100644 contributor_repos/sscotth.json delete mode 100644 contributor_repos/sundersc.json delete mode 100644 contributor_repos/swaminator.json delete mode 100644 contributor_repos/vercel[bot].json delete mode 100644 contributor_repos/yuth.json delete mode 100644 contributor_repos/zeynepsu.json create mode 100755 github_repo_scanners/run_contributor_json_creation.sh create mode 100755 interactive_user_removal.sh create mode 100755 remove_user_from_repos.sh create mode 100755 remove_user_guided.sh create mode 100755 remove_user_i-ayushh18.sh create mode 100755 test_interactive.sh diff --git a/README_interactive_script.md b/README_interactive_script.md new file mode 100644 index 0000000..800589a --- /dev/null +++ b/README_interactive_script.md @@ -0,0 +1,272 @@ +# 🚀 Interactive GitHub User Removal Script + +An intuitive, guided script that walks you through the process of removing users from GitHub repositories with a beautiful interactive interface. + +## ✨ Features + +### đŸŽ¯ Interactive Experience +- **Beautiful Welcome Screen** with ASCII art +- **Step-by-step Guided Process** - no command line arguments needed +- **Smart Input Validation** with helpful error messages +- **Confirmation Prompts** to prevent accidental operations +- **Real-time Progress Updates** with visual progress bars + +### đŸ›Ąī¸ Safety Features +- **Dry Run Mode** (recommended first run) - preview changes without executing +- **Multiple Confirmation Steps** for destructive operations +- **Token Validation** before proceeding +- **Pattern Preview** to show what repositories will match + +### 🎨 User Interface +- **Color-coded Output** for easy reading +- **Emoji Icons** for visual clarity +- **Formatted Headers** and sections +- **Clear Success/Error Messages** + +## 📋 Requirements + +- `bash` (version 4.0+) +- `curl` +- `jq` +- Valid GitHub Personal Access Token with `repo` and `admin:org` permissions + +## 🚀 Usage + +Simply run the script - no command line arguments needed: + +```bash +./remove_user_guided.sh +``` + +The script will guide you through each step: + +### 1. 🔑 GitHub Authentication +``` +🔑 GitHub Authentication +============================================================ +Please provide your GitHub Personal Access Token: +💡 The token should have 'repo' and 'admin:org' permissions +💡 You can create one at: https://github.com/settings/tokens + +🔐 Enter your GitHub token: [hidden input] +``` + +### 2. 👤 Target Organization/User +``` +👤 Target Organization/User +============================================================ +Enter the GitHub username or organization name: +💡 This is where we'll look for repositories +💡 Examples: 'mycompany', 'john-doe', 'my-organization' + +đŸĸ Organization/Username: +``` + +### 3. đŸŽ¯ User to Remove +``` +đŸŽ¯ User to Remove +============================================================ +Enter the username you want to remove from repositories: +💡 This user will be removed as a collaborator from matching repositories +💡 They will lose access to private repositories (if applicable) + +👤 Username to remove: +``` + +### 4. 📁 Repository Filter +``` +📁 Repository Filter +============================================================ +Enter a repository name pattern to filter repositories: +💡 Pattern examples: + â€ĸ '*' - All repositories + â€ĸ 'myproject-' - Repos starting with 'myproject-' + â€ĸ '*api*' - Repos containing 'api' + â€ĸ 'web-app' - Repos starting with 'web-app' + +🔍 Repository pattern: +``` + +### 5. âš™ī¸ Operation Options +``` +âš™ī¸ Operation Options +============================================================ +Choose your operation mode: + +1) 🔍 Dry Run - Preview what would be done (Recommended) +2) 🚀 Execute - Perform the actual removal + +Select option (1 or 2): +``` + +### 6. 📋 Final Summary +``` +📋 Operation Summary +============================================================ +Configuration: + đŸĸ Organization/User: myorg + 👤 User to remove: olduser + 🔍 Repository pattern: project-* + âš™ī¸ Mode: Dry Run + 📝 Logging: Standard + +Ready to proceed? (yes/no): +``` + +## 🎭 Interactive Flow Example + +Here's what a complete session looks like: + +``` + ╔══════════════════════════════════════════════════════════╗ + ║ ║ + ║ 🚀 GitHub User Removal Tool 🚀 ║ + ║ ║ + ║ Remove users from repositories with ease! ║ + ║ ║ + ╚══════════════════════════════════════════════════════════╝ + +â„šī¸ Welcome to the Interactive GitHub User Removal Script! + +🔑 GitHub Authentication +============================================================ +[Token input and validation...] + +👤 Target Organization/User +============================================================ +[Organization selection...] + +đŸŽ¯ User to Remove +============================================================ +[User selection with confirmation...] + +📁 Repository Filter +============================================================ +[Pattern selection with preview...] + +âš™ī¸ Operation Options +============================================================ +[Mode selection...] + +📋 Operation Summary +============================================================ +[Final confirmation...] + +🚀 Processing Repositories +============================================================ +â„šī¸ Discovering repositories for myorg... +✅ Found 25 repositories +â„šī¸ Filtering repositories by pattern 'project-*'... +✅ Found 8 repositories matching pattern 'project-*' +â„šī¸ Processing repositories... + +Progress: [100%] 8/8 repositories processed +[DRY RUN] Would remove olduser from myorg/project-api +[DRY RUN] Would remove olduser from myorg/project-web + +🎉 Operation Complete +============================================================ +📊 Statistics: + 📁 Repositories scanned: 25 + 🔍 Repositories matching pattern: 8 + 👤 Repositories where user was collaborator: 2 + + ✅ Successful removals: 0 + â„šī¸ Already removed: 0 + ❌ Failed removals: 0 + +âš ī¸ This was a dry run - no actual changes were made +💡 To perform the actual removal, run the script again and select 'Execute' mode + +🙏 Thank you for using the GitHub User Removal Tool! +``` + +## đŸ›Ąī¸ Safety Features in Detail + +### 1. **Token Validation** +- Validates GitHub token before any operations +- Shows authenticated username for confirmation +- Provides clear error messages for invalid tokens + +### 2. **Input Validation** +- Validates username/organization formats +- Checks repository pattern syntax +- Provides helpful suggestions for corrections + +### 3. **Confirmation Steps** +- Confirms user to be removed +- Confirms repository pattern understanding +- Requires explicit "YES" for destructive operations + +### 4. **Dry Run Mode (Recommended)** +- Shows exactly what would be done +- No actual changes made +- Perfect for testing and verification + +### 5. **Pattern Preview** +- Shows what the pattern will match before execution +- Examples: "This will match repositories starting with: project-" +- Helps prevent unintended scope + +## 🔧 Repository Patterns + +| Pattern | What it Matches | Examples | +|---------|-----------------|----------| +| `*` | All repositories | All repos in the org/user | +| `bytelyst-` | Repos starting with 'bytelyst-' | `bytelyst-web`, `bytelyst-api`, `bytelyst-mobile` | +| `*api*` | Repos containing 'api' | `web-api`, `user-api-v2`, `api-gateway` | +| `web-*` | Repos starting with 'web-' | `web-frontend`, `web-backend`, `web-app` | +| `*-service` | Repos ending with '-service' | `user-service`, `auth-service` | + +## 🎨 Color Coding + +The script uses intuitive color coding: + +- đŸ”ĩ **Blue**: Informational messages and prompts +- đŸŸĸ **Green**: Success messages and confirmations +- 🟡 **Yellow**: Warnings and important notices +- 🔴 **Red**: Errors and failures +- đŸŸŖ **Purple**: Section headers +- đŸŸĻ **Cyan**: Progress updates and statistics + +## 🚨 Important Notes + +1. **Always start with Dry Run mode** to preview changes +2. **Double-check the user to remove** - there's no undo! +3. **Verify repository patterns** match your intentions +4. **Ensure your token has sufficient permissions** +5. **Users will lose access to private repositories** immediately + +## 💡 Tips for Best Experience + +1. **Have your GitHub token ready** before starting +2. **Know the exact username** you want to remove +3. **Think about the repository pattern** beforehand +4. **Use Dry Run first** to verify everything looks correct +5. **Keep the terminal window** large enough for the interface + +## 🔗 Quick Start Guide + +1. **Prepare**: Get your GitHub token with proper permissions +2. **Run**: Execute `./remove_user_guided.sh` +3. **Follow**: The interactive prompts step by step +4. **Preview**: Always do a dry run first +5. **Execute**: Run again in execute mode if satisfied + +## ⚡ Keyboard Shortcuts + +- `Ctrl+C`: Cancel operation at any time +- `Enter`: Confirm current input +- Arrow keys work in most terminals for command history + +## 🆘 Need Help? + +The script provides comprehensive help at each step: +- Clear explanations for each input +- Examples for common patterns +- Helpful error messages +- Recovery suggestions + +--- + +**Ready to clean up your repositories? Just run `./remove_user_guided.sh` and let the script guide you!** 🚀 \ No newline at end of file diff --git a/README_remove_user_script.md b/README_remove_user_script.md new file mode 100644 index 0000000..b0dc744 --- /dev/null +++ b/README_remove_user_script.md @@ -0,0 +1,194 @@ +# GitHub User Removal Script + +A comprehensive script to remove a specified user from all repositories matching a prefix pattern under a given GitHub username or organization. + +## Features + +- ✅ **Flexible Filtering**: Support for various repository prefix patterns including wildcards +- ✅ **Dry Run Mode**: Test operations without making actual changes +- ✅ **Verbose Logging**: Detailed output for debugging and monitoring +- ✅ **Progress Tracking**: Real-time progress updates during processing +- ✅ **Error Handling**: Robust error handling with detailed HTTP status reporting +- ✅ **Statistics**: Comprehensive summary of operations performed +- ✅ **Auto-detection**: Automatically detects if the root is a user or organization + +## Requirements + +- `bash` (version 4.0+) +- `curl` +- `jq` +- Valid GitHub Personal Access Token with `repo` and `admin:org` permissions + +## Usage + +```bash +./remove_user_from_repos.sh -t TOKEN -r ROOT_USER -u USER_TO_REMOVE -p REPO_PREFIX [OPTIONS] +``` + +### Required Parameters + +| Parameter | Description | +|-----------|-------------| +| `-t, --token TOKEN` | GitHub Personal Access Token | +| `-r, --root ROOT_USER` | Root GitHub username or organization | +| `-u, --user USER_TO_REMOVE` | Username to remove from repositories | +| `-p, --prefix REPO_PREFIX` | Repository name prefix pattern | + +### Optional Parameters + +| Parameter | Description | +|-----------|-------------| +| `-d, --dry-run` | Show what would be done without making changes | +| `-v, --verbose` | Enable verbose logging | +| `-h, --help` | Show help message | + +## Repository Prefix Patterns + +| Pattern | Description | Example Matches | +|---------|-------------|-----------------| +| `"bytelyst-"` | Repos starting with 'bytelyst-' | `bytelyst-web`, `bytelyst-api` | +| `"*api*"` | Repos containing 'api' | `web-api`, `api-service`, `my-api-v2` | +| `"*"` | All repositories | All repos in the organization/user | +| `"web-app"` | Repos starting with 'web-app' | `web-app-frontend`, `web-app-v2` | + +## Examples + +### 1. Remove user from all repositories starting with 'bytelyst-' +```bash +export GITHUB_TOKEN="your_token_here" +./remove_user_from_repos.sh -t "$GITHUB_TOKEN" -r "saravanakumardb" -u "i-ayushh18" -p "bytelyst-" +``` + +### 2. Dry run - Remove user from all repositories (preview mode) +```bash +./remove_user_from_repos.sh -t "$GITHUB_TOKEN" -r "myorg" -u "olduser" -p "*" --dry-run +``` + +### 3. Remove user with verbose logging +```bash +./remove_user_from_repos.sh -t "$GITHUB_TOKEN" -r "myorg" -u "olduser" -p "project-" --verbose +``` + +### 4. Remove user from repositories containing 'api' +```bash +./remove_user_from_repos.sh -t "$GITHUB_TOKEN" -r "myorg" -u "developer123" -p "*api*" +``` + +## Output Example + +```bash +GitHub User Removal Script +============================================================ +â„šī¸ Root user/organization: saravanakumardb +â„šī¸ User to remove: i-ayushh18 +â„šī¸ Repository prefix: bytelyst- +✅ Token validated (authenticated as: saravanakumardb) + +Repository Discovery +============================================================ +✅ Found 23 repositories + +Filtering Repositories +============================================================ +✅ Found 4 repositories matching prefix 'bytelyst-' + +Processing Repositories +============================================================ +Progress: [100%] 4/4 repositories processed +✅ Successfully removed i-ayushh18 from saravanakumardb/bytelyst-web-app + +Operation Summary +============================================================ +Repositories scanned: 23 +Repositories matching prefix: 4 +Repositories where user was collaborator: 1 + +Successful removals: 1 +Already removed: 0 +Failed removals: 0 +Success rate: 100% + +✅ Operation completed successfully! +``` + +## Creating GitHub Token + +1. Go to GitHub → Settings → Developer Settings → Personal Access Tokens → Fine-grained tokens +2. Click "Generate new token" +3. Select the required permissions: + - `repo` (Full control of private repositories) + - `admin:org` (Full control of orgs and teams) +4. Set appropriate expiration date +5. Generate and copy the token + +## Security Best Practices + +- Store tokens as environment variables: `export GITHUB_TOKEN="your_token"` +- Never commit tokens to version control +- Use fine-grained tokens with minimal required permissions +- Regularly rotate tokens +- Use `--dry-run` first to verify operations + +## Error Handling + +The script handles various error scenarios: + +- **Invalid tokens**: Authentication validation before operations +- **Missing repositories**: Graceful handling of non-existent repos +- **Insufficient permissions**: Clear error messages for access issues +- **Network issues**: Retry logic for transient failures +- **Invalid users/orgs**: Proper detection and error reporting + +## Exit Codes + +- `0`: Success - All operations completed successfully +- `1`: Failure - One or more operations failed (details in summary) + +## Troubleshooting + +### Common Issues + +1. **"Invalid or expired GitHub token"** + - Check token validity + - Ensure token has required permissions + +2. **"Access forbidden for repository"** + - Token may lack admin permissions for the repository + - Repository may be archived or have restricted access + +3. **"Could not fetch repositories"** + - User/organization name may be incorrect + - Token may lack appropriate access + +### Debug Mode + +Use `--verbose` flag to see detailed operation logs: +```bash +./remove_user_from_repos.sh -t "$TOKEN" -r "user" -u "target" -p "*" -v +``` + +## Integration Examples + +### CI/CD Pipeline +```yaml +- name: Remove user from repositories + run: | + ./remove_user_from_repos.sh \ + -t "${{ secrets.GITHUB_TOKEN }}" \ + -r "${{ vars.ORG_NAME }}" \ + -u "${{ vars.USER_TO_REMOVE }}" \ + -p "${{ vars.REPO_PREFIX }}" +``` + +### Batch Processing +```bash +#!/bin/bash +users=("user1" "user2" "user3") +for user in "${users[@]}"; do + ./remove_user_from_repos.sh -t "$TOKEN" -r "myorg" -u "$user" -p "*" +done +``` + +## License + +This script is provided as-is for repository management purposes. Use responsibly and ensure you have appropriate permissions before running in production environments. \ No newline at end of file diff --git a/check_i_ayushh18_collaborator.sh b/check_i_ayushh18_collaborator.sh new file mode 100755 index 0000000..05390ab --- /dev/null +++ b/check_i_ayushh18_collaborator.sh @@ -0,0 +1,160 @@ +#!/bin/bash + +# Script to check if i-ayushh18 is a collaborator on repositories +# Uses accounts.json for authentication tokens + +set -euo pipefail + +# Color definitions +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly CYAN='\033[0;36m' +readonly BOLD='\033[1m' +readonly NC='\033[0m' # No Color + +USER_TO_CHECK="i-ayushh18" +REPOS_FILE="repos.txt" +ACCOUNTS_FILE="accounts.json" + +# Function to log messages +log_info() { + echo -e "${BLUE}â„šī¸ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}âš ī¸ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +log_header() { + echo -e "\n${BOLD}${CYAN}$1${NC}" + echo -e "${CYAN}$(printf '=%.0s' {1..60})${NC}" +} + +# Check required files +if [[ ! -f "$REPOS_FILE" ]]; then + log_error "Repository list file '$REPOS_FILE' not found" + exit 1 +fi + +if [[ ! -f "$ACCOUNTS_FILE" ]]; then + log_error "Accounts file '$ACCOUNTS_FILE' not found" + exit 1 +fi + +# Get GitHub token from accounts.json +GITHUB_TOKEN=$(jq -r '.[0].token' "$ACCOUNTS_FILE") +GITHUB_USER=$(jq -r '.[0].user' "$ACCOUNTS_FILE") + +if [[ -z "$GITHUB_TOKEN" || "$GITHUB_TOKEN" == "null" ]]; then + log_error "Could not extract GitHub token from accounts.json" + exit 1 +fi + +log_info "Using GitHub account: $GITHUB_USER" + +# Function to check if user is a collaborator on a repository +check_collaboration() { + local repo="$1" + + # Validate repository name format + if [[ ! "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + log_warning "Invalid repository name format: $repo" + return 1 + fi + + local response + response=$(curl -s -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$USER_TO_CHECK") + + local http_code="${response: -3}" + + case "$http_code" in + 204) + return 0 # User is a collaborator + ;; + 404) + return 1 # User is not a collaborator + ;; + 403) + log_warning "Access forbidden for $repo - may not have admin permissions" + return 1 + ;; + 401) + log_error "Authentication failed - token may be invalid or expired" + return 1 + ;; + *) + log_warning "Failed to check collaboration status for $USER_TO_CHECK on $repo (HTTP: $http_code)" + return 1 + ;; + esac +} + +# Main execution +log_header "Checking collaborator status for $USER_TO_CHECK" + +# Read repositories from file +if [[ ! -s "$REPOS_FILE" ]]; then + log_error "Repository file '$REPOS_FILE' is empty" + exit 1 +fi + +collaborator_repos=() +total_repos=0 +checked_repos=0 + +# Count total repositories +total_repos=$(wc -l < "$REPOS_FILE") +log_info "Found $total_repos repositories to check" + +log_header "Checking Repositories" + +# Check each repository +while IFS= read -r repo; do + # Skip empty lines + [[ -z "$repo" ]] && continue + + ((checked_repos++)) + printf "\r${CYAN}Progress: [%3d%%] %d/%d repositories checked${NC}" \ + $((checked_repos * 100 / total_repos)) "$checked_repos" "$total_repos" + + if check_collaboration "$repo"; then + collaborator_repos+=("$repo") + echo # New line after progress + log_success "$USER_TO_CHECK is a collaborator on: $repo" + fi +done < "$REPOS_FILE" + +echo # New line after progress + +# Show results +log_header "Results Summary" + +if [[ ${#collaborator_repos[@]} -eq 0 ]]; then + log_info "✨ $USER_TO_CHECK is not a collaborator on any of the $total_repos repositories checked" + echo -e "${GREEN}No repositories found where $USER_TO_CHECK has collaborator access.${NC}" +else + log_success "$USER_TO_CHECK is a collaborator on ${#collaborator_repos[@]} out of $total_repos repositories:" + echo + for repo in "${collaborator_repos[@]}"; do + echo -e "${YELLOW}â€ĸ $repo${NC}" + done + + # Save results to file + results_file="collaborator_repos_${USER_TO_CHECK}.txt" + printf '%s\n' "${collaborator_repos[@]}" > "$results_file" + log_info "Results saved to: $results_file" +fi + +log_header "Operation Complete" +echo -e "${GREEN}Finished checking $total_repos repositories for $USER_TO_CHECK collaborator status${NC}" \ No newline at end of file diff --git a/contributor_repos/ADPatel07.json b/contributor_repos/ADPatel07.json deleted file mode 100644 index def8e3c..0000000 --- a/contributor_repos/ADPatel07.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - "saravanakumardb/bytelyst-ds-intern-akhil-Rephrase-Assignment", - "saravanakumardb1/bytelyst-micro-service", - "saravanakumardb1/bytelyst-notelett-api", - "saravanakumardb1/bytelyst-notification-fastapi", - "saravanakumardb1/bytelyst-users-fastapi" -] diff --git a/contributor_repos/AaronZyLee.json b/contributor_repos/AaronZyLee.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/AaronZyLee.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/Aditya108786.json b/contributor_repos/Aditya108786.json deleted file mode 100644 index f83c602..0000000 --- a/contributor_repos/Aditya108786.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "bytelyst-ai/bytelyst-minutemaster-web" -] diff --git a/contributor_repos/Amplifiyer.json b/contributor_repos/Amplifiyer.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/Amplifiyer.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/ArnabhS.json b/contributor_repos/ArnabhS.json deleted file mode 100644 index b46b5c8..0000000 --- a/contributor_repos/ArnabhS.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - "ArnabhS/snapscribe-web", - "bytelyst-ai/newsletter", - "bytelyst-ai/snapscribe-web", - "bytelyst-ai/Task-Manager", - "bytelyst-ai/zenhustles-web", - "saravanakumardb/notelett-webapp" -] diff --git a/contributor_repos/DeeAndroid.json b/contributor_repos/DeeAndroid.json deleted file mode 100644 index 3fb9fb2..0000000 --- a/contributor_repos/DeeAndroid.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "Bytelyst/tapchat-web" -] diff --git a/contributor_repos/Kmann22.json b/contributor_repos/Kmann22.json deleted file mode 100644 index 1ed41cd..0000000 --- a/contributor_repos/Kmann22.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - "bytelyst-ai/activetracker", - "bytelyst-ai/elevatr-mob", - "bytelyst-ai/figmatoflutter", - "bytelyst-ai/minutemaster", - "bytelyst-ai/voiceapp" -] diff --git a/contributor_repos/ReethuVennam.json b/contributor_repos/ReethuVennam.json deleted file mode 100644 index 7baad1a..0000000 --- a/contributor_repos/ReethuVennam.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/bytelyst-gaslesspad-web" -] diff --git a/contributor_repos/SamadritaBhattacharya.json b/contributor_repos/SamadritaBhattacharya.json deleted file mode 100644 index 4924946..0000000 --- a/contributor_repos/SamadritaBhattacharya.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - "ArnabhS/snapscribe-web", - "bytelyst-ai/snapscribe-web", - "saravanakumardb/notelett-webapp" -] diff --git a/contributor_repos/UnleashedMind.json b/contributor_repos/UnleashedMind.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/UnleashedMind.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/abhinaisai2002.json b/contributor_repos/abhinaisai2002.json deleted file mode 100644 index 4b2e7db..0000000 --- a/contributor_repos/abhinaisai2002.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - "abhinaisai2002/bytelyst-mock-interviews-ai-web", - "abhinaisai2002/chat.com", - "abhinaisai2002/DSA-Prep", - "ByteLystAI/bytelyst-micro-services-old-delete-", - "saravanakumardb/Abhi-DSA-Prep-2024" -] diff --git a/contributor_repos/akgm3i.json b/contributor_repos/akgm3i.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/akgm3i.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/akshbhu.json b/contributor_repos/akshbhu.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/akshbhu.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/alexmcmanus.json b/contributor_repos/alexmcmanus.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/alexmcmanus.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/ammarkarachi.json b/contributor_repos/ammarkarachi.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/ammarkarachi.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/appwiz.json b/contributor_repos/appwiz.json deleted file mode 100644 index 6aa414b..0000000 --- a/contributor_repos/appwiz.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] diff --git a/contributor_repos/ashika01.json b/contributor_repos/ashika01.json deleted file mode 100644 index 6aa414b..0000000 --- a/contributor_repos/ashika01.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] diff --git a/contributor_repos/ashika112.json b/contributor_repos/ashika112.json deleted file mode 100644 index 6aa414b..0000000 --- a/contributor_repos/ashika112.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] diff --git a/contributor_repos/attilah.json b/contributor_repos/attilah.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/attilah.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/awsed.json b/contributor_repos/awsed.json deleted file mode 100644 index 6aa414b..0000000 --- a/contributor_repos/awsed.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] diff --git a/contributor_repos/bytelyst-ai.json b/contributor_repos/bytelyst-ai.json deleted file mode 100644 index 40d3859..0000000 --- a/contributor_repos/bytelyst-ai.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/notelett-webapp" -] diff --git a/contributor_repos/dabit3.json b/contributor_repos/dabit3.json deleted file mode 100644 index 83b8d63..0000000 --- a/contributor_repos/dabit3.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "ByteLystLabs/snap-scribe-mob" -] diff --git a/contributor_repos/diegocstn.json b/contributor_repos/diegocstn.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/diegocstn.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/edwardfoyle.json b/contributor_repos/edwardfoyle.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/edwardfoyle.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/fjnoyp.json b/contributor_repos/fjnoyp.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/fjnoyp.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/frimfram.json b/contributor_repos/frimfram.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/frimfram.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/hirochachacha.json b/contributor_repos/hirochachacha.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/hirochachacha.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/i-ayushh18.json b/contributor_repos/i-ayushh18.json deleted file mode 100644 index db502e3..0000000 --- a/contributor_repos/i-ayushh18.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - "i-ayushh18/ByteListTask", - "saravanakumardb/bytelyst-devopsdash-ayush-assignment", - "saravanakumardb/bytelyst-upskillpilot-web", - "saravanakumardb1/bytelyst-github-fastapi", - "saravanakumardb1/bytelyst-skillnest-web-delete" -] diff --git a/contributor_repos/jamesonwilliams.json b/contributor_repos/jamesonwilliams.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/jamesonwilliams.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/kaustavghosh06.json b/contributor_repos/kaustavghosh06.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/kaustavghosh06.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/khushie03.json b/contributor_repos/khushie03.json deleted file mode 100644 index dd6e0b1..0000000 --- a/contributor_repos/khushie03.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "bytelyst-ai/BytelystAI_Experiments", - "bytelyst-ai/LocalLLMSandboxApp" -] diff --git a/contributor_repos/lakshmitulasimandala.json b/contributor_repos/lakshmitulasimandala.json deleted file mode 100644 index 8e95194..0000000 --- a/contributor_repos/lakshmitulasimandala.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "lakshmitulasimandala/Minute-Master-redesign" -] diff --git a/contributor_repos/lawmicha.json b/contributor_repos/lawmicha.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/lawmicha.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/lovable-dev[bot].json b/contributor_repos/lovable-dev[bot].json deleted file mode 100644 index 4f105f6..0000000 --- a/contributor_repos/lovable-dev[bot].json +++ /dev/null @@ -1,5 +0,0 @@ -[ - "saravanakumardb/action-guide-portal", - "saravanakumardb/bytelyst-launchops-web", - "saravanakumardb/bytelyst-nomgap-web" -] diff --git a/contributor_repos/mabdullahadeel.json b/contributor_repos/mabdullahadeel.json deleted file mode 100644 index f9ed345..0000000 --- a/contributor_repos/mabdullahadeel.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "bytelyst-ai/vercel-fastapi-deployment_TemplateService" -] diff --git a/contributor_repos/malvika05.json b/contributor_repos/malvika05.json deleted file mode 100644 index a2b879a..0000000 --- a/contributor_repos/malvika05.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - "bytelyst-ai/Cover_letter_generator", - "bytelyst-ai/crewai", - "bytelyst-ai/prompted-insipiration", - "bytelyst-ai/quote_generator", - "bytelyst-ai/task-recommendation" -] diff --git a/contributor_repos/malvika112.json b/contributor_repos/malvika112.json deleted file mode 100644 index 8c6247a..0000000 --- a/contributor_repos/malvika112.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "ByteLystAI/MockInterviewsAI" -] diff --git a/contributor_repos/marcvberg.json b/contributor_repos/marcvberg.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/marcvberg.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/mikepschneider.json b/contributor_repos/mikepschneider.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/mikepschneider.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/muskan901.json b/contributor_repos/muskan901.json deleted file mode 100644 index f97e05f..0000000 --- a/contributor_repos/muskan901.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - "bytelyst-ai/photo-album", - "bytelyst-ai/timer", - "bytelyst-ai/zenhustles-web" -] diff --git a/contributor_repos/nikhilsharma8193.json b/contributor_repos/nikhilsharma8193.json deleted file mode 100644 index 6aa414b..0000000 --- a/contributor_repos/nikhilsharma8193.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] diff --git a/contributor_repos/nikhname.json b/contributor_repos/nikhname.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/nikhname.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/odedpeer.json b/contributor_repos/odedpeer.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/odedpeer.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/onlybakam.json b/contributor_repos/onlybakam.json deleted file mode 100644 index 6aa414b..0000000 --- a/contributor_repos/onlybakam.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] diff --git a/contributor_repos/pavellazar.json b/contributor_repos/pavellazar.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/pavellazar.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/phani-srikar.json b/contributor_repos/phani-srikar.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/phani-srikar.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/rakannimer.json b/contributor_repos/rakannimer.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/rakannimer.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/rjuliano.json b/contributor_repos/rjuliano.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/rjuliano.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/rougue1.json b/contributor_repos/rougue1.json deleted file mode 100644 index f90d542..0000000 --- a/contributor_repos/rougue1.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "rougue1/taskify" -] diff --git a/contributor_repos/sandho.json b/contributor_repos/sandho.json deleted file mode 100644 index f368a08..0000000 --- a/contributor_repos/sandho.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - "Bytelyst/tap-chat-backend", - "Bytelyst/tapchat-web", - "Bytelyst/zh-api", - "saravanakumardb/bytelyst-backend-micro-services" -] diff --git a/contributor_repos/saravanakumardb.json b/contributor_repos/saravanakumardb.json deleted file mode 100644 index 404fad0..0000000 --- a/contributor_repos/saravanakumardb.json +++ /dev/null @@ -1,76 +0,0 @@ -[ - "abhinaisai2002/bytelyst-mock-interviews-ai-web", - "ArnabhS/snapscribe-web", - "bytelyst-ai/snap-scribe-web", - "bytelyst-ai/snapscribe-web", - "bytelyst-ai/vercel-fastapi-deployment_TemplateService", - "bytelyst-ai/zenhustles-web", - "ByteLyst-Bootstrap-Templates/bytelyst-saas-starter-web", - "Bytelyst/tapchat-web", - "Bytelyst/zen-hustles-web-secrets", - "ByteLystAgents/MyTimeLine", - "ByteLystAgents/SnapScribeAI", - "ByteLystAgents/teams-welness-ninja-bot", - "ByteLystAgents/TeamsTimeKeeperBot", - "ByteLystAgents/TeamsTimerTab", - "ByteLystAgents/Timer", - "ByteLystAI-Svc/bytelyst-apikeymgmt-go-api", - "ByteLystAI-Svc/bytelyst-flomonk-fastapi", - "ByteLystAI-Svc/bytelyst-helloworld-svc", - "ByteLystAI-Svc/bytelyst-notify-go-api", - "ByteLystAI-Svc/bytelyst-tapchat-go-api", - "ByteLystAI/bytelyst-trading-agents", - "ByteLystAI/ByteLystAI_KMP_Mob", - "ByteLystAI/IBM_Watcon_Playground", - "ByteLystAI/MockInterviewsAI", - "ByteLystLabs/bytelyst_commons_fastapi", - "ByteLystLabs/bytelyst-vercel-fastapi-template", - "ByteLystLabs/bytelyst-worker", - "ByteLystLabs/BytelystBots", - "ByteLystLabs/diary_dazzle", - "ByteLystLabs/gen-ai-service", - "ByteLystLabs/limitless", - "ByteLystLabs/minute-master-web-delete", - "ByteLystLabs/notelett-web", - "ByteLystLabs/QRCodeAPPMobile", - "ByteLystLabs/redis-queue-processor", - "ByteLystLabs/snap-scribe-mob", - "ByteLystLabs/UserService", - "ByteLystLabs/vaa-ventures-web", - "ByteLystLabs/zen_hustles_flutter_mob_delete", - "ByteLystLabs/zen_hustles_mob", - "ByteLystLabs/zen-hustles-mob-delete", - "ByteLystLearning/udemy-webpack", - "HolosuitLabs/HoloBot-Chat", - "i-ayushh18/ByteListTask", - "saravanakumardb/.files", - "saravanakumardb/action-guide-portal", - "saravanakumardb/amplify-app", - "saravanakumardb/bytelyst", - "saravanakumardb/bytelyst-alp-ai", - "saravanakumardb/bytelyst-azure-ai-toolbox-web", - "saravanakumardb/bytelyst-azure-functions", - "saravanakumardb/bytelyst-bytelystos", - "saravanakumardb/bytelyst-compass4ai-web", - "saravanakumardb/bytelyst-dev-productivity-standards", - "saravanakumardb/bytelyst-devops-tools", - "saravanakumardb/bytelyst-devops-web", - "saravanakumardb/bytelyst-ds-intern-akhil-Rephrase-Assignment", - "saravanakumardb/bytelyst-dummy1-delete", - "saravanakumardb/bytelyst-flomonk-web", - "saravanakumardb/bytelyst-heirloom-web", - "saravanakumardb/bytelyst-ibm-watson-ai-toolbox-web", - "saravanakumardb/bytelyst-infrastructure", - "saravanakumardb/bytelyst-liteai-web", - "saravanakumardb/bytelyst-nomgap-web", - "saravanakumardb/bytelyst-upskillpilot-web", - "saravanakumardb/notelett-webapp", - "saravanakumardb1/bytelyst_upskillpilot_fastapi", - "saravanakumardb1/bytelyst-commons-api", - "saravanakumardb1/bytelyst-github-fastapi", - "saravanakumardb1/bytelyst-micro-service", - "saravanakumardb1/bytelyst-nomgap-api", - "saravanakumardb1/bytelyst-notelett-api", - "saravanakumardb1/bytelyst-notification-fastapi", - "saravanakumardb1/bytelyst-products-go-api" -] diff --git a/contributor_repos/saravanakumardb1.json b/contributor_repos/saravanakumardb1.json deleted file mode 100644 index d2e52f5..0000000 --- a/contributor_repos/saravanakumardb1.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - "saravanakumardb/bytelyst-ibm-watson-ai-toolbox-web", - "saravanakumardb/bytelyst-upskillpilot-web", - "saravanakumardb1/bytelyst_upskillpilot_fastapi", - "saravanakumardb1/bytelyst-github-fastapi", - "saravanakumardb1/bytelyst-micro-service", - "saravanakumardb1/bytelyst-notelett-mob", - "saravanakumardb1/bytelyst-notification-fastapi", - "saravanakumardb1/bytelyst-tapchat-web" -] diff --git a/contributor_repos/saravanange.json b/contributor_repos/saravanange.json deleted file mode 100644 index 7395eb5..0000000 --- a/contributor_repos/saravanange.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - "ByteLystAI/bytelyst-trading-agents", - "ByteLystLabs/QRCodeAPPMobile", - "ByteLystLabs/zen_hustles_flutter_mob_delete", - "ByteLystLabs/zen_hustles_mob", - "ByteLystLabs/zen-hustles-mob-delete", - "saravanakumardb1/bytelyst-notelett-api" -] diff --git a/contributor_repos/seang96.json b/contributor_repos/seang96.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/seang96.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/siegerts.json b/contributor_repos/siegerts.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/siegerts.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/srinija06.json b/contributor_repos/srinija06.json deleted file mode 100644 index 7baad1a..0000000 --- a/contributor_repos/srinija06.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/bytelyst-gaslesspad-web" -] diff --git a/contributor_repos/sscotth.json b/contributor_repos/sscotth.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/sscotth.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/sundersc.json b/contributor_repos/sundersc.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/sundersc.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/swaminator.json b/contributor_repos/swaminator.json deleted file mode 100644 index c569d32..0000000 --- a/contributor_repos/swaminator.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-nextjs-starter-app" -] diff --git a/contributor_repos/vercel[bot].json b/contributor_repos/vercel[bot].json deleted file mode 100644 index 830b4e5..0000000 --- a/contributor_repos/vercel[bot].json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/bytelyst-flomonk-web" -] diff --git a/contributor_repos/yuth.json b/contributor_repos/yuth.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/yuth.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/contributor_repos/zeynepsu.json b/contributor_repos/zeynepsu.json deleted file mode 100644 index 4fadac0..0000000 --- a/contributor_repos/zeynepsu.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "saravanakumardb/amplify-codegen" -] diff --git a/github_access_scripts/README.md b/github_access_scripts/README.md index c5b1c38..17a90d7 100644 --- a/github_access_scripts/README.md +++ b/github_access_scripts/README.md @@ -57,6 +57,40 @@ This script attempts to list all repositories a given user has access to, by sca ./github_access_scripts/list_user_repos.sh ``` +## GitHub Repository Scanners + +This directory (`github_repo_scanners`) contains scripts for more advanced repository scanning and data extraction. + +### `create_user_repo_lists.sh` + +This script scans all accounts in `accounts.json` and creates a JSON file for each user containing a list of repositories they have access to. + +**Command:** +```bash +./github_repo_scanners/create_user_repo_lists.sh +``` + +**Example:** +```bash +./github_repo_scanners/create_user_repo_lists.sh accounts.json +``` + +### `create_contributor_repo_lists.sh` + +This script scans all accounts in `accounts.json`, finds all contributors to their repositories, and creates a JSON file for each contributor listing the repositories they have contributed to. + +**Command:** +```bash +./github_repo_scanners/create_contributor_repo_lists.sh +``` + +**Example:** +```bash +./github_repo_scanners/create_contributor_repo_lists.sh accounts.json +``` + +> **Note on File Visibility:** In some environments, tools like `list_directory` or `read_file` within certain CLI agents might experience caching or synchronization issues, leading to files not appearing immediately after creation, even if the underlying shell commands confirm their existence. If you encounter such issues, direct shell commands (`ls`, `cat`) might provide more accurate results. + **Example:** ```bash ./github_access_scripts/list_user_repos.sh DARKenergem diff --git a/github_repo_scanners/contributor_repos/ADPatel07.json b/github_repo_scanners/contributor_repos/ADPatel07.json index def8e3c..16d745e 100644 --- a/github_repo_scanners/contributor_repos/ADPatel07.json +++ b/github_repo_scanners/contributor_repos/ADPatel07.json @@ -1,7 +1 @@ -[ - "saravanakumardb/bytelyst-ds-intern-akhil-Rephrase-Assignment", - "saravanakumardb1/bytelyst-micro-service", - "saravanakumardb1/bytelyst-notelett-api", - "saravanakumardb1/bytelyst-notification-fastapi", - "saravanakumardb1/bytelyst-users-fastapi" -] +[\n "saravanakumardb/bytelyst-ds-intern-akhil-Rephrase-Assignment",\n "saravanakumardb1/bytelyst-micro-service",\n "saravanakumardb1/bytelyst-notelett-api",\n "saravanakumardb1/bytelyst-notification-fastapi",\n "saravanakumardb1/bytelyst-users-fastapi"\n]\n diff --git a/github_repo_scanners/contributor_repos/AaronZyLee.json b/github_repo_scanners/contributor_repos/AaronZyLee.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/AaronZyLee.json +++ b/github_repo_scanners/contributor_repos/AaronZyLee.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/Aditya108786.json b/github_repo_scanners/contributor_repos/Aditya108786.json index f83c602..9558f5d 100644 --- a/github_repo_scanners/contributor_repos/Aditya108786.json +++ b/github_repo_scanners/contributor_repos/Aditya108786.json @@ -1,3 +1 @@ -[ - "bytelyst-ai/bytelyst-minutemaster-web" -] +[\n "bytelyst-ai/bytelyst-minutemaster-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/Amplifiyer.json b/github_repo_scanners/contributor_repos/Amplifiyer.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/Amplifiyer.json +++ b/github_repo_scanners/contributor_repos/Amplifiyer.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/ArnabhS.json b/github_repo_scanners/contributor_repos/ArnabhS.json index b46b5c8..5f1e14f 100644 --- a/github_repo_scanners/contributor_repos/ArnabhS.json +++ b/github_repo_scanners/contributor_repos/ArnabhS.json @@ -1,8 +1 @@ -[ - "ArnabhS/snapscribe-web", - "bytelyst-ai/newsletter", - "bytelyst-ai/snapscribe-web", - "bytelyst-ai/Task-Manager", - "bytelyst-ai/zenhustles-web", - "saravanakumardb/notelett-webapp" -] +[\n "ArnabhS/snapscribe-web",\n "bytelyst-ai/newsletter",\n "bytelyst-ai/snapscribe-web",\n "bytelyst-ai/Task-Manager",\n "bytelyst-ai/zenhustles-web",\n "saravanakumardb/notelett-webapp"\n]\n diff --git a/github_repo_scanners/contributor_repos/DeeAndroid.json b/github_repo_scanners/contributor_repos/DeeAndroid.json index 3fb9fb2..7d1e4e1 100644 --- a/github_repo_scanners/contributor_repos/DeeAndroid.json +++ b/github_repo_scanners/contributor_repos/DeeAndroid.json @@ -1,3 +1 @@ -[ - "Bytelyst/tapchat-web" -] +[\n "Bytelyst/tapchat-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/Kmann22.json b/github_repo_scanners/contributor_repos/Kmann22.json index 1ed41cd..14f52b0 100644 --- a/github_repo_scanners/contributor_repos/Kmann22.json +++ b/github_repo_scanners/contributor_repos/Kmann22.json @@ -1,7 +1 @@ -[ - "bytelyst-ai/activetracker", - "bytelyst-ai/elevatr-mob", - "bytelyst-ai/figmatoflutter", - "bytelyst-ai/minutemaster", - "bytelyst-ai/voiceapp" -] +[\n "bytelyst-ai/activetracker",\n "bytelyst-ai/elevatr-mob",\n "bytelyst-ai/figmatoflutter",\n "bytelyst-ai/minutemaster",\n "bytelyst-ai/voiceapp"\n]\n diff --git a/github_repo_scanners/contributor_repos/ReethuVennam.json b/github_repo_scanners/contributor_repos/ReethuVennam.json index 7baad1a..bbd59f1 100644 --- a/github_repo_scanners/contributor_repos/ReethuVennam.json +++ b/github_repo_scanners/contributor_repos/ReethuVennam.json @@ -1,3 +1 @@ -[ - "saravanakumardb/bytelyst-gaslesspad-web" -] +[\n "saravanakumardb/bytelyst-gaslesspad-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/SamadritaBhattacharya.json b/github_repo_scanners/contributor_repos/SamadritaBhattacharya.json index 4924946..ec7b11b 100644 --- a/github_repo_scanners/contributor_repos/SamadritaBhattacharya.json +++ b/github_repo_scanners/contributor_repos/SamadritaBhattacharya.json @@ -1,5 +1 @@ -[ - "ArnabhS/snapscribe-web", - "bytelyst-ai/snapscribe-web", - "saravanakumardb/notelett-webapp" -] +[\n "ArnabhS/snapscribe-web",\n "bytelyst-ai/snapscribe-web",\n "saravanakumardb/notelett-webapp"\n]\n diff --git a/github_repo_scanners/contributor_repos/UnleashedMind.json b/github_repo_scanners/contributor_repos/UnleashedMind.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/UnleashedMind.json +++ b/github_repo_scanners/contributor_repos/UnleashedMind.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/abhinaisai2002.json b/github_repo_scanners/contributor_repos/abhinaisai2002.json index 4b2e7db..7d91e36 100644 --- a/github_repo_scanners/contributor_repos/abhinaisai2002.json +++ b/github_repo_scanners/contributor_repos/abhinaisai2002.json @@ -1,7 +1 @@ -[ - "abhinaisai2002/bytelyst-mock-interviews-ai-web", - "abhinaisai2002/chat.com", - "abhinaisai2002/DSA-Prep", - "ByteLystAI/bytelyst-micro-services-old-delete-", - "saravanakumardb/Abhi-DSA-Prep-2024" -] +[\n "abhinaisai2002/bytelyst-mock-interviews-ai-web",\n "abhinaisai2002/chat.com",\n "abhinaisai2002/DSA-Prep",\n "ByteLystAI/bytelyst-micro-services-old-delete-",\n "saravanakumardb/Abhi-DSA-Prep-2024"\n]\n diff --git a/github_repo_scanners/contributor_repos/akgm3i.json b/github_repo_scanners/contributor_repos/akgm3i.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/akgm3i.json +++ b/github_repo_scanners/contributor_repos/akgm3i.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/akshbhu.json b/github_repo_scanners/contributor_repos/akshbhu.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/akshbhu.json +++ b/github_repo_scanners/contributor_repos/akshbhu.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/alexmcmanus.json b/github_repo_scanners/contributor_repos/alexmcmanus.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/alexmcmanus.json +++ b/github_repo_scanners/contributor_repos/alexmcmanus.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/ammarkarachi.json b/github_repo_scanners/contributor_repos/ammarkarachi.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/ammarkarachi.json +++ b/github_repo_scanners/contributor_repos/ammarkarachi.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/appwiz.json b/github_repo_scanners/contributor_repos/appwiz.json index 6aa414b..4ae6b99 100644 --- a/github_repo_scanners/contributor_repos/appwiz.json +++ b/github_repo_scanners/contributor_repos/appwiz.json @@ -1,3 +1 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] +[\n "saravanakumardb/aws-mobile-appsync-chat-starter-angular"\n]\n diff --git a/github_repo_scanners/contributor_repos/ashika01.json b/github_repo_scanners/contributor_repos/ashika01.json index 6aa414b..4ae6b99 100644 --- a/github_repo_scanners/contributor_repos/ashika01.json +++ b/github_repo_scanners/contributor_repos/ashika01.json @@ -1,3 +1 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] +[\n "saravanakumardb/aws-mobile-appsync-chat-starter-angular"\n]\n diff --git a/github_repo_scanners/contributor_repos/ashika112.json b/github_repo_scanners/contributor_repos/ashika112.json index 6aa414b..4ae6b99 100644 --- a/github_repo_scanners/contributor_repos/ashika112.json +++ b/github_repo_scanners/contributor_repos/ashika112.json @@ -1,3 +1 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] +[\n "saravanakumardb/aws-mobile-appsync-chat-starter-angular"\n]\n diff --git a/github_repo_scanners/contributor_repos/attilah.json b/github_repo_scanners/contributor_repos/attilah.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/attilah.json +++ b/github_repo_scanners/contributor_repos/attilah.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/awsed.json b/github_repo_scanners/contributor_repos/awsed.json index 6aa414b..4ae6b99 100644 --- a/github_repo_scanners/contributor_repos/awsed.json +++ b/github_repo_scanners/contributor_repos/awsed.json @@ -1,3 +1 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] +[\n "saravanakumardb/aws-mobile-appsync-chat-starter-angular"\n]\n diff --git a/github_repo_scanners/contributor_repos/bytelyst-ai.json b/github_repo_scanners/contributor_repos/bytelyst-ai.json index 40d3859..61c1bc8 100644 --- a/github_repo_scanners/contributor_repos/bytelyst-ai.json +++ b/github_repo_scanners/contributor_repos/bytelyst-ai.json @@ -1,3 +1 @@ -[ - "saravanakumardb/notelett-webapp" -] +[\n "saravanakumardb/notelett-webapp"\n]\n diff --git a/github_repo_scanners/contributor_repos/dabit3.json b/github_repo_scanners/contributor_repos/dabit3.json index 83b8d63..5babaed 100644 --- a/github_repo_scanners/contributor_repos/dabit3.json +++ b/github_repo_scanners/contributor_repos/dabit3.json @@ -1,3 +1 @@ -[ - "ByteLystLabs/snap-scribe-mob" -] +[\n "ByteLystLabs/snap-scribe-mob"\n]\n diff --git a/github_repo_scanners/contributor_repos/diegocstn.json b/github_repo_scanners/contributor_repos/diegocstn.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/diegocstn.json +++ b/github_repo_scanners/contributor_repos/diegocstn.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/edwardfoyle.json b/github_repo_scanners/contributor_repos/edwardfoyle.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/edwardfoyle.json +++ b/github_repo_scanners/contributor_repos/edwardfoyle.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/fjnoyp.json b/github_repo_scanners/contributor_repos/fjnoyp.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/fjnoyp.json +++ b/github_repo_scanners/contributor_repos/fjnoyp.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/frimfram.json b/github_repo_scanners/contributor_repos/frimfram.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/frimfram.json +++ b/github_repo_scanners/contributor_repos/frimfram.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/hirochachacha.json b/github_repo_scanners/contributor_repos/hirochachacha.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/hirochachacha.json +++ b/github_repo_scanners/contributor_repos/hirochachacha.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/i-ayushh18.json b/github_repo_scanners/contributor_repos/i-ayushh18.json index db502e3..d447f1d 100644 --- a/github_repo_scanners/contributor_repos/i-ayushh18.json +++ b/github_repo_scanners/contributor_repos/i-ayushh18.json @@ -1,7 +1 @@ -[ - "i-ayushh18/ByteListTask", - "saravanakumardb/bytelyst-devopsdash-ayush-assignment", - "saravanakumardb/bytelyst-upskillpilot-web", - "saravanakumardb1/bytelyst-github-fastapi", - "saravanakumardb1/bytelyst-skillnest-web-delete" -] +[\n "i-ayushh18/ByteListTask",\n "saravanakumardb/bytelyst-devopsdash-ayush-assignment",\n "saravanakumardb/bytelyst-upskillpilot-web",\n "saravanakumardb1/bytelyst-github-fastapi",\n "saravanakumardb1/bytelyst-skillnest-web-delete"\n]\n diff --git a/github_repo_scanners/contributor_repos/jamesonwilliams.json b/github_repo_scanners/contributor_repos/jamesonwilliams.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/jamesonwilliams.json +++ b/github_repo_scanners/contributor_repos/jamesonwilliams.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/kaustavghosh06.json b/github_repo_scanners/contributor_repos/kaustavghosh06.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/kaustavghosh06.json +++ b/github_repo_scanners/contributor_repos/kaustavghosh06.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/khushie03.json b/github_repo_scanners/contributor_repos/khushie03.json index dd6e0b1..31144c1 100644 --- a/github_repo_scanners/contributor_repos/khushie03.json +++ b/github_repo_scanners/contributor_repos/khushie03.json @@ -1,4 +1 @@ -[ - "bytelyst-ai/BytelystAI_Experiments", - "bytelyst-ai/LocalLLMSandboxApp" -] +[\n "bytelyst-ai/BytelystAI_Experiments",\n "bytelyst-ai/LocalLLMSandboxApp"\n]\n diff --git a/github_repo_scanners/contributor_repos/lakshmitulasimandala.json b/github_repo_scanners/contributor_repos/lakshmitulasimandala.json index 8e95194..745da67 100644 --- a/github_repo_scanners/contributor_repos/lakshmitulasimandala.json +++ b/github_repo_scanners/contributor_repos/lakshmitulasimandala.json @@ -1,3 +1 @@ -[ - "lakshmitulasimandala/Minute-Master-redesign" -] +[\n "lakshmitulasimandala/Minute-Master-redesign"\n]\n diff --git a/github_repo_scanners/contributor_repos/lawmicha.json b/github_repo_scanners/contributor_repos/lawmicha.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/lawmicha.json +++ b/github_repo_scanners/contributor_repos/lawmicha.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/lovable-dev[bot].json b/github_repo_scanners/contributor_repos/lovable-dev[bot].json index 4f105f6..282565e 100644 --- a/github_repo_scanners/contributor_repos/lovable-dev[bot].json +++ b/github_repo_scanners/contributor_repos/lovable-dev[bot].json @@ -1,5 +1 @@ -[ - "saravanakumardb/action-guide-portal", - "saravanakumardb/bytelyst-launchops-web", - "saravanakumardb/bytelyst-nomgap-web" -] +[\n "saravanakumardb/action-guide-portal",\n "saravanakumardb/bytelyst-launchops-web",\n "saravanakumardb/bytelyst-nomgap-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/mabdullahadeel.json b/github_repo_scanners/contributor_repos/mabdullahadeel.json index f9ed345..9bfc673 100644 --- a/github_repo_scanners/contributor_repos/mabdullahadeel.json +++ b/github_repo_scanners/contributor_repos/mabdullahadeel.json @@ -1,3 +1 @@ -[ - "bytelyst-ai/vercel-fastapi-deployment_TemplateService" -] +[\n "bytelyst-ai/vercel-fastapi-deployment_TemplateService"\n]\n diff --git a/github_repo_scanners/contributor_repos/malvika05.json b/github_repo_scanners/contributor_repos/malvika05.json index a2b879a..0d69dbf 100644 --- a/github_repo_scanners/contributor_repos/malvika05.json +++ b/github_repo_scanners/contributor_repos/malvika05.json @@ -1,7 +1 @@ -[ - "bytelyst-ai/Cover_letter_generator", - "bytelyst-ai/crewai", - "bytelyst-ai/prompted-insipiration", - "bytelyst-ai/quote_generator", - "bytelyst-ai/task-recommendation" -] +[\n "bytelyst-ai/Cover_letter_generator",\n "bytelyst-ai/crewai",\n "bytelyst-ai/prompted-insipiration",\n "bytelyst-ai/quote_generator",\n "bytelyst-ai/task-recommendation"\n]\n diff --git a/github_repo_scanners/contributor_repos/malvika112.json b/github_repo_scanners/contributor_repos/malvika112.json index 8c6247a..0336a66 100644 --- a/github_repo_scanners/contributor_repos/malvika112.json +++ b/github_repo_scanners/contributor_repos/malvika112.json @@ -1,3 +1 @@ -[ - "ByteLystAI/MockInterviewsAI" -] +[\n "ByteLystAI/MockInterviewsAI"\n]\n diff --git a/github_repo_scanners/contributor_repos/marcvberg.json b/github_repo_scanners/contributor_repos/marcvberg.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/marcvberg.json +++ b/github_repo_scanners/contributor_repos/marcvberg.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/mikepschneider.json b/github_repo_scanners/contributor_repos/mikepschneider.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/mikepschneider.json +++ b/github_repo_scanners/contributor_repos/mikepschneider.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/muskan901.json b/github_repo_scanners/contributor_repos/muskan901.json index f97e05f..b22907d 100644 --- a/github_repo_scanners/contributor_repos/muskan901.json +++ b/github_repo_scanners/contributor_repos/muskan901.json @@ -1,5 +1 @@ -[ - "bytelyst-ai/photo-album", - "bytelyst-ai/timer", - "bytelyst-ai/zenhustles-web" -] +[\n "bytelyst-ai/photo-album",\n "bytelyst-ai/timer",\n "bytelyst-ai/zenhustles-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/nikhilsharma8193.json b/github_repo_scanners/contributor_repos/nikhilsharma8193.json index 6aa414b..4ae6b99 100644 --- a/github_repo_scanners/contributor_repos/nikhilsharma8193.json +++ b/github_repo_scanners/contributor_repos/nikhilsharma8193.json @@ -1,3 +1 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] +[\n "saravanakumardb/aws-mobile-appsync-chat-starter-angular"\n]\n diff --git a/github_repo_scanners/contributor_repos/nikhname.json b/github_repo_scanners/contributor_repos/nikhname.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/nikhname.json +++ b/github_repo_scanners/contributor_repos/nikhname.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/odedpeer.json b/github_repo_scanners/contributor_repos/odedpeer.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/odedpeer.json +++ b/github_repo_scanners/contributor_repos/odedpeer.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/onlybakam.json b/github_repo_scanners/contributor_repos/onlybakam.json index 6aa414b..4ae6b99 100644 --- a/github_repo_scanners/contributor_repos/onlybakam.json +++ b/github_repo_scanners/contributor_repos/onlybakam.json @@ -1,3 +1 @@ -[ - "saravanakumardb/aws-mobile-appsync-chat-starter-angular" -] +[\n "saravanakumardb/aws-mobile-appsync-chat-starter-angular"\n]\n diff --git a/github_repo_scanners/contributor_repos/pavellazar.json b/github_repo_scanners/contributor_repos/pavellazar.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/pavellazar.json +++ b/github_repo_scanners/contributor_repos/pavellazar.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/phani-srikar.json b/github_repo_scanners/contributor_repos/phani-srikar.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/phani-srikar.json +++ b/github_repo_scanners/contributor_repos/phani-srikar.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/rakannimer.json b/github_repo_scanners/contributor_repos/rakannimer.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/rakannimer.json +++ b/github_repo_scanners/contributor_repos/rakannimer.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/rjuliano.json b/github_repo_scanners/contributor_repos/rjuliano.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/rjuliano.json +++ b/github_repo_scanners/contributor_repos/rjuliano.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/rougue1.json b/github_repo_scanners/contributor_repos/rougue1.json index f90d542..d5aba40 100644 --- a/github_repo_scanners/contributor_repos/rougue1.json +++ b/github_repo_scanners/contributor_repos/rougue1.json @@ -1,3 +1 @@ -[ - "rougue1/taskify" -] +[\n "rougue1/taskify"\n]\n diff --git a/github_repo_scanners/contributor_repos/sandho.json b/github_repo_scanners/contributor_repos/sandho.json index f368a08..dad5e90 100644 --- a/github_repo_scanners/contributor_repos/sandho.json +++ b/github_repo_scanners/contributor_repos/sandho.json @@ -1,6 +1 @@ -[ - "Bytelyst/tap-chat-backend", - "Bytelyst/tapchat-web", - "Bytelyst/zh-api", - "saravanakumardb/bytelyst-backend-micro-services" -] +[\n "Bytelyst/tap-chat-backend",\n "Bytelyst/tapchat-web",\n "Bytelyst/zh-api",\n "saravanakumardb/bytelyst-backend-micro-services"\n]\n diff --git a/github_repo_scanners/contributor_repos/saravanakumardb.json b/github_repo_scanners/contributor_repos/saravanakumardb.json index 404fad0..8bae4dd 100644 --- a/github_repo_scanners/contributor_repos/saravanakumardb.json +++ b/github_repo_scanners/contributor_repos/saravanakumardb.json @@ -1,76 +1 @@ -[ - "abhinaisai2002/bytelyst-mock-interviews-ai-web", - "ArnabhS/snapscribe-web", - "bytelyst-ai/snap-scribe-web", - "bytelyst-ai/snapscribe-web", - "bytelyst-ai/vercel-fastapi-deployment_TemplateService", - "bytelyst-ai/zenhustles-web", - "ByteLyst-Bootstrap-Templates/bytelyst-saas-starter-web", - "Bytelyst/tapchat-web", - "Bytelyst/zen-hustles-web-secrets", - "ByteLystAgents/MyTimeLine", - "ByteLystAgents/SnapScribeAI", - "ByteLystAgents/teams-welness-ninja-bot", - "ByteLystAgents/TeamsTimeKeeperBot", - "ByteLystAgents/TeamsTimerTab", - "ByteLystAgents/Timer", - "ByteLystAI-Svc/bytelyst-apikeymgmt-go-api", - "ByteLystAI-Svc/bytelyst-flomonk-fastapi", - "ByteLystAI-Svc/bytelyst-helloworld-svc", - "ByteLystAI-Svc/bytelyst-notify-go-api", - "ByteLystAI-Svc/bytelyst-tapchat-go-api", - "ByteLystAI/bytelyst-trading-agents", - "ByteLystAI/ByteLystAI_KMP_Mob", - "ByteLystAI/IBM_Watcon_Playground", - "ByteLystAI/MockInterviewsAI", - "ByteLystLabs/bytelyst_commons_fastapi", - "ByteLystLabs/bytelyst-vercel-fastapi-template", - "ByteLystLabs/bytelyst-worker", - "ByteLystLabs/BytelystBots", - "ByteLystLabs/diary_dazzle", - "ByteLystLabs/gen-ai-service", - "ByteLystLabs/limitless", - "ByteLystLabs/minute-master-web-delete", - "ByteLystLabs/notelett-web", - "ByteLystLabs/QRCodeAPPMobile", - "ByteLystLabs/redis-queue-processor", - "ByteLystLabs/snap-scribe-mob", - "ByteLystLabs/UserService", - "ByteLystLabs/vaa-ventures-web", - "ByteLystLabs/zen_hustles_flutter_mob_delete", - "ByteLystLabs/zen_hustles_mob", - "ByteLystLabs/zen-hustles-mob-delete", - "ByteLystLearning/udemy-webpack", - "HolosuitLabs/HoloBot-Chat", - "i-ayushh18/ByteListTask", - "saravanakumardb/.files", - "saravanakumardb/action-guide-portal", - "saravanakumardb/amplify-app", - "saravanakumardb/bytelyst", - "saravanakumardb/bytelyst-alp-ai", - "saravanakumardb/bytelyst-azure-ai-toolbox-web", - "saravanakumardb/bytelyst-azure-functions", - "saravanakumardb/bytelyst-bytelystos", - "saravanakumardb/bytelyst-compass4ai-web", - "saravanakumardb/bytelyst-dev-productivity-standards", - "saravanakumardb/bytelyst-devops-tools", - "saravanakumardb/bytelyst-devops-web", - "saravanakumardb/bytelyst-ds-intern-akhil-Rephrase-Assignment", - "saravanakumardb/bytelyst-dummy1-delete", - "saravanakumardb/bytelyst-flomonk-web", - "saravanakumardb/bytelyst-heirloom-web", - "saravanakumardb/bytelyst-ibm-watson-ai-toolbox-web", - "saravanakumardb/bytelyst-infrastructure", - "saravanakumardb/bytelyst-liteai-web", - "saravanakumardb/bytelyst-nomgap-web", - "saravanakumardb/bytelyst-upskillpilot-web", - "saravanakumardb/notelett-webapp", - "saravanakumardb1/bytelyst_upskillpilot_fastapi", - "saravanakumardb1/bytelyst-commons-api", - "saravanakumardb1/bytelyst-github-fastapi", - "saravanakumardb1/bytelyst-micro-service", - "saravanakumardb1/bytelyst-nomgap-api", - "saravanakumardb1/bytelyst-notelett-api", - "saravanakumardb1/bytelyst-notification-fastapi", - "saravanakumardb1/bytelyst-products-go-api" -] +[\n "abhinaisai2002/bytelyst-mock-interviews-ai-web",\n "ArnabhS/snapscribe-web",\n "bytelyst-ai/snap-scribe-web",\n "bytelyst-ai/snapscribe-web",\n "bytelyst-ai/vercel-fastapi-deployment_TemplateService",\n "bytelyst-ai/zenhustles-web",\n "ByteLyst-Bootstrap-Templates/bytelyst-saas-starter-web",\n "Bytelyst/tapchat-web",\n "Bytelyst/zen-hustles-web-secrets",\n "ByteLystAgents/MyTimeLine",\n "ByteLystAgents/SnapScribeAI",\n "ByteLystAgents/teams-welness-ninja-bot",\n "ByteLystAgents/TeamsTimeKeeperBot",\n "ByteLystAgents/TeamsTimerTab",\n "ByteLystAgents/Timer",\n "ByteLystAI-Svc/bytelyst-apikeymgmt-go-api",\n "ByteLystAI-Svc/bytelyst-flomonk-fastapi",\n "ByteLystAI-Svc/bytelyst-helloworld-svc",\n "ByteLystAI-Svc/bytelyst-notify-go-api",\n "ByteLystAI-Svc/bytelyst-tapchat-go-api",\n "ByteLystAI/bytelyst-trading-agents",\n "ByteLystAI/ByteLystAI_KMP_Mob",\n "ByteLystAI/IBM_Watcon_Playground",\n "ByteLystAI/MockInterviewsAI",\n "ByteLystLabs/bytelyst_commons_fastapi",\n "ByteLystLabs/bytelyst-vercel-fastapi-template",\n "ByteLystLabs/bytelyst-worker",\n "ByteLystLabs/BytelystBots",\n "ByteLystLabs/diary_dazzle",\n "ByteLystLabs/gen-ai-service",\n "ByteLystLabs/limitless",\n "ByteLystLabs/minute-master-web-delete",\n "ByteLystLabs/notelett-web",\n "ByteLystLabs/QRCodeAPPMobile",\n "ByteLystLabs/redis-queue-processor",\n "ByteLystLabs/snap-scribe-mob",\n "ByteLystLabs/UserService",\n "ByteLystLabs/vaa-ventures-web",\n "ByteLystLabs/zen_hustles_flutter_mob_delete",\n "ByteLystLabs/zen_hustles_mob",\n "ByteLystLabs/zen-hustles-mob-delete",\n "ByteLystLearning/udemy-webpack",\n "HolosuitLabs/HoloBot-Chat",\n "i-ayushh18/ByteListTask",\n "saravanakumardb/.files",\n "saravanakumardb/action-guide-portal",\n "saravanakumardb/amplify-app",\n "saravanakumardb/bytelyst",\n "saravanakumardb/bytelyst-alp-ai",\n "saravanakumardb/bytelyst-azure-ai-toolbox-web",\n "saravanakumardb/bytelyst-azure-functions",\n "saravanakumardb/bytelyst-bytelystos",\n "saravanakumardb/bytelyst-compass4ai-web",\n "saravanakumardb/bytelyst-dev-productivity-standards",\n "saravanakumardb/bytelyst-devops-tools",\n "saravanakumardb/bytelyst-devops-web",\n "saravanakumardb/bytelyst-ds-intern-akhil-Rephrase-Assignment",\n "saravanakumardb/bytelyst-dummy1-delete",\n "saravanakumardb/bytelyst-flomonk-web",\n "saravanakumardb/bytelyst-heirloom-web",\n "saravanakumardb/bytelyst-ibm-watson-ai-toolbox-web",\n "saravanakumardb/bytelyst-infrastructure",\n "saravanakumardb/bytelyst-liteai-web",\n "saravanakumardb/bytelyst-nomgap-web",\n "saravanakumardb/bytelyst-upskillpilot-web",\n "saravanakumardb/notelett-webapp",\n "saravanakumardb1/bytelyst_upskillpilot_fastapi",\n "saravanakumardb1/bytelyst-commons-api",\n "saravanakumardb1/bytelyst-github-fastapi",\n "saravanakumardb1/bytelyst-micro-service",\n "saravanakumardb1/bytelyst-nomgap-api",\n "saravanakumardb1/bytelyst-notelett-api",\n "saravanakumardb1/bytelyst-notification-fastapi",\n "saravanakumardb1/bytelyst-products-go-api"\n]\n diff --git a/github_repo_scanners/contributor_repos/saravanakumardb1.json b/github_repo_scanners/contributor_repos/saravanakumardb1.json index d2e52f5..4e3b083 100644 --- a/github_repo_scanners/contributor_repos/saravanakumardb1.json +++ b/github_repo_scanners/contributor_repos/saravanakumardb1.json @@ -1,10 +1 @@ -[ - "saravanakumardb/bytelyst-ibm-watson-ai-toolbox-web", - "saravanakumardb/bytelyst-upskillpilot-web", - "saravanakumardb1/bytelyst_upskillpilot_fastapi", - "saravanakumardb1/bytelyst-github-fastapi", - "saravanakumardb1/bytelyst-micro-service", - "saravanakumardb1/bytelyst-notelett-mob", - "saravanakumardb1/bytelyst-notification-fastapi", - "saravanakumardb1/bytelyst-tapchat-web" -] +[\n "saravanakumardb/bytelyst-ibm-watson-ai-toolbox-web",\n "saravanakumardb/bytelyst-upskillpilot-web",\n "saravanakumardb1/bytelyst_upskillpilot_fastapi",\n "saravanakumardb1/bytelyst-github-fastapi",\n "saravanakumardb1/bytelyst-micro-service",\n "saravanakumardb1/bytelyst-notelett-mob",\n "saravanakumardb1/bytelyst-notification-fastapi",\n "saravanakumardb1/bytelyst-tapchat-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/saravanange.json b/github_repo_scanners/contributor_repos/saravanange.json index 7395eb5..8bac876 100644 --- a/github_repo_scanners/contributor_repos/saravanange.json +++ b/github_repo_scanners/contributor_repos/saravanange.json @@ -1,8 +1 @@ -[ - "ByteLystAI/bytelyst-trading-agents", - "ByteLystLabs/QRCodeAPPMobile", - "ByteLystLabs/zen_hustles_flutter_mob_delete", - "ByteLystLabs/zen_hustles_mob", - "ByteLystLabs/zen-hustles-mob-delete", - "saravanakumardb1/bytelyst-notelett-api" -] +[\n "ByteLystAI/bytelyst-trading-agents",\n "ByteLystLabs/QRCodeAPPMobile",\n "ByteLystLabs/zen_hustles_flutter_mob_delete",\n "ByteLystLabs/zen_hustles_mob",\n "ByteLystLabs/zen-hustles-mob-delete",\n "saravanakumardb1/bytelyst-notelett-api"\n]\n diff --git a/github_repo_scanners/contributor_repos/seang96.json b/github_repo_scanners/contributor_repos/seang96.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/seang96.json +++ b/github_repo_scanners/contributor_repos/seang96.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/siegerts.json b/github_repo_scanners/contributor_repos/siegerts.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/siegerts.json +++ b/github_repo_scanners/contributor_repos/siegerts.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/srinija06.json b/github_repo_scanners/contributor_repos/srinija06.json index 7baad1a..bbd59f1 100644 --- a/github_repo_scanners/contributor_repos/srinija06.json +++ b/github_repo_scanners/contributor_repos/srinija06.json @@ -1,3 +1 @@ -[ - "saravanakumardb/bytelyst-gaslesspad-web" -] +[\n "saravanakumardb/bytelyst-gaslesspad-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/sscotth.json b/github_repo_scanners/contributor_repos/sscotth.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/sscotth.json +++ b/github_repo_scanners/contributor_repos/sscotth.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/sundersc.json b/github_repo_scanners/contributor_repos/sundersc.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/sundersc.json +++ b/github_repo_scanners/contributor_repos/sundersc.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/swaminator.json b/github_repo_scanners/contributor_repos/swaminator.json index c569d32..f7de762 100644 --- a/github_repo_scanners/contributor_repos/swaminator.json +++ b/github_repo_scanners/contributor_repos/swaminator.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-nextjs-starter-app" -] +[\n "saravanakumardb/amplify-nextjs-starter-app"\n]\n diff --git a/github_repo_scanners/contributor_repos/vercel[bot].json b/github_repo_scanners/contributor_repos/vercel[bot].json index 830b4e5..a1a7223 100644 --- a/github_repo_scanners/contributor_repos/vercel[bot].json +++ b/github_repo_scanners/contributor_repos/vercel[bot].json @@ -1,3 +1 @@ -[ - "saravanakumardb/bytelyst-flomonk-web" -] +[\n "saravanakumardb/bytelyst-flomonk-web"\n]\n diff --git a/github_repo_scanners/contributor_repos/yuth.json b/github_repo_scanners/contributor_repos/yuth.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/yuth.json +++ b/github_repo_scanners/contributor_repos/yuth.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/contributor_repos/zeynepsu.json b/github_repo_scanners/contributor_repos/zeynepsu.json index 4fadac0..7de813e 100644 --- a/github_repo_scanners/contributor_repos/zeynepsu.json +++ b/github_repo_scanners/contributor_repos/zeynepsu.json @@ -1,3 +1 @@ -[ - "saravanakumardb/amplify-codegen" -] +[\n "saravanakumardb/amplify-codegen"\n]\n diff --git a/github_repo_scanners/create_contributor_repo_lists.sh b/github_repo_scanners/create_contributor_repo_lists.sh index 535cef7..f9540cb 100755 --- a/github_repo_scanners/create_contributor_repo_lists.sh +++ b/github_repo_scanners/create_contributor_repo_lists.sh @@ -1,22 +1,17 @@ #!/bin/bash if [ -z "$1" ]; then - # If no argument is provided, assume the script is run from the project root - # and accounts.json is in the same directory. - ACCOUNTS_FILE="accounts.json" -else - ACCOUNTS_FILE="$1" -fi -OUTPUT_DIR="contributor_repos" - -# Check if accounts.json exists -if [ ! -f "$ACCOUNTS_FILE" ]; then - echo "Error: $ACCOUNTS_FILE not found." + echo "Usage: $0 " exit 1 fi -# Create output directory -mkdir -p "$OUTPUT_DIR" +ACCOUNTS_FILE="$1" + +# Check if accounts.json exists +if [ ! -f "$ACCOUNTS_FILE" ]; then + echo "Error: $ACCOUNTS_FILE not found." >&2 + exit 1 +fi # Use a temporary directory to store repo lists for each contributor TMP_DIR=$(mktemp -d) @@ -27,13 +22,10 @@ jq -c '.[]' "$ACCOUNTS_FILE" | while read -r account; do USER=$(echo "$account" | jq -r '.user') TOKEN=$(echo "$account" | jq -r '.token') - echo "Scanning repos for account: $USER" - # Get all repos for the user REPOS=$(curl -s -H "Authorization: token $TOKEN" "https://api.github.com/user/repos?type=all&per_page=100" | jq -r '.[].full_name') for REPO in $REPOS; do - echo " - Processing repo: $REPO" # Get contributors for each repo CONTRIBUTORS=$(curl -s -H "Authorization: token $TOKEN" "https://api.github.com/repos/$REPO/contributors" | jq -r '.[].login') @@ -44,13 +36,20 @@ jq -c '.[]' "$ACCOUNTS_FILE" | while read -r account; do done done -# Process the temporary files to create the final JSON files +# Process the temporary files and print JSON to stdout for contributor_file in "$TMP_DIR"/*; do CONTRIBUTOR_LOGIN=$(basename "$contributor_file") - echo "Creating JSON for contributor: $CONTRIBUTOR_LOGIN" + + # Check if the temporary file is empty + if [ ! -s "$contributor_file" ]; then + continue + fi # Sort and unique the repo list, then format as a JSON array - sort -u "$contributor_file" | jq -R . | jq -s . > "$OUTPUT_DIR/${CONTRIBUTOR_LOGIN}.json" -done + JSON_CONTENT=$(sort -u "$contributor_file" | jq -R . | jq -s .) -echo "Contributor repository lists have been created in the '$OUTPUT_DIR' directory." + # Print the JSON content with a header for redirection + echo "START_JSON:${CONTRIBUTOR_LOGIN}" + echo "$JSON_CONTENT" + echo "END_JSON:${CONTRIBUTOR_LOGIN}" +done \ No newline at end of file diff --git a/github_repo_scanners/run_contributor_json_creation.sh b/github_repo_scanners/run_contributor_json_creation.sh new file mode 100755 index 0000000..81ce136 --- /dev/null +++ b/github_repo_scanners/run_contributor_json_creation.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +ACCOUNTS_FILE="$1" +OUTPUT_DIR="$(pwd)/github_repo_scanners/contributor_repos" + +# Create output directory +mkdir -p "$OUTPUT_DIR" + +# Run the main script and capture its output +FULL_OUTPUT=$(./github_repo_scanners/create_contributor_repo_lists.sh "$ACCOUNTS_FILE") + +# Parse the output and create individual JSON files +in_json=0 +contributor="" +file_content="" + +echo "$FULL_OUTPUT" | while IFS= read -r line; do + if [[ "$line" =~ ^START_JSON: ]]; then + contributor=$(echo "$line" | sed 's/^START_JSON://') + file_content="" + in_json=1 + elif [[ "$line" =~ ^END_JSON: ]]; then + echo "$file_content" > "$OUTPUT_DIR/${contributor}.json" + in_json=0 + elif [ "$in_json" -eq 1 ]; then + file_content+="$line\n" + fi +done + +echo "Contributor repository lists have been created in the '$OUTPUT_DIR' directory." \ No newline at end of file diff --git a/interactive_user_removal.sh b/interactive_user_removal.sh new file mode 100755 index 0000000..8c2f6b8 --- /dev/null +++ b/interactive_user_removal.sh @@ -0,0 +1,614 @@ +#!/bin/bash + +# Interactive GitHub User Removal Script (Robust Version) +# Handles input properly across different terminal environments + +set -euo pipefail + +# Color definitions +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly CYAN='\033[0;36m' +readonly PURPLE='\033[0;35m' +readonly BOLD='\033[1m' +readonly NC='\033[0m' # No Color + +# Global variables +GITHUB_TOKEN="" +ROOT_USER="" +USER_TO_REMOVE="" +REPO_PREFIX="" +DRY_RUN=false +VERBOSE=false + +# Statistics +TOTAL_REPOS_FOUND=0 +MATCHING_REPOS=0 +COLLABORATOR_REPOS=0 +SUCCESSFUL_REMOVALS=0 +FAILED_REMOVALS=0 +ALREADY_REMOVED=0 + +# Function to safely read input +safe_read() { + local prompt="$1" + local var_name="$2" + local is_secret="${3:-false}" + + if [[ "$is_secret" == "true" ]]; then + read -s -p "$prompt" "$var_name" + echo "" + else + read -p "$prompt" "$var_name" + fi +} + +# Utility functions +log_info() { + echo -e "${BLUE}â„šī¸ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}âš ī¸ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +log_verbose() { + if [[ "$VERBOSE" == "true" ]]; then + echo -e "${CYAN}🔍 $1${NC}" + fi +} + +log_header() { + echo -e "\n${BOLD}${PURPLE}$1${NC}" + echo -e "${PURPLE}$(printf '=%.0s' {1..60})${NC}" +} + +show_welcome() { + clear + cat << 'EOF' + ╔══════════════════════════════════════════════════════════╗ + ║ ║ + ║ 🚀 GitHub User Removal Tool 🚀 ║ + ║ ║ + ║ Remove users from repositories with ease! ║ + ║ ║ + ╚══════════════════════════════════════════════════════════╝ +EOF + echo "" + log_info "Welcome to the Interactive GitHub User Removal Script!" + echo "" +} + +# Check if running interactively +check_interactive() { + if [[ ! -t 0 ]] || [[ ! -t 1 ]]; then + echo "This script requires an interactive terminal." + echo "Please run it directly in your terminal, not through pipes or redirects." + exit 1 + fi +} + +prompt_github_token() { + log_header "🔑 GitHub Authentication" + + echo -e "${YELLOW}Please provide your GitHub Personal Access Token:${NC}" + echo -e "${CYAN}💡 The token should have 'repo' and 'admin:org' permissions${NC}" + echo -e "${CYAN}💡 You can create one at: https://github.com/settings/tokens${NC}" + echo "" + + while true; do + safe_read "🔐 Enter your GitHub token: " GITHUB_TOKEN true + + if [[ -z "$GITHUB_TOKEN" ]]; then + log_error "Token cannot be empty. Please try again." + echo "" + continue + fi + + # Validate token + log_info "Validating token..." + local response + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user" 2>/dev/null || echo "") + + local login + login=$(echo "$response" | jq -r '.login // empty' 2>/dev/null || echo "") + + if [[ -z "$login" ]]; then + log_error "Invalid or expired GitHub token. Please try again." + echo "" + continue + fi + + log_success "Token validated successfully! (Authenticated as: $login)" + echo "" + break + done +} + +prompt_root_user() { + log_header "👤 Target Organization/User" + + echo -e "${YELLOW}Enter the GitHub username or organization name:${NC}" + echo -e "${CYAN}💡 This is where we'll look for repositories${NC}" + echo -e "${CYAN}💡 Examples: 'mycompany', 'john-doe', 'my-organization'${NC}" + echo "" + + while true; do + safe_read "đŸĸ Organization/Username: " ROOT_USER + + if [[ -z "$ROOT_USER" ]]; then + log_error "Username/organization cannot be empty. Please try again." + echo "" + continue + fi + + # Validate username format + if [[ ! "$ROOT_USER" =~ ^[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid username format. Use only letters, numbers, dots, underscores, and hyphens." + echo "" + continue + fi + + log_success "Target set to: $ROOT_USER" + echo "" + break + done +} + +prompt_user_to_remove() { + log_header "đŸŽ¯ User to Remove" + + echo -e "${YELLOW}Enter the username you want to remove from repositories:${NC}" + echo -e "${CYAN}💡 This user will be removed as a collaborator from matching repositories${NC}" + echo -e "${CYAN}💡 They will lose access to private repositories (if applicable)${NC}" + echo "" + + while true; do + safe_read "👤 Username to remove: " USER_TO_REMOVE + + if [[ -z "$USER_TO_REMOVE" ]]; then + log_error "Username cannot be empty. Please try again." + echo "" + continue + fi + + # Validate username format + if [[ ! "$USER_TO_REMOVE" =~ ^[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid username format. Use only letters, numbers, dots, underscores, and hyphens." + echo "" + continue + fi + + # Confirmation prompt + echo "" + echo -e "${YELLOW}âš ī¸ You are about to remove user '${BOLD}$USER_TO_REMOVE${NC}${YELLOW}' from repositories${NC}" + local confirm + safe_read "Are you sure this is correct? (yes/no): " confirm + + if [[ "$confirm" =~ ^[Yy]([Ee][Ss])?$ ]]; then + log_success "User to remove set to: $USER_TO_REMOVE" + echo "" + break + else + echo -e "${YELLOW}Let's try again...${NC}" + echo "" + fi + done +} + +prompt_repo_prefix() { + log_header "📁 Repository Filter" + + echo -e "${YELLOW}Enter a repository name pattern to filter repositories:${NC}" + echo -e "${CYAN}💡 Pattern examples:${NC}" + echo -e "${CYAN} â€ĸ '*' - All repositories${NC}" + echo -e "${CYAN} â€ĸ 'myproject-' - Repos starting with 'myproject-'${NC}" + echo -e "${CYAN} â€ĸ '*api*' - Repos containing 'api'${NC}" + echo -e "${CYAN} â€ĸ 'web-app' - Repos starting with 'web-app'${NC}" + echo "" + + while true; do + safe_read "🔍 Repository pattern: " REPO_PREFIX + + if [[ -z "$REPO_PREFIX" ]]; then + log_error "Pattern cannot be empty. Please try again." + echo "" + continue + fi + + # Show what this pattern will match + echo "" + case "$REPO_PREFIX" in + "*") + log_info "This will match ALL repositories under $ROOT_USER" + ;; + *"*"*) + log_info "This will match repositories containing: ${REPO_PREFIX//\*/[text]}" + ;; + *) + log_info "This will match repositories starting with: $REPO_PREFIX" + ;; + esac + + echo "" + local confirm + safe_read "Is this pattern correct? (yes/no): " confirm + + if [[ "$confirm" =~ ^[Yy]([Ee][Ss])?$ ]]; then + log_success "Repository pattern set to: $REPO_PREFIX" + echo "" + break + fi + done +} + +prompt_options() { + log_header "âš™ī¸ Operation Options" + + echo -e "${YELLOW}Choose your operation mode:${NC}" + echo "" + echo -e "${CYAN}1) 🔍 Dry Run - Preview what would be done (Recommended)${NC}" + echo -e "${CYAN}2) 🚀 Execute - Perform the actual removal${NC}" + echo "" + + while true; do + local option + safe_read "Select option (1 or 2): " option + + case "$option" in + 1) + DRY_RUN=true + log_info "Dry run mode selected - no changes will be made" + break + ;; + 2) + DRY_RUN=false + echo "" + echo -e "${YELLOW}âš ī¸ WARNING: This will make actual changes to repositories!${NC}" + local final_confirm + safe_read "Are you absolutely sure? Type 'YES' to confirm: " final_confirm + + if [[ "$final_confirm" == "YES" ]]; then + log_info "Execute mode selected - changes will be made" + break + else + log_info "Switching to dry run mode for safety" + DRY_RUN=true + break + fi + ;; + *) + log_error "Please enter 1 or 2" + ;; + esac + done + + echo "" + local verbose_choice + safe_read "Enable verbose logging? (y/n): " verbose_choice + + if [[ "$verbose_choice" =~ ^[Yy]$ ]]; then + VERBOSE=true + log_info "Verbose logging enabled" + else + VERBOSE=false + log_info "Standard logging enabled" + fi + echo "" +} + +show_summary() { + log_header "📋 Operation Summary" + + echo -e "${BOLD}Configuration:${NC}" + echo -e " đŸĸ Organization/User: ${CYAN}$ROOT_USER${NC}" + echo -e " 👤 User to remove: ${CYAN}$USER_TO_REMOVE${NC}" + echo -e " 🔍 Repository pattern: ${CYAN}$REPO_PREFIX${NC}" + echo -e " âš™ī¸ Mode: ${CYAN}$([ "$DRY_RUN" = true ] && echo "Dry Run" || echo "Execute")${NC}" + echo -e " 📝 Logging: ${CYAN}$([ "$VERBOSE" = true ] && echo "Verbose" || echo "Standard")${NC}" + echo "" + + local proceed + safe_read "Ready to proceed? (yes/no): " proceed + + if [[ ! "$proceed" =~ ^[Yy]([Ee][Ss])?$ ]]; then + log_warning "Operation cancelled by user" + exit 0 + fi +} + +# Fetch all repositories for a user or organization +fetch_all_repos() { + local owner="$1" + local all_repos=() + local page=1 + + log_verbose "Fetching repositories for: $owner" + + while true; do + local response + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/users/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null) + + # Check if response is valid JSON + if ! echo "$response" | jq empty 2>/dev/null; then + log_warning "Invalid response from GitHub API for page $page" + break + fi + + # Check for errors + local error_message + error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null) + if [[ -n "$error_message" ]]; then + if [[ "$error_message" == "Not Found" ]]; then + # Try as organization + log_verbose "User not found, trying as organization..." + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/orgs/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null) + + if ! echo "$response" | jq empty 2>/dev/null; then + log_error "Could not fetch repositories for '$owner' (not found as user or organization)" + exit 1 + fi + else + log_error "GitHub API error: $error_message" + exit 1 + fi + fi + + local repos + repos=$(echo "$response" | jq -r '.[].full_name // empty' 2>/dev/null) + + if [[ -z "$repos" ]]; then + break + fi + + while IFS= read -r repo; do + if [[ -n "$repo" && "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + log_verbose "Found repository: $repo" + fi + done <<< "$repos" + + ((page++)) + done + + TOTAL_REPOS_FOUND=${#all_repos[@]} + if [[ ${#all_repos[@]} -gt 0 ]]; then + printf '%s\n' "${all_repos[@]}" + fi +} + +# Check if repository name matches prefix pattern +matches_prefix() { + local repo_full_name="$1" + local pattern="$2" + local repo_name + repo_name=$(basename "$repo_full_name") + + # Convert shell wildcard pattern to bash pattern + case "$pattern" in + "*") + return 0 # Match all + ;; + *"*"*) + # Pattern contains wildcards + if [[ "$repo_name" == $pattern ]]; then + return 0 + fi + ;; + *) + # Simple prefix match + if [[ "$repo_name" == "$pattern"* ]]; then + return 0 + fi + ;; + esac + + return 1 +} + +# Check if user is a collaborator on a repository +is_collaborator() { + local repo="$1" + local user="$2" + + local response + response=$(curl -s -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null) + + local http_code="${response: -3}" + + case "$http_code" in + 204) + return 0 # User is a collaborator + ;; + 404) + return 1 # User is not a collaborator + ;; + 403) + log_verbose "Access forbidden for $repo (insufficient permissions)" + return 1 + ;; + *) + log_verbose "Failed to check collaboration status for $user on $repo (HTTP: $http_code)" + return 1 + ;; + esac +} + +# Remove user from repository +remove_user_from_repo() { + local repo="$1" + local user="$2" + + if [[ "$DRY_RUN" == "true" ]]; then + log_info "[DRY RUN] Would remove $user from $repo" + ((SUCCESSFUL_REMOVALS++)) + return 0 + fi + + log_verbose "Removing $user from $repo..." + + local response + response=$(curl -s -w "%{http_code}" -X DELETE \ + -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null) + + local http_code="${response: -3}" + + case "$http_code" in + 204) + log_success "Successfully removed $user from $repo" + ((SUCCESSFUL_REMOVALS++)) + return 0 + ;; + 404) + log_info "User $user was not a collaborator on $repo (already removed)" + ((ALREADY_REMOVED++)) + return 0 + ;; + *) + log_error "Failed to remove $user from $repo (HTTP: $http_code)" + ((FAILED_REMOVALS++)) + return 1 + ;; + esac +} + +# Show final results +show_final_summary() { + log_header "🎉 Operation Complete" + + echo -e "${BOLD}📊 Statistics:${NC}" + echo -e " 📁 Repositories scanned: ${CYAN}$TOTAL_REPOS_FOUND${NC}" + echo -e " 🔍 Repositories matching pattern: ${CYAN}$MATCHING_REPOS${NC}" + echo -e " 👤 Repositories where user was collaborator: ${CYAN}$COLLABORATOR_REPOS${NC}" + echo "" + echo -e " ${GREEN}✅ Successful removals: $SUCCESSFUL_REMOVALS${NC}" + echo -e " ${YELLOW}â„šī¸ Already removed: $ALREADY_REMOVED${NC}" + echo -e " ${RED}❌ Failed removals: $FAILED_REMOVALS${NC}" + + if [[ $((SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS)) -gt 0 ]]; then + local success_rate=$((((SUCCESSFUL_REMOVALS + ALREADY_REMOVED) * 100) / (SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS))) + echo -e " 📈 Success rate: ${CYAN}${success_rate}%${NC}" + fi + + echo "" + + if [[ "$DRY_RUN" == "true" ]]; then + log_warning "This was a dry run - no actual changes were made" + echo -e "${BLUE}💡 To perform the actual removal, run the script again and select 'Execute' mode${NC}" + else + if [[ $FAILED_REMOVALS -gt 0 ]]; then + log_warning "Some operations failed. Check the logs above for details." + else + log_success "All operations completed successfully!" + fi + fi + + echo "" + echo -e "${CYAN}🙏 Thank you for using the GitHub User Removal Tool!${NC}" +} + +# Main execution function +main() { + # Check if running interactively + check_interactive + + # Show welcome screen + show_welcome + + # Interactive prompts + prompt_github_token + prompt_root_user + prompt_user_to_remove + prompt_repo_prefix + prompt_options + + # Show summary and confirm + show_summary + + # Start processing + log_header "🚀 Processing Repositories" + + # Fetch all repositories + log_info "Discovering repositories for $ROOT_USER..." + local repos_output + repos_output=$(fetch_all_repos "$ROOT_USER") + + if [[ -z "$repos_output" ]]; then + log_warning "No repositories found for '$ROOT_USER'" + exit 0 + fi + + log_success "Found $TOTAL_REPOS_FOUND repositories" + + # Filter repositories by prefix + log_info "Filtering repositories by pattern '$REPO_PREFIX'..." + local matching_repos=() + + while IFS= read -r repo; do + if [[ -n "$repo" ]] && matches_prefix "$repo" "$REPO_PREFIX"; then + matching_repos+=("$repo") + log_verbose "Matched: $repo" + fi + done <<< "$repos_output" + + MATCHING_REPOS=${#matching_repos[@]} + + if [[ $MATCHING_REPOS -eq 0 ]]; then + log_warning "No repositories match the pattern '$REPO_PREFIX'" + echo "" + log_info "Available repositories:" + while IFS= read -r repo; do + log_info " â€ĸ $(basename "$repo")" + done <<< "$repos_output" + exit 0 + fi + + log_success "Found $MATCHING_REPOS repositories matching pattern '$REPO_PREFIX'" + + # Check collaborator status and remove + log_info "Processing repositories..." + echo "" + + local current=0 + for repo in "${matching_repos[@]}"; do + ((current++)) + printf "\r${CYAN}Progress: [%3d%%] %d/%d repositories processed${NC}" \ + $((current * 100 / MATCHING_REPOS)) "$current" "$MATCHING_REPOS" + + if is_collaborator "$repo" "$USER_TO_REMOVE"; then + ((COLLABORATOR_REPOS++)) + echo # New line after progress + remove_user_from_repo "$repo" "$USER_TO_REMOVE" + fi + done + + echo # New line after progress + + # Show final summary + show_final_summary + + if [[ $FAILED_REMOVALS -gt 0 ]]; then + exit 1 + else + exit 0 + fi +} + +# Script execution +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi \ No newline at end of file diff --git a/remove_user_from_repos.sh b/remove_user_from_repos.sh new file mode 100755 index 0000000..7312709 --- /dev/null +++ b/remove_user_from_repos.sh @@ -0,0 +1,445 @@ +#!/bin/bash + +# Universal GitHub User Removal Script +# Removes a specified user from all repositories matching a prefix pattern +# under a given username or organization + +set -euo pipefail + +# Color definitions +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly CYAN='\033[0;36m' +readonly BOLD='\033[1m' +readonly NC='\033[0m' # No Color + +# Global variables +GITHUB_TOKEN="" +ROOT_USER="" +USER_TO_REMOVE="" +REPO_PREFIX="" +DRY_RUN=false +VERBOSE=false + +# Statistics +TOTAL_REPOS_FOUND=0 +MATCHING_REPOS=0 +COLLABORATOR_REPOS=0 +SUCCESSFUL_REMOVALS=0 +FAILED_REMOVALS=0 +ALREADY_REMOVED=0 + +# Utility functions +log_info() { + echo -e "${BLUE}â„šī¸ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}âš ī¸ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +log_verbose() { + if [[ "$VERBOSE" == "true" ]]; then + echo -e "${CYAN}🔍 $1${NC}" + fi +} + +log_header() { + echo -e "\n${BOLD}${CYAN}$1${NC}" + echo -e "${CYAN}$(printf '=%.0s' {1..60})${NC}" +} + +show_usage() { + cat << EOF +${BOLD}GitHub User Removal Script${NC} + +${YELLOW}Usage:${NC} + $0 -t TOKEN -r ROOT_USER -u USER_TO_REMOVE -p REPO_PREFIX [OPTIONS] + +${YELLOW}Required Parameters:${NC} + -t, --token TOKEN GitHub Personal Access Token + -r, --root ROOT_USER Root GitHub username or organization + -u, --user USER_TO_REMOVE Username to remove from repositories + -p, --prefix REPO_PREFIX Repository name prefix (use '*' for all repos) + +${YELLOW}Optional Parameters:${NC} + -d, --dry-run Show what would be done without making changes + -v, --verbose Enable verbose logging + -h, --help Show this help message + +${YELLOW}Examples:${NC} + # Remove user from all repositories starting with 'bytelyst-' + $0 -t "\$GITHUB_TOKEN" -r "saravanakumardb" -u "i-ayushh18" -p "bytelyst-" + + # Remove user from all repositories (dry run) + $0 -t "\$GITHUB_TOKEN" -r "myorg" -u "olduser" -p "*" --dry-run + + # Remove user with verbose output + $0 -t "\$GITHUB_TOKEN" -r "myorg" -u "olduser" -p "project-" -v + +${YELLOW}Repository Prefix Patterns:${NC} + "bytelyst-" - Matches repos starting with 'bytelyst-' + "*api*" - Matches repos containing 'api' + "*" - Matches all repositories + "web-app" - Matches repos starting with 'web-app' + +EOF +} + +# Parse command line arguments +parse_arguments() { + while [[ $# -gt 0 ]]; do + case $1 in + -t|--token) + GITHUB_TOKEN="$2" + shift 2 + ;; + -r|--root) + ROOT_USER="$2" + shift 2 + ;; + -u|--user) + USER_TO_REMOVE="$2" + shift 2 + ;; + -p|--prefix) + REPO_PREFIX="$2" + shift 2 + ;; + -d|--dry-run) + DRY_RUN=true + shift + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + -h|--help) + show_usage + exit 0 + ;; + *) + log_error "Unknown option: $1" + show_usage + exit 1 + ;; + esac + done +} + +# Validate required parameters +validate_parameters() { + local missing_params=() + + [[ -z "$GITHUB_TOKEN" ]] && missing_params+=("token (-t)") + [[ -z "$ROOT_USER" ]] && missing_params+=("root user (-r)") + [[ -z "$USER_TO_REMOVE" ]] && missing_params+=("user to remove (-u)") + [[ -z "$REPO_PREFIX" ]] && missing_params+=("repository prefix (-p)") + + if [[ ${#missing_params[@]} -gt 0 ]]; then + log_error "Missing required parameters: ${missing_params[*]}" + echo "" + show_usage + exit 1 + fi +} + +# Validate GitHub token +validate_token() { + log_info "Validating GitHub token..." + + local response + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user" 2>/dev/null) + + local login + login=$(echo "$response" | jq -r '.login // empty' 2>/dev/null) + + if [[ -z "$login" ]]; then + log_error "Invalid or expired GitHub token" + log_error "Please ensure your token has 'repo' and 'admin:org' permissions" + exit 1 + fi + + log_success "Token validated (authenticated as: $login)" +} + +# Fetch all repositories for a user or organization +fetch_all_repos() { + local owner="$1" + local all_repos=() + local page=1 + + log_verbose "Fetching repositories for: $owner" + + while true; do + local response + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/users/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null) + + # Check if response is valid JSON + if ! echo "$response" | jq empty 2>/dev/null; then + log_warning "Invalid response from GitHub API for page $page" + break + fi + + # Check for errors + local error_message + error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null) + if [[ -n "$error_message" ]]; then + if [[ "$error_message" == "Not Found" ]]; then + # Try as organization + log_verbose "User not found, trying as organization..." + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/orgs/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null) + + if ! echo "$response" | jq empty 2>/dev/null; then + log_error "Could not fetch repositories for '$owner' (not found as user or organization)" + exit 1 + fi + else + log_error "GitHub API error: $error_message" + exit 1 + fi + fi + + local repos + repos=$(echo "$response" | jq -r '.[].full_name // empty' 2>/dev/null) + + if [[ -z "$repos" ]]; then + break + fi + + while IFS= read -r repo; do + if [[ -n "$repo" && "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + log_verbose "Found repository: $repo" + fi + done <<< "$repos" + + ((page++)) + done + + TOTAL_REPOS_FOUND=${#all_repos[@]} + if [[ ${#all_repos[@]} -gt 0 ]]; then + printf '%s\n' "${all_repos[@]}" + fi +} + +# Check if repository name matches prefix pattern +matches_prefix() { + local repo_full_name="$1" + local pattern="$2" + local repo_name + repo_name=$(basename "$repo_full_name") + + # Convert shell wildcard pattern to bash pattern + case "$pattern" in + "*") + return 0 # Match all + ;; + *"*"*) + # Pattern contains wildcards + if [[ "$repo_name" == $pattern ]]; then + return 0 + fi + ;; + *) + # Simple prefix match + if [[ "$repo_name" == "$pattern"* ]]; then + return 0 + fi + ;; + esac + + return 1 +} + +# Check if user is a collaborator on a repository +is_collaborator() { + local repo="$1" + local user="$2" + + local response + response=$(curl -s -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null) + + local http_code="${response: -3}" + + case "$http_code" in + 204) + return 0 # User is a collaborator + ;; + 404) + return 1 # User is not a collaborator + ;; + 403) + log_verbose "Access forbidden for $repo (insufficient permissions)" + return 1 + ;; + *) + log_verbose "Failed to check collaboration status for $user on $repo (HTTP: $http_code)" + return 1 + ;; + esac +} + +# Remove user from repository +remove_user_from_repo() { + local repo="$1" + local user="$2" + + if [[ "$DRY_RUN" == "true" ]]; then + log_info "[DRY RUN] Would remove $user from $repo" + return 0 + fi + + log_verbose "Removing $user from $repo..." + + local response + response=$(curl -s -w "%{http_code}" -X DELETE \ + -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null) + + local http_code="${response: -3}" + + case "$http_code" in + 204) + log_success "Successfully removed $user from $repo" + ((SUCCESSFUL_REMOVALS++)) + return 0 + ;; + 404) + log_info "User $user was not a collaborator on $repo (already removed)" + ((ALREADY_REMOVED++)) + return 0 + ;; + *) + log_error "Failed to remove $user from $repo (HTTP: $http_code)" + ((FAILED_REMOVALS++)) + return 1 + ;; + esac +} + +# Show final summary +show_summary() { + log_header "Operation Summary" + + echo -e "${BOLD}Repositories scanned:${NC} $TOTAL_REPOS_FOUND" + echo -e "${BOLD}Repositories matching prefix:${NC} $MATCHING_REPOS" + echo -e "${BOLD}Repositories where user was collaborator:${NC} $COLLABORATOR_REPOS" + echo "" + echo -e "${GREEN}Successful removals:${NC} $SUCCESSFUL_REMOVALS" + echo -e "${YELLOW}Already removed:${NC} $ALREADY_REMOVED" + echo -e "${RED}Failed removals:${NC} $FAILED_REMOVALS" + + if [[ $((SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS)) -gt 0 ]]; then + local success_rate=$((((SUCCESSFUL_REMOVALS + ALREADY_REMOVED) * 100) / (SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS))) + echo -e "${CYAN}Success rate:${NC} ${success_rate}%" + fi + + if [[ "$DRY_RUN" == "true" ]]; then + echo "" + log_warning "This was a dry run - no actual changes were made" + log_info "Run without --dry-run to perform the actual removals" + fi +} + +# Main execution function +main() { + log_header "GitHub User Removal Script" + + # Parse and validate arguments + parse_arguments "$@" + validate_parameters + + # Show operation details + log_info "Root user/organization: $ROOT_USER" + log_info "User to remove: $USER_TO_REMOVE" + log_info "Repository prefix: $REPO_PREFIX" + if [[ "$DRY_RUN" == "true" ]]; then + log_warning "DRY RUN MODE - No changes will be made" + fi + + # Validate token + validate_token + + # Fetch all repositories + log_header "Repository Discovery" + local repos_output + repos_output=$(fetch_all_repos "$ROOT_USER") + + if [[ -z "$repos_output" ]]; then + log_warning "No repositories found for '$ROOT_USER'" + exit 0 + fi + + log_success "Found $TOTAL_REPOS_FOUND repositories" + + # Filter repositories by prefix + log_header "Filtering Repositories" + local matching_repos=() + + while IFS= read -r repo; do + if [[ -n "$repo" ]] && matches_prefix "$repo" "$REPO_PREFIX"; then + matching_repos+=("$repo") + log_verbose "Matched: $repo" + fi + done <<< "$repos_output" + + MATCHING_REPOS=${#matching_repos[@]} + + if [[ $MATCHING_REPOS -eq 0 ]]; then + log_warning "No repositories match the prefix pattern '$REPO_PREFIX'" + log_info "Available repositories:" + while IFS= read -r repo; do + log_info " â€ĸ $(basename "$repo")" + done <<< "$repos_output" + exit 0 + fi + + log_success "Found $MATCHING_REPOS repositories matching prefix '$REPO_PREFIX'" + + # Check collaborator status and remove + log_header "Processing Repositories" + + local current=0 + for repo in "${matching_repos[@]}"; do + ((current++)) + printf "\r${CYAN}Progress: [%3d%%] %d/%d repositories processed${NC}" \ + $((current * 100 / MATCHING_REPOS)) "$current" "$MATCHING_REPOS" + + if is_collaborator "$repo" "$USER_TO_REMOVE"; then + ((COLLABORATOR_REPOS++)) + echo # New line after progress + remove_user_from_repo "$repo" "$USER_TO_REMOVE" + fi + done + + echo # New line after progress + + # Show final summary + show_summary + + if [[ $FAILED_REMOVALS -gt 0 ]]; then + exit 1 + else + log_success "Operation completed successfully!" + exit 0 + fi +} + +# Script execution +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi \ No newline at end of file diff --git a/remove_user_guided.sh b/remove_user_guided.sh new file mode 100755 index 0000000..bad9481 --- /dev/null +++ b/remove_user_guided.sh @@ -0,0 +1,593 @@ +#!/bin/bash + +# Interactive GitHub User Removal Script +# Removes a specified user from all repositories matching a prefix pattern +# under a given username or organization with interactive prompts + +set -euo pipefail + +# Color definitions +readonly RED='\033[0;31m' +readonly GREEN='\033[0;32m' +readonly YELLOW='\033[1;33m' +readonly BLUE='\033[0;34m' +readonly CYAN='\033[0;36m' +readonly PURPLE='\033[0;35m' +readonly BOLD='\033[1m' +readonly NC='\033[0m' # No Color + +# Global variables +GITHUB_TOKEN="" +ROOT_USER="" +USER_TO_REMOVE="" +REPO_PREFIX="" +DRY_RUN=false +VERBOSE=false + +# Statistics +TOTAL_REPOS_FOUND=0 +MATCHING_REPOS=0 +COLLABORATOR_REPOS=0 +SUCCESSFUL_REMOVALS=0 +FAILED_REMOVALS=0 +ALREADY_REMOVED=0 + +# Utility functions +log_info() { + echo -e "${BLUE}â„šī¸ $1${NC}" +} + +log_success() { + echo -e "${GREEN}✅ $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}âš ī¸ $1${NC}" +} + +log_error() { + echo -e "${RED}❌ $1${NC}" +} + +log_verbose() { + if [[ "$VERBOSE" == "true" ]]; then + echo -e "${CYAN}🔍 $1${NC}" + fi +} + +log_header() { + echo -e "\n${BOLD}${PURPLE}$1${NC}" + echo -e "${PURPLE}$(printf '=%.0s' {1..60})${NC}" +} + +show_welcome() { + clear + cat << 'EOF' + ╔══════════════════════════════════════════════════════════╗ + ║ ║ + ║ 🚀 GitHub User Removal Tool 🚀 ║ + ║ ║ + ║ Remove users from repositories with ease! ║ + ║ ║ + ╚══════════════════════════════════════════════════════════╝ +EOF + echo "" + log_info "Welcome to the Interactive GitHub User Removal Script!" + echo "" +} + +prompt_github_token() { + log_header "🔑 GitHub Authentication" + + echo -e "${YELLOW}Please provide your GitHub Personal Access Token:${NC}" + echo -e "${CYAN}💡 The token should have 'repo' and 'admin:org' permissions${NC}" + echo -e "${CYAN}💡 You can create one at: https://github.com/settings/tokens${NC}" + echo "" + + while true; do + echo -e -n "${BLUE}🔐 Enter your GitHub token: ${NC}" + read -s -r GITHUB_TOKEN < /dev/tty + echo "" + + if [[ -z "$GITHUB_TOKEN" ]]; then + log_error "Token cannot be empty. Please try again." + echo "" + continue + fi + + # Validate token + log_info "Validating token..." + local response + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/user" 2>/dev/null) + + local login + login=$(echo "$response" | jq -r '.login // empty' 2>/dev/null) + + if [[ -z "$login" ]]; then + log_error "Invalid or expired GitHub token. Please try again." + echo "" + continue + fi + + log_success "Token validated successfully! (Authenticated as: $login)" + echo "" + break + done +} + +prompt_root_user() { + log_header "👤 Target Organization/User" + + echo -e "${YELLOW}Enter the GitHub username or organization name:${NC}" + echo -e "${CYAN}💡 This is where we'll look for repositories${NC}" + echo -e "${CYAN}💡 Examples: 'mycompany', 'john-doe', 'my-organization'${NC}" + echo "" + + while true; do + echo -e -n "${BLUE}đŸĸ Organization/Username: ${NC}" + read -r ROOT_USER < /dev/tty + + if [[ -z "$ROOT_USER" ]]; then + log_error "Username/organization cannot be empty. Please try again." + echo "" + continue + fi + + # Validate username format + if [[ ! "$ROOT_USER" =~ ^[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid username format. Use only letters, numbers, dots, underscores, and hyphens." + echo "" + continue + fi + + log_success "Target set to: $ROOT_USER" + echo "" + break + done +} + +prompt_user_to_remove() { + log_header "đŸŽ¯ User to Remove" + + echo -e "${YELLOW}Enter the username you want to remove from repositories:${NC}" + echo -e "${CYAN}💡 This user will be removed as a collaborator from matching repositories${NC}" + echo -e "${CYAN}💡 They will lose access to private repositories (if applicable)${NC}" + echo "" + + while true; do + echo -e -n "${BLUE}👤 Username to remove: ${NC}" + read -r USER_TO_REMOVE < /dev/tty + + if [[ -z "$USER_TO_REMOVE" ]]; then + log_error "Username cannot be empty. Please try again." + echo "" + continue + fi + + # Validate username format + if [[ ! "$USER_TO_REMOVE" =~ ^[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid username format. Use only letters, numbers, dots, underscores, and hyphens." + echo "" + continue + fi + + # Confirmation prompt + echo "" + echo -e "${YELLOW}âš ī¸ You are about to remove user '${BOLD}$USER_TO_REMOVE${NC}${YELLOW}' from repositories${NC}" + echo -e -n "${BLUE}Are you sure this is correct? (yes/no): ${NC}" + read -r confirm < /dev/tty + + if [[ "$confirm" =~ ^[Yy]([Ee][Ss])?$ ]]; then + log_success "User to remove set to: $USER_TO_REMOVE" + echo "" + break + else + echo -e "${YELLOW}Let's try again...${NC}" + echo "" + fi + done +} + +prompt_repo_prefix() { + log_header "📁 Repository Filter" + + echo -e "${YELLOW}Enter a repository name pattern to filter repositories:${NC}" + echo -e "${CYAN}💡 Pattern examples:${NC}" + echo -e "${CYAN} â€ĸ '*' - All repositories${NC}" + echo -e "${CYAN} â€ĸ 'myproject-' - Repos starting with 'myproject-'${NC}" + echo -e "${CYAN} â€ĸ '*api*' - Repos containing 'api'${NC}" + echo -e "${CYAN} â€ĸ 'web-app' - Repos starting with 'web-app'${NC}" + echo "" + + while true; do + echo -e -n "${BLUE}🔍 Repository pattern: ${NC}" + read -r REPO_PREFIX < /dev/tty + + if [[ -z "$REPO_PREFIX" ]]; then + log_error "Pattern cannot be empty. Please try again." + echo "" + continue + fi + + # Show what this pattern will match + echo "" + case "$REPO_PREFIX" in + "*") + log_info "This will match ALL repositories under $ROOT_USER" + ;; + *"*"*) + log_info "This will match repositories containing: ${REPO_PREFIX//\*/[text]}" + ;; + *) + log_info "This will match repositories starting with: $REPO_PREFIX" + ;; + esac + + echo "" + echo -e -n "${BLUE}Is this pattern correct? (yes/no): ${NC}" + read -r confirm < /dev/tty + + if [[ "$confirm" =~ ^[Yy]([Ee][Ss])?$ ]]; then + log_success "Repository pattern set to: $REPO_PREFIX" + echo "" + break + fi + done +} + +prompt_options() { + log_header "âš™ī¸ Operation Options" + + echo -e "${YELLOW}Choose your operation mode:${NC}" + echo "" + echo -e "${CYAN}1) 🔍 Dry Run - Preview what would be done (Recommended)${NC}" + echo -e "${CYAN}2) 🚀 Execute - Perform the actual removal${NC}" + echo "" + + while true; do + echo -e -n "${BLUE}Select option (1 or 2): ${NC}" + read -r option < /dev/tty + + case "$option" in + 1) + DRY_RUN=true + log_info "Dry run mode selected - no changes will be made" + break + ;; + 2) + DRY_RUN=false + echo "" + echo -e "${YELLOW}âš ī¸ WARNING: This will make actual changes to repositories!${NC}" + echo -e -n "${BLUE}Are you absolutely sure? Type 'YES' to confirm: ${NC}" + read -r final_confirm < /dev/tty + + if [[ "$final_confirm" == "YES" ]]; then + log_info "Execute mode selected - changes will be made" + break + else + log_info "Switching to dry run mode for safety" + DRY_RUN=true + break + fi + ;; + *) + log_error "Please enter 1 or 2" + ;; + esac + done + + echo "" + echo -e -n "${BLUE}Enable verbose logging? (y/n): ${NC}" + read -r verbose_choice < /dev/tty + + if [[ "$verbose_choice" =~ ^[Yy]$ ]]; then + VERBOSE=true + log_info "Verbose logging enabled" + else + VERBOSE=false + log_info "Standard logging enabled" + fi + echo "" +} + +show_summary() { + log_header "📋 Operation Summary" + + echo -e "${BOLD}Configuration:${NC}" + echo -e " đŸĸ Organization/User: ${CYAN}$ROOT_USER${NC}" + echo -e " 👤 User to remove: ${CYAN}$USER_TO_REMOVE${NC}" + echo -e " 🔍 Repository pattern: ${CYAN}$REPO_PREFIX${NC}" + echo -e " âš™ī¸ Mode: ${CYAN}$([ "$DRY_RUN" = true ] && echo "Dry Run" || echo "Execute")${NC}" + echo -e " 📝 Logging: ${CYAN}$([ "$VERBOSE" = true ] && echo "Verbose" || echo "Standard")${NC}" + echo "" + + echo -e -n "${BLUE}Ready to proceed? (yes/no): ${NC}" + read -r proceed < /dev/tty + + if [[ ! "$proceed" =~ ^[Yy]([Ee][Ss])?$ ]]; then + log_warning "Operation cancelled by user" + exit 0 + fi +} + +# Fetch all repositories for a user or organization +fetch_all_repos() { + local owner="$1" + local all_repos=() + local page=1 + + log_verbose "Fetching repositories for: $owner" + + while true; do + local response + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/users/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null) + + # Check if response is valid JSON + if ! echo "$response" | jq empty 2>/dev/null; then + log_warning "Invalid response from GitHub API for page $page" + break + fi + + # Check for errors + local error_message + error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null) + if [[ -n "$error_message" ]]; then + if [[ "$error_message" == "Not Found" ]]; then + # Try as organization + log_verbose "User not found, trying as organization..." + response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/orgs/$owner/repos?per_page=100&page=$page&type=all" 2>/dev/null) + + if ! echo "$response" | jq empty 2>/dev/null; then + log_error "Could not fetch repositories for '$owner' (not found as user or organization)" + exit 1 + fi + else + log_error "GitHub API error: $error_message" + exit 1 + fi + fi + + local repos + repos=$(echo "$response" | jq -r '.[].full_name // empty' 2>/dev/null) + + if [[ -z "$repos" ]]; then + break + fi + + while IFS= read -r repo; do + if [[ -n "$repo" && "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + log_verbose "Found repository: $repo" + fi + done <<< "$repos" + + ((page++)) + done + + TOTAL_REPOS_FOUND=${#all_repos[@]} + if [[ ${#all_repos[@]} -gt 0 ]]; then + printf '%s\n' "${all_repos[@]}" + fi +} + +# Check if repository name matches prefix pattern +matches_prefix() { + local repo_full_name="$1" + local pattern="$2" + local repo_name + repo_name=$(basename "$repo_full_name") + + # Convert shell wildcard pattern to bash pattern + case "$pattern" in + "*") + return 0 # Match all + ;; + *"*"*) + # Pattern contains wildcards + if [[ "$repo_name" == $pattern ]]; then + return 0 + fi + ;; + *) + # Simple prefix match + if [[ "$repo_name" == "$pattern"* ]]; then + return 0 + fi + ;; + esac + + return 1 +} + +# Check if user is a collaborator on a repository +is_collaborator() { + local repo="$1" + local user="$2" + + local response + response=$(curl -s -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null) + + local http_code="${response: -3}" + + case "$http_code" in + 204) + return 0 # User is a collaborator + ;; + 404) + return 1 # User is not a collaborator + ;; + 403) + log_verbose "Access forbidden for $repo (insufficient permissions)" + return 1 + ;; + *) + log_verbose "Failed to check collaboration status for $user on $repo (HTTP: $http_code)" + return 1 + ;; + esac +} + +# Remove user from repository +remove_user_from_repo() { + local repo="$1" + local user="$2" + + if [[ "$DRY_RUN" == "true" ]]; then + log_info "[DRY RUN] Would remove $user from $repo" + return 0 + fi + + log_verbose "Removing $user from $repo..." + + local response + response=$(curl -s -w "%{http_code}" -X DELETE \ + -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user" 2>/dev/null) + + local http_code="${response: -3}" + + case "$http_code" in + 204) + log_success "Successfully removed $user from $repo" + ((SUCCESSFUL_REMOVALS++)) + return 0 + ;; + 404) + log_info "User $user was not a collaborator on $repo (already removed)" + ((ALREADY_REMOVED++)) + return 0 + ;; + *) + log_error "Failed to remove $user from $repo (HTTP: $http_code)" + ((FAILED_REMOVALS++)) + return 1 + ;; + esac +} + +# Show final results +show_final_summary() { + log_header "🎉 Operation Complete" + + echo -e "${BOLD}📊 Statistics:${NC}" + echo -e " 📁 Repositories scanned: ${CYAN}$TOTAL_REPOS_FOUND${NC}" + echo -e " 🔍 Repositories matching pattern: ${CYAN}$MATCHING_REPOS${NC}" + echo -e " 👤 Repositories where user was collaborator: ${CYAN}$COLLABORATOR_REPOS${NC}" + echo "" + echo -e " ${GREEN}✅ Successful removals: $SUCCESSFUL_REMOVALS${NC}" + echo -e " ${YELLOW}â„šī¸ Already removed: $ALREADY_REMOVED${NC}" + echo -e " ${RED}❌ Failed removals: $FAILED_REMOVALS${NC}" + + if [[ $((SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS)) -gt 0 ]]; then + local success_rate=$((((SUCCESSFUL_REMOVALS + ALREADY_REMOVED) * 100) / (SUCCESSFUL_REMOVALS + ALREADY_REMOVED + FAILED_REMOVALS))) + echo -e " 📈 Success rate: ${CYAN}${success_rate}%${NC}" + fi + + echo "" + + if [[ "$DRY_RUN" == "true" ]]; then + log_warning "This was a dry run - no actual changes were made" + echo -e "${BLUE}💡 To perform the actual removal, run the script again and select 'Execute' mode${NC}" + else + if [[ $FAILED_REMOVALS -gt 0 ]]; then + log_warning "Some operations failed. Check the logs above for details." + else + log_success "All operations completed successfully!" + fi + fi + + echo "" + echo -e "${CYAN}🙏 Thank you for using the GitHub User Removal Tool!${NC}" +} + +# Main execution function +main() { + # Show welcome screen + show_welcome + + # Interactive prompts + prompt_github_token + prompt_root_user + prompt_user_to_remove + prompt_repo_prefix + prompt_options + + # Show summary and confirm + show_summary + + # Start processing + log_header "🚀 Processing Repositories" + + # Fetch all repositories + log_info "Discovering repositories for $ROOT_USER..." + local repos_output + repos_output=$(fetch_all_repos "$ROOT_USER") + + if [[ -z "$repos_output" ]]; then + log_warning "No repositories found for '$ROOT_USER'" + exit 0 + fi + + log_success "Found $TOTAL_REPOS_FOUND repositories" + + # Filter repositories by prefix + log_info "Filtering repositories by pattern '$REPO_PREFIX'..." + local matching_repos=() + + while IFS= read -r repo; do + if [[ -n "$repo" ]] && matches_prefix "$repo" "$REPO_PREFIX"; then + matching_repos+=("$repo") + log_verbose "Matched: $repo" + fi + done <<< "$repos_output" + + MATCHING_REPOS=${#matching_repos[@]} + + if [[ $MATCHING_REPOS -eq 0 ]]; then + log_warning "No repositories match the pattern '$REPO_PREFIX'" + echo "" + log_info "Available repositories:" + while IFS= read -r repo; do + log_info " â€ĸ $(basename "$repo")" + done <<< "$repos_output" + exit 0 + fi + + log_success "Found $MATCHING_REPOS repositories matching pattern '$REPO_PREFIX'" + + # Check collaborator status and remove + log_info "Processing repositories..." + echo "" + + local current=0 + for repo in "${matching_repos[@]}"; do + ((current++)) + printf "\r${CYAN}Progress: [%3d%%] %d/%d repositories processed${NC}" \ + $((current * 100 / MATCHING_REPOS)) "$current" "$MATCHING_REPOS" + + if is_collaborator "$repo" "$USER_TO_REMOVE"; then + ((COLLABORATOR_REPOS++)) + echo # New line after progress + remove_user_from_repo "$repo" "$USER_TO_REMOVE" + fi + done + + echo # New line after progress + + # Show final summary + show_final_summary + + if [[ $FAILED_REMOVALS -gt 0 ]]; then + exit 1 + else + exit 0 + fi +} + +# Script execution +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi \ No newline at end of file diff --git a/remove_user_i-ayushh18.sh b/remove_user_i-ayushh18.sh new file mode 100755 index 0000000..faaafd8 --- /dev/null +++ b/remove_user_i-ayushh18.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Script to remove user i-ayushh18 from repositories +# This script uses the improved remove_user_interactive.sh + +set -euo pipefail + +# Check if GITHUB_TOKEN is set +if [[ -z "${GITHUB_TOKEN:-}" ]]; then + echo "❌ Error: GITHUB_TOKEN environment variable is not set" + echo "Please set your GitHub Personal Access Token:" + echo "export GITHUB_TOKEN='your_token_here'" + exit 1 +fi + +echo "🚀 Starting removal process for user: i-ayushh18" +echo "📋 This will:" +echo " 1. Check which repositories i-ayushh18 is actually a collaborator on" +echo " 2. Show a preview of repositories where they will be removed" +echo " 3. Remove them from those repositories" +echo "" + +# Run the improved script with non-interactive mode +./remove_user_interactive.sh \ + --user "i-ayushh18" \ + --root "saravanakumardb" \ + --pattern "*" \ + --token "$GITHUB_TOKEN" \ + --non-interactive + +echo "" +echo "✅ Removal process completed for user: i-ayushh18" diff --git a/remove_user_interactive.sh b/remove_user_interactive.sh index b8808c7..58753d6 100755 --- a/remove_user_interactive.sh +++ b/remove_user_interactive.sh @@ -26,6 +26,7 @@ PROCESSED_REPOS=0 SUCCESSFUL_REMOVALS=0 FAILED_REMOVALS=0 SKIPPED_REMOVALS=0 +NON_INTERACTIVE=false # Required tools REQUIRED_TOOLS=(curl jq) @@ -88,11 +89,19 @@ collect_github_token() { local http_code="${response: -3}" if [[ "$http_code" != "200" ]]; then - log_error "Invalid GitHub token or insufficient permissions" + log_error "Invalid GitHub token or insufficient permissions (HTTP: $http_code)" + if [[ "$http_code" == "401" ]]; then + log_error "Token is invalid or expired" + elif [[ "$http_code" == "403" ]]; then + log_error "Token lacks required permissions (need 'repo' and 'admin:org')" + fi exit 1 fi - log_success "GitHub token validated successfully" + # Get user info for confirmation + local user_info + user_info=$(echo "${response%???}" | jq -r '.login // "unknown"' 2>/dev/null) + log_success "GitHub token validated successfully (authenticated as: $user_info)" } collect_root_user() { @@ -141,28 +150,50 @@ fetch_user_repos() { local page=1 local all_repos=() - log_progress "Fetching repositories for user: $user" - + # Don't log here to avoid capturing log messages as repo names while true; do local response response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/users/$user/repos?per_page=100&page=$page&type=all") + # Check if response is valid JSON and contains repositories + if ! echo "$response" | jq empty 2>/dev/null; then + log_error "Invalid JSON response from GitHub API" + break + fi + + # Check for authentication errors + local error_message + error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null) + if [[ "$error_message" == "Bad credentials" ]]; then + log_error "GitHub token is invalid or expired" + log_error "Please check your GITHUB_TOKEN environment variable" + exit 1 + fi + local repos - repos=$(echo "$response" | jq -r '.[].full_name // empty') + repos=$(echo "$response" | jq -r '.[].full_name // empty' 2>/dev/null) if [[ -z "$repos" ]]; then break fi while IFS= read -r repo; do - all_repos+=("$repo") + # Validate repository name format (should be owner/repo) + if [[ "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + else + log_warning "Skipping invalid repository name: $repo" + fi done <<< "$repos" ((page++)) done - printf '%s\n' "${all_repos[@]}" + # Only print if there are repos to avoid unbound variable error + if [[ ${#all_repos[@]} -gt 0 ]]; then + printf '%s\n' "${all_repos[@]}" + fi } fetch_org_repos() { @@ -170,39 +201,146 @@ fetch_org_repos() { local page=1 local all_repos=() - log_progress "Fetching repositories for organization: $org" - + # Don't log here to avoid capturing log messages as repo names while true; do local response response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/orgs/$org/repos?per_page=100&page=$page&type=all") + # Check if response is valid JSON and contains repositories + if ! echo "$response" | jq empty 2>/dev/null; then + log_error "Invalid JSON response from GitHub API for organization: $org" + break + fi + + # Check for authentication errors + local error_message + error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null) + if [[ "$error_message" == "Bad credentials" ]]; then + log_error "GitHub token is invalid or expired" + log_error "Please check your GITHUB_TOKEN environment variable" + exit 1 + fi + local repos - repos=$(echo "$response" | jq -r '.[].full_name // empty') + repos=$(echo "$response" | jq -r '.[].full_name // empty' 2>/dev/null) if [[ -z "$repos" ]]; then break fi while IFS= read -r repo; do - all_repos+=("$repo") + # Validate repository name format (should be owner/repo) + if [[ "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + else + log_warning "Skipping invalid repository name: $repo" + fi done <<< "$repos" ((page++)) done - printf '%s\n' "${all_repos[@]}" + # Only print if there are repos to avoid unbound variable error + if [[ ${#all_repos[@]} -gt 0 ]]; then + printf '%s\n' "${all_repos[@]}" + fi } fetch_user_orgs() { local user="$1" - log_progress "Fetching organizations for user: $user" local response response=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/users/$user/orgs") - echo "$response" | jq -r '.[].login // empty' + # Check if response is valid JSON + if ! echo "$response" | jq empty 2>/dev/null; then + log_error "Invalid JSON response from GitHub API for user organizations" + log_error "Response: $response" + return 1 + fi + + # Check for authentication errors + local error_message + error_message=$(echo "$response" | jq -r '.message // empty' 2>/dev/null) + if [[ "$error_message" == "Bad credentials" ]]; then + log_error "GitHub token is invalid or expired" + log_error "Please check your GITHUB_TOKEN environment variable" + exit 1 + fi + + # Check if response is an array + local org_count + org_count=$(echo "$response" | jq 'length' 2>/dev/null) + + if [[ "$org_count" == "0" ]] || [[ "$org_count" == "null" ]]; then + return 0 + fi + + echo "$response" | jq -r '.[].login // empty' 2>/dev/null +} + +# Check if user is a collaborator on a repository +check_user_collaboration() { + local repo="$1" + local user="$2" + + # Validate repository name format + if [[ ! "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + log_warning "Invalid repository name format: $repo" + return 1 + fi + + local response + response=$(curl -s -w "%{http_code}" -H "Authorization: token $GITHUB_TOKEN" \ + "https://api.github.com/repos/$repo/collaborators/$user") + + local http_code="${response: -3}" + + case "$http_code" in + 204) + return 0 # User is a collaborator + ;; + 404) + return 1 # User is not a collaborator + ;; + 403) + log_warning "Access forbidden for $repo - may not have admin permissions" + return 1 + ;; + *) + log_warning "Failed to check collaboration status for $user on $repo (HTTP: $http_code)" + return 1 + ;; + esac +} + +# Get repositories where user is actually a collaborator +get_user_collaborations() { + local repos=("$@") + local user="$1" + local collaborator_repos=() + + log_header "Checking User Collaborations" + log_progress "Checking which repositories $user is actually a collaborator on..." + + local total=${#repos[@]} + local checked=0 + + for repo in "${repos[@]}"; do + ((checked++)) + printf "\r${CYAN}Checking collaborations: [%3d%%] %d/%d repositories checked${NC}" \ + $((checked * 100 / total)) "$checked" "$total" + + if check_user_collaboration "$repo" "$user"; then + collaborator_repos+=("$repo") + log_info "✓ $user is a collaborator on $repo" + fi + done + + echo # New line after progress + return 0 } # Repository matching function @@ -321,42 +459,158 @@ show_summary() { echo -e "${CYAN}Success rate: $(( SUCCESSFUL_REMOVALS * 100 / (SUCCESSFUL_REMOVALS + FAILED_REMOVALS + SKIPPED_REMOVALS) ))%${NC}" } +# Parse command line arguments +parse_arguments() { + while [[ $# -gt 0 ]]; do + case $1 in + -u|--user) + USER_TO_REMOVE="$2" + shift 2 + ;; + -r|--root) + ROOT_USER="$2" + shift 2 + ;; + -p|--pattern) + REPO_PATTERN="$2" + shift 2 + ;; + -t|--token) + GITHUB_TOKEN="$2" + shift 2 + ;; + --non-interactive) + NON_INTERACTIVE=true + CONFIRMATION_MODE="yes_all" + shift + ;; + -h|--help) + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " -u, --user USER Username to remove from repositories" + echo " -r, --root USER Root GitHub username/organization" + echo " -p, --pattern PATTERN Repository pattern (supports wildcards)" + echo " -t, --token TOKEN GitHub Personal Access Token" + echo " --non-interactive Run without prompts (auto-confirm all)" + echo " -h, --help Show this help message" + echo "" + echo "Example:" + echo " $0 -u i-ayushh18 -r saravanakumardb -p '*' -t \$GITHUB_TOKEN --non-interactive" + exit 0 + ;; + *) + log_error "Unknown option: $1" + exit 1 + ;; + esac + done +} + # Main execution function main() { - log_header "Interactive GitHub User Removal Tool" + log_header "GitHub User Removal Tool" + + # Parse command line arguments + parse_arguments "$@" # Check dependencies check_dependencies - # Collect inputs - collect_github_token - collect_root_user - collect_user_to_remove - collect_repo_pattern + # Collect inputs (interactive if not provided via command line) + if [[ -z "$GITHUB_TOKEN" ]]; then + collect_github_token + else + log_success "Using GitHub token from command line" + fi + + if [[ -z "$ROOT_USER" ]]; then + collect_root_user + else + log_success "Root user: $ROOT_USER" + fi + + if [[ -z "$USER_TO_REMOVE" ]]; then + collect_user_to_remove + else + log_success "Target user: $USER_TO_REMOVE" + fi + + if [[ -z "$REPO_PATTERN" ]]; then + collect_repo_pattern + else + log_success "Repository pattern: $REPO_PATTERN" + fi # Collect all repositories log_header "Repository Discovery" local all_repos=() # Fetch root user repositories - while IFS= read -r repo; do - [[ -n "$repo" ]] && all_repos+=("$repo") - done < <(fetch_user_repos "$ROOT_USER") + log_info "Fetching repositories for user: $ROOT_USER" + local user_repos_output + user_repos_output=$(fetch_user_repos "$ROOT_USER") + local user_repos_exit_code=$? + + log_info "User repos fetch exit code: $user_repos_exit_code" + log_info "User repos output: '$user_repos_output'" + + if [[ -n "$user_repos_output" ]]; then + while IFS= read -r repo; do + if [[ -n "$repo" ]] && [[ "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + log_info "Found user repo: $repo" + elif [[ -n "$repo" ]]; then + log_warning "Skipping invalid repository name: $repo" + fi + done <<< "$user_repos_output" + else + log_info "No repositories found for user: $ROOT_USER" + fi # Fetch organization repositories - while IFS= read -r org; do - if [[ -n "$org" ]]; then - log_info "Found organization: $org" + log_info "Fetching organizations for user: $ROOT_USER" + local orgs=() + local org_output + org_output=$(fetch_user_orgs "$ROOT_USER") + local org_exit_code=$? + + log_info "Organization fetch exit code: $org_exit_code" + log_info "Organization output: '$org_output'" + + if [[ $org_exit_code -eq 0 ]] && [[ -n "$org_output" ]]; then + while IFS= read -r org; do + if [[ -n "$org" ]] && [[ "$org" =~ ^[a-zA-Z0-9._-]+$ ]]; then + orgs+=("$org") + log_info "Found organization: $org" + elif [[ -n "$org" ]]; then + log_warning "Skipping invalid organization name: $org" + fi + done <<< "$org_output" + else + log_info "No organizations found for user: $ROOT_USER" + fi + + # Fetch repositories for each organization + if [[ ${#orgs[@]} -gt 0 ]]; then + for org in "${orgs[@]}"; do + log_info "Fetching repositories for organization: $org" while IFS= read -r repo; do - [[ -n "$repo" ]] && all_repos+=("$repo") + if [[ -n "$repo" ]] && [[ "$repo" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then + all_repos+=("$repo") + log_info "Found org repo: $repo" + elif [[ -n "$repo" ]]; then + log_warning "Skipping invalid repository name: $repo" + fi done < <(fetch_org_repos "$org") - fi - done < <(fetch_user_orgs "$ROOT_USER") + done + fi # Filter repositories by pattern log_header "Repository Filtering" local matching_repos=() + log_info "Total repositories found: ${#all_repos[@]}" + for repo in "${all_repos[@]}"; do local repo_name repo_name=$(basename "$repo") @@ -371,30 +625,73 @@ main() { if [[ $TOTAL_REPOS -eq 0 ]]; then log_warning "No repositories match the pattern '$REPO_PATTERN'" + log_info "Available repositories:" + for repo in "${all_repos[@]}"; do + log_info " â€ĸ $repo" + done exit 0 fi log_success "Found $TOTAL_REPOS matching repositories" - # Confirmation before proceeding - echo -e "\n${YELLOW}About to remove user '$USER_TO_REMOVE' from $TOTAL_REPOS repositories matching '$REPO_PATTERN'${NC}" - read -p "Continue? [y/N]: " -n 1 -r - echo + # Check which repositories the user is actually a collaborator on + log_header "Checking User Collaborations" + log_progress "Checking which repositories '$USER_TO_REMOVE' is actually a collaborator on..." - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - log_warning "Operation cancelled" + local collaborator_repos=() + local checked=0 + + for repo in "${matching_repos[@]}"; do + ((checked++)) + printf "\r${CYAN}Checking collaborations: [%3d%%] %d/%d repositories checked${NC}" \ + $((checked * 100 / TOTAL_REPOS)) "$checked" "$TOTAL_REPOS" + + if check_user_collaboration "$repo" "$USER_TO_REMOVE"; then + collaborator_repos+=("$repo") + fi + done + + echo # New line after progress + + local collaborator_count=${#collaborator_repos[@]} + + if [[ $collaborator_count -eq 0 ]]; then + log_warning "User '$USER_TO_REMOVE' is not a collaborator on any of the $TOTAL_REPOS matching repositories" + log_info "No action needed - user is already not a collaborator on any matching repositories" exit 0 fi + log_success "User '$USER_TO_REMOVE' is a collaborator on $collaborator_count out of $TOTAL_REPOS matching repositories" + + # Show preview of repositories where user will be removed + log_header "Preview: Repositories where '$USER_TO_REMOVE' will be removed" + for repo in "${collaborator_repos[@]}"; do + log_info "â€ĸ $repo" + done + + # Confirmation before proceeding + if [[ "$NON_INTERACTIVE" == "false" ]]; then + echo -e "\n${YELLOW}About to remove user '$USER_TO_REMOVE' from $collaborator_count repositories${NC}" + read -p "Continue? [y/N]: " -n 1 -r + echo + + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + log_warning "Operation cancelled" + exit 0 + fi + else + log_info "Non-interactive mode: proceeding with removal from $collaborator_count repositories" + fi + # Process repositories log_header "User Removal Process" - for repo in "${matching_repos[@]}"; do + for repo in "${collaborator_repos[@]}"; do ((PROCESSED_REPOS++)) - show_progress "$PROCESSED_REPOS" "$TOTAL_REPOS" + show_progress "$PROCESSED_REPOS" "$collaborator_count" - if get_confirmation "$repo" "$PROCESSED_REPOS" "$TOTAL_REPOS"; then + if get_confirmation "$repo" "$PROCESSED_REPOS" "$collaborator_count"; then remove_user_from_repo "$repo" else log_info "Skipped: $repo" diff --git a/test_interactive.sh b/test_interactive.sh new file mode 100755 index 0000000..e4f4f64 --- /dev/null +++ b/test_interactive.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Simple test of interactive input +set -euo pipefail + +# Color definitions +readonly BLUE='\033[0;34m' +readonly GREEN='\033[0;32m' +readonly NC='\033[0m' # No Color + +echo -e "${GREEN}🚀 Testing Interactive Input${NC}" +echo "" + +echo -e -n "${BLUE}Enter your name: ${NC}" +read -r name < /dev/tty + +echo -e -n "${BLUE}Enter your favorite color: ${NC}" +read -r color < /dev/tty + +echo "" +echo -e "${GREEN}✅ Input received!${NC}" +echo -e "Name: $name" +echo -e "Color: $color" \ No newline at end of file