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