A streamlined system for managing and running batch operations across multiple Elixir repositories.
This tool provides a simple framework for:
- Scanning a directory for Elixir git repositories
- Filtering repositories based on exclude lists
- Running custom actions across filtered repositories
- Extensible action system for batch operations
- Elixir 1.14 or higher
- Git
- (Optional) API keys for LLM integrations (Gemini, Claude)
- The scripts use
Mix.installand will automatically download dependencies on first run - For LLM features (when you implement them), set environment variables:
export GEMINI_API_KEY="your-gemini-key" export ANTHROPIC_API_KEY="your-claude-key"# 1. Initial setup - scan parent directory and create filtered list elixir run.exs setup # 2. Run actions on filtered repos elixir run.exs uncommitted # Check for uncommitted work elixir run.exs analyze # Analyze repos (stubbed for LLM) elixir run.exs placeholder # Run your custom actionScans the parent directory (..) for repositories that are:
- Git repositories (contain
.gitdirectory) - Elixir projects (contain
mix.exsfile)
Outputs:
repos.json- All found repositoriesrepos_exclude.json- All repositories EXCEPT DSPex (modify as needed)
Example:
elixir run.exs scan # or directly: elixir scan_repos.exsCreates a final filtered list by subtracting excluded repos from the main list:
- Reads
repos.json(main list) - Reads
repos_exclude.json(exclusion list) - Creates
repos_filtered.json(main - excludes)
Example:
elixir run.exs filter # or directly: elixir filter_repos.exsRuns actions on repositories in repos_filtered.json.
| Command | Description | Output Files |
|---|---|---|
elixir run.exs | Show help | - |
elixir run.exs scan | Scan for Elixir repos | repos.json, repos_exclude.json |
elixir run.exs filter | Filter repos | repos_filtered.json |
elixir run.exs setup | Run scan + filter | All JSON files |
elixir launch_wt_erlexec.exs [N] | Launch Windows Terminal layouts sized for 4K | ~/.config/wt_launcher/windows.exs |
elixir launch_wt_erlexec.exs --config [path] | Launch Windows Terminal from a layout file | ~/.config/wt_launcher/windows.exs |
| Command | Description | Status |
|---|---|---|
elixir run.exs uncommitted | Check for uncommitted changes | ✅ Working |
elixir run.exs analyze | Analyze repos with LLM | 🔨 Stubbed |
elixir run.exs placeholder | Template for custom actions | 🔨 Stubbed |
Actions are located in the actions/ directory. Each action is a self-contained Elixir script.
Checks each repository for uncommitted changes using git status --porcelain.
Output:
=== Checking for uncommitted work === ✓ repo1 - clean ✗ repo2 - has uncommitted changes ✓ repo3 - clean Repos with uncommitted work (1): - /path/to/repo2 Analyzes repositories against a reference repository.
Features:
- Hardcoded reference repo:
../gemini_ex - Extracts repo metadata (logo, mix.exs, README)
- Creates LLM analysis prompts
- Currently stubbed - Ready for LLM integration
What it checks:
- Has Logo - Presence of logo files
- Hex Publishing Format - mix.exs structure for publishing
- Documentation Quality - README completeness
- Project Metadata - Package info structure
- Future checks (stubbed):
- CI/CD setup
- Testing setup
- Code style/formatting
Output:
🔍 Using REFERENCE REPO: ../gemini_ex (explicitly hardcoded in script) ✓ Reference loaded (has_logo: false) 📊 Analyzing 1 repos... ============================================================ Analyzing: DSPex ============================================================ 📝 STUB: Would analyze with LLM Prompt ready (8981 chars) Has logo: false Has mix.exs: true Has README: true Template for creating custom actions.
Output:
=== Running placeholder action === Processing: repo1 Processing: repo2 ✓ Placeholder action complete launch_wt_erlexec.exs automates Windows Terminal from WSL with two complementary workflows:
- Builtin tiling –
elixir launch_wt_erlexec.exs(or… exs N) tiles the full 3840×2160 desktop forN = 2..24windows. Widths are scaled so panes stay usable; heights stretch to fill the display. Each pane gets a named window and a placeholder tab ready for reuse. - Config-driven –
elixir launch_wt_erlexec.exs --configreads a layout file (example:config/wt_layout.exs) that specifies per-window tabs, titles, profiles, positions, and modes. Override the file path withWT_LAYOUT_CONFIGor pass it inline.
Every launch persists state to ~/.config/wt_launcher/windows.exs, capturing UUIDs, window targets, pixel rectangles, and tab metadata. Use those targets later with wt.exe -w <target> to add, focus, or close tabs programmatically.
To customize the default layout without editing tracked files, copy config/wt_layout.local.example.exs to config/wt_layout.local.exs (ignored by git) and set left_path / right_path to your preferred workspaces. Legacy keys such as :nordic_road_path and :snakepit_path are still recognized for compatibility.
WT_DRY_RUN=1— Print the commands without opening Windows Terminal (great for validating layouts).WT_WSL_EXE,WT_BASH_EXE,WT_DEFAULT_COMMAND— Override the executables/commands used inside tabs.WT_LAYOUT_CONFIG=/path/to/layout.exs— Force a specific config file without supplying--config.
- Create a new file in
actions/directory (e.g.,actions/my_action.exs) - Define a module with a
run/1function:
#!/usr/bin/env elixir defmodule Actions.MyAction do def run(repos) do Enum.each(repos, fn repo -> repo_name = Path.basename(repo) IO.puts("Processing: #{repo_name}") # Your custom logic here # - Read files from repo # - Run git commands # - Analyze code # - Generate reports # etc. end) end end- Add command to
run.exs:
["my-action"] -> IO.puts("=== Running my action ===") run_action("actions/my_action.exs")tools/ ├── run.exs # Main runner ├── scan_repos.exs # Repo scanner ├── filter_repos.exs # Repo filter ├── mix.exs # Project dependencies ├── README.md # This file ├── .formatter.exs # Code formatter config ├── .gitignore # Git ignore rules ├── actions/ # Action modules │ ├── check_uncommitted.exs # Check git status │ ├── analyze_repos.exs # LLM analysis (stubbed) │ └── placeholder.exs # Template action └── (generated files) ├── repos.json # All found repos ├── repos_exclude.json # Repos minus excludes └── repos_filtered.json # Final filtered list Edit repos_exclude.json after running scan:
{ "repos": [ "/path/to/repo1", "/path/to/repo2" ] }Then run elixir run.exs filter to regenerate repos_filtered.json.
Edit actions/analyze_repos.exs:
# Change this line: @reference_repo "../gemini_ex" # To your preferred reference repo: @reference_repo "../my_reference_repo"The analyze_repos.exs action is stubbed and ready for LLM integration.
Dependencies are already in mix.exs. To integrate:
# In analyze_repos.exs, add after Mix.install if using as script: Mix.install([ {:jason, "~> 1.4"}, {:gemini_ex, "~> 0.1.0"} ]) # Then in analyze_repo function, replace stub with: def analyze_repo(ref_files, target_path) do # ... existing code ... prompt = create_analysis_prompt(ref_files, target_files, target_name) # Call Gemini api_key = System.get_env("GEMINI_API_KEY") result = GeminiEx.generate_content(api_key, prompt) IO.puts(result) end# Add to Mix.install: Mix.install([ {:jason, "~> 1.4"}, {:claude_code_sdk_elixir, "~> 0.1.0"} ]) # Replace stub with Claude call: def analyze_repo(ref_files, target_path) do # ... existing code ... prompt = create_analysis_prompt(ref_files, target_files, target_name) # Call Claude api_key = System.get_env("ANTHROPIC_API_KEY") result = ClaudeCodeSdk.generate(api_key, prompt) IO.puts(result) end- Make sure you ran
elixir run.exs setupfirst - Check that parent directory (
..) contains Elixir repos - Verify repos have both
.git/andmix.exs
- Check that
../gemini_exexists - Or change
@reference_repoinactions/analyze_repos.exs
- Ensure internet connection (Mix.install downloads from Hex)
- Check Elixir version:
elixir --version - Clear Mix cache:
rm -rf ~/.hex ~/.mix
# Setup elixir run.exs setup # Check status elixir run.exs uncommitted# Setup elixir run.exs setup # Analyze (currently shows what would be analyzed) elixir run.exs analyze# Initial scan elixir run.exs scan # Edit repos_exclude.json to exclude more repos # Add the full paths of repos you want to exclude # Re-filter elixir run.exs filter # Run action on filtered list elixir run.exs uncommitted- Simple: Plain Elixir scripts using Mix.install
- Modular: Actions are independent modules
- Extensible: Easy to add new actions
- Explicit: Reference repo hardcoded and printed
- Debuggable: Console logging throughout
- Stubbed: Framework ready for LLM integration
Potential additions (currently stubbed):
- CI/CD configuration analysis
- Test coverage reports
- Code formatting checks
- Dependency update scanning
- License compliance checking
- Documentation completeness scoring
- Performance benchmarking
- Security vulnerability scanning
To add a new action:
- Copy
actions/placeholder.exstoactions/your_action.exs - Implement your logic in the
run/1function - Add command mapping in
run.exs - Update this README with your action's documentation
This tool is part of your personal toolkit for managing Elixir repositories.
For issues or questions:
- Check the troubleshooting section
- Review the code - it's intentionally simple
- Modify as needed for your workflow