cesarferreira/dryrun
☁️ Try the demo project of any Android Library
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 6mo ago
- ✓7 active contributors
- ✓MIT licensed
Show 4 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Slowing — last commit 6mo ago
- ⚠Concentrated ownership — top contributor handles 70% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/cesarferreira/dryrun)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/cesarferreira/dryrun on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: cesarferreira/dryrun
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cesarferreira/dryrun shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 6mo ago
- 7 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Slowing — last commit 6mo ago
- ⚠ Concentrated ownership — top contributor handles 70% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live cesarferreira/dryrun
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/cesarferreira/dryrun.
What it runs against: a local clone of cesarferreira/dryrun — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in cesarferreira/dryrun | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 221 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cesarferreira/dryrun. If you don't
# have one yet, run these first:
#
# git clone https://github.com/cesarferreira/dryrun.git
# cd dryrun
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of cesarferreira/dryrun and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cesarferreira/dryrun(\\.git)?\\b" \\
&& ok "origin remote is cesarferreira/dryrun" \\
|| miss "origin remote is not cesarferreira/dryrun (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 221 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~191d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cesarferreira/dryrun"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
dryrun is a Ruby CLI tool that clones any Android library from GitHub and runs it directly on a connected device or emulator without opening Android Studio. It automates the tedious workflow of downloading, importing, syncing Gradle, and deploying—reducing library testing from 10+ manual steps to a single command like dryrun https://github.com/cesarferreira/android-helloworld. Single-package Ruby gem structure: bin/dryrun is the CLI entry point; lib/dryrun/ contains core logic modules (android_project.rb orchestrates the workflow, gradle_adapter.rb wraps Gradle, manifest_parser.rb reads AndroidManifest.xml, device.rb abstracts ADB interaction, github.rb clones repos). The gem is published via dryrun.gemspec; docs/ holds a minimal static site.
👥Who it's for
Android library developers and QA engineers who need to quickly test third-party Android libraries on real devices without the overhead of Android Studio, plus library maintainers who want to streamline demo/testing workflows for contributors.
🌱Maturity & risk
Moderately mature and stable. The project has a Gem badge, was featured in Android Weekly #200, has closed issue tracking, and includes CI via Travis (.travis.yml). However, the repo lacks a recent commit timestamp in the provided data; the codebase is primarily Ruby (25K LOC) with modest test coverage (spec/ folder exists but limited test files visible). Verdict: actively maintained but not heavily updated—suitable for production use with awareness that active development may be intermittent.
Low-to-moderate risk. Single maintainer (Cesar Ferreira) concentrates knowledge. Tight coupling to Android SDK environment variables ($ANDROID_SDK_ROOT) and Git availability creates brittle external dependencies. Windows support requires manual PATH setup (.gitignore and environment docs suggest fragile cross-platform handling). No indication of automated testing for all OS/SDK variants.
Active areas of work
No explicit recent activity visible in the file list, but the existence of multiple usage GIFs (usage_v2.gif through usage_v4.gif in extras/) suggests iterative UI improvements. The .rubocop.yml and Rakefile indicate ongoing code quality maintenance. No open PR or milestone data provided.
🚀Get running
gem install dryrun
dryrun https://github.com/cesarferreira/android-helloworld
Ensure $ANDROID_SDK_ROOT is set, adb is in PATH, a device/emulator is connected, and (on Windows) Git/cmd is in PATH.
Daily commands:
bundle install
rake # runs tests
# or directly:
bin/dryrun https://github.com/USER/REPO
Rakefile likely defines test tasks; see .rspec for RSpec config.
🗺️Map of the codebase
- bin/dryrun: CLI entry point; parses all command-line arguments (-m, -b, -f, -p, -t, -c, -w, -a flags) and orchestrates the workflow.
- lib/dryrun/android_project.rb: Core orchestrator; manages the full lifecycle: Git cloning, Gradle detection, module selection, APK building, and ADB installation.
- lib/dryrun/gradle_adapter.rb: Abstracts Gradle interaction; builds APK with custom flavors/variants and handles module-specific build commands.
- lib/dryrun/manifest_parser.rb: Parses AndroidManifest.xml to extract module names and launch activities, enabling auto-detection of testable targets.
- lib/dryrun/device.rb: Wraps ADB commands; detects connected devices/emulators and handles APK installation and app launching.
- lib/dryrun/github.rb: Git repository cloning logic; supports SSH keys for private repos and branch/tag/commit checkout.
- dryrun.gemspec: Gem metadata and dependency declarations; defines gem version, Ruby compatibility, and required gems.
🛠️How to make changes
Adding new features: Start in lib/dryrun/android_utils.rb or lib/dryrun/dryrun_utils.rb for Android-specific logic. Improving device detection: Modify lib/dryrun/device.rb. Parsing Android configs: Edit lib/dryrun/manifest_parser.rb. Gradle integration: Extend lib/dryrun/gradle_adapter.rb. New CLI flags: Update bin/dryrun argument parsing. Tests: Add specs to spec/ following patterns in spec/dryrun_spec.rb and spec/github_spec.rb.
🪤Traps & gotchas
- $ANDROID_SDK_ROOT must be set — tool silently fails if not. No fallback to $ANDROID_HOME. 2. ADB PATH dependency — adb must be in $PATH or in $ANDROID_SDK_ROOT/platform-tools; Gradle wrapper may not find it. 3. Git SSH on Windows — private repos require Git/cmd in PATH; HTTPS not mentioned as alternative. 4. Temporary folder location — scripts clone to a fixed dryrun temp directory (likely ~/.dryrun); --wipe and --cleanup flags manage this but can conflict if not understood. 5. Gradle wrapper assumption — code likely expects gradlew to exist in cloned repos; standalone Gradle projects may fail. 6. Device/emulator must be running — tool has no fallback or error message if no device is available at runtime.
💡Concepts to learn
- Android Manifest Introspection — manifest_parser.rb must extract launch activities and module names from XML without an XML parser dependency; understanding how to parse partial/malformed XML safely is key to robust parsing.
- Gradle Build Variants & Flavors — The --flavour flag (lib/dryrun/gradle_adapter.rb) must construct correct Gradle tasks (e.g., assembleDebugFlavor); misunderstanding build variants breaks multi-flavor library testing.
- ADB Protocol & Device Detection — lib/dryrun/device.rb uses ADB to push APKs and launch activities; understanding ADB connection states and am instrument commands is critical for reliable device interaction.
- Git Shallow Clone & Sparse Checkout — lib/dryrun/github.rb clones full repos which can be slow; optimizing with git clone --depth or sparse-checkout could dramatically improve performance for large repos.
- Ruby Subprocess Management & Shell Escaping — bin/dryrun and adapters execute system commands (Git, Gradle, ADB) via shell; improper quoting/escaping of paths with spaces or special chars is a common failure mode.
- Gradle Daemon Process Lifecycle — Repeated dryrun invocations spawn Gradle daemons that can consume memory; understanding daemon shutdown and reuse is important for production scaling.
🔗Related repos
robovm/robovm— Alternative approach to cross-platform Android testing (now archived); shows contrast with dryrun's philosophy of CLI-based library demoing.facebook/buck— Build system alternative to Gradle used in some Android projects; dryrun's gradle_adapter.rb would need extension to support Buck projects.google/bundletool— Official Google tool for APK bundling and testing; dryrun could integrate bundletool for more sophisticated variant selection and testing.fastlane/fastlane— Ruby-based mobile CI/CD automation; shares similar goals of automating Android workflows and could be a complementary tool for library publishers.gradle/gradle— The underlying build system that dryrun wraps; understanding Gradle's daemon, task model, and variant system is essential for extending dryrun's gradle_adapter.rb.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for lib/dryrun/manifest_parser.rb
The manifest_parser.rb is a critical component for parsing Android manifests, but there are minimal tests in spec/dryrun_spec.rb. A new test file spec/manifest_parser_spec.rb would ensure robustness when handling various manifest structures, edge cases (missing attributes, malformed XML), and different Android versions. This directly impacts the reliability of the tool's core functionality.
- [ ] Create spec/manifest_parser_spec.rb with test cases
- [ ] Add tests for valid manifest parsing with different package names
- [ ] Add tests for edge cases: empty manifests, missing attributes, malformed XML
- [ ] Add tests for extracting application names and permissions
- [ ] Run tests with
bundle exec rspec spec/manifest_parser_spec.rb
Add GitHub Actions CI workflow to replace Travis CI
.travis.yml is present but GitHub Actions is now the standard for GitHub repos. Create a modern CI workflow that runs RSpec tests on multiple Ruby versions (2.6+) and validates the gem build. This ensures the project stays current with GitHub's native CI/CD and improves contributor experience.
- [ ] Create .github/workflows/ci.yml with standard Ruby testing setup
- [ ] Configure matrix testing for Ruby 2.6, 2.7, 3.0+
- [ ] Add steps: checkout, setup Ruby, bundle install, rspec, gem build
- [ ] Add status badge to README.md pointing to GitHub Actions workflow
- [ ] Test workflow by pushing to a feature branch and verifying it runs
Add integration tests for lib/dryrun/github.rb GitHub API interactions
spec/github_spec.rb exists but likely lacks comprehensive coverage of GitHub API interactions (repo cloning, branch detection, authentication). Add VCR cassettes or mock-based tests to verify the GitHub module correctly handles various scenarios: public/private repos, rate limiting, network errors. This prevents regressions when the GitHub API changes.
- [ ] Expand spec/github_spec.rb with tests for repo URL parsing
- [ ] Add tests for successful repository cloning scenarios
- [ ] Add tests for error handling: 404 repos, network timeouts, authentication failures
- [ ] Consider adding VCR gem for recording/replaying HTTP interactions (add to Gemfile)
- [ ] Verify tests run with
bundle exec rspec spec/github_spec.rb
🌿Good first issues
- Add integration tests for the android_utils.rb helper functions (lib/dryrun/android_utils.rb). The spec/ folder only has dryrun_spec.rb and github_spec.rb; utility functions lack test coverage and are likely fragile on edge cases.
- Improve Windows cross-platform support documentation and testing. README mentions Git/cmd PATH requirement but does not validate or auto-detect it; add a spec test (spec/windows_compat_spec.rb) that stubs Windows PATH behavior.
- Add a --list-devices flag to show connected devices before running, with prompt to select. Currently device selection is opaque; the device.rb module could expose a list_available_devices method to improve UX.
⭐Top contributors
Click to expand
Top contributors
- @cesarferreira — 70 commits
- @luispereira — 13 commits
- @ghostbuster91 — 9 commits
- [@Amaël Sikel](https://github.com/Amaël Sikel) — 5 commits
- @matejsemancik — 1 commits
📝Recent commits
Click to expand
Recent commits
3cdd6e8— Update badge links in README.md (cesarferreira)0ca622b— updated version (cesarferreira)898b1e5— Fix constant initialization (Amaël Sikel)4f616d5— Bump version (Amaël Sikel)a77770d— Cleanup + update notes (Amaël Sikel)2819b50— Update README.md (Amaël Sikel)5644cf3— Update environment variable (Amaël Sikel)8794d8a— fixes issue #135 (cesarferreira)d4e51b0— Update README.md (cesarferreira)ae99882— Update README.md (cesarferreira)
🔒Security observations
This Ruby gem for testing Android libraries has moderate security concerns. The primary risks stem from executing arbitrary code from untrusted sources (GitHub repositories and Gradle builds) with minimal validation. The application lacks input validation on repository URLs, secure XML parsing hardening, and command injection protections. Dependency security scanning is not evident. Immediate focus should be on implementing strict validation for external inputs, sandboxing code execution, and adding dependency vulnerability checks. The codebase lacks security testing evidence (no security-focused tests visible in spec files).
- High · External GitHub Repository Access Without Authentication —
lib/dryrun/github.rb. The file lib/dryrun/github.rb suggests the application fetches and executes code from GitHub repositories. Without proper authentication and verification mechanisms, this could expose users to man-in-the-middle attacks or compromised repositories. Fix: Implement HTTPS-only communication, verify GPG signatures of repositories, use authenticated GitHub API calls with rate limiting, and validate repository integrity before cloning/executing. - High · Arbitrary Code Execution Risk via Gradle —
lib/dryrun/gradle_adapter.rb, lib/dryrun/test_application_command.rb. The gradle_adapter.rb and test_application_command.rb modules execute Gradle build commands and Android APK installation. Gradle build scripts can contain arbitrary code execution, and untrusted library repositories could inject malicious code during the build process. Fix: Validate and sandbox Gradle execution, use dependency verification mechanisms, implement build artifact signing verification, and isolate execution in containers. - Medium · Manifest Parser - Potential XML External Entity (XXE) Attack —
lib/dryrun/manifest_parser.rb. The manifest_parser.rb processes Android manifest XML files. Without proper XML parser hardening, this could be vulnerable to XXE attacks if malicious manifest files are processed. Fix: Use secure XML parsing libraries with XXE protection disabled by default. Validate and sanitize manifest file input before parsing. - Medium · Insufficient Input Validation on GitHub URLs —
lib/dryrun/github.rb, bin/dryrun. The application accepts GitHub repository URLs as input. Without proper validation, users could be tricked into cloning repositories with path traversal or injection attacks. Fix: Implement strict URL validation (whitelist GitHub domains), sanitize repository paths, reject special characters and path traversal attempts. - Medium · Missing Dependency Lock File Security —
Gemfile.lock, Gemfile. While Gemfile.lock exists, there's no evidence of dependency vulnerability scanning or pinned versions verification in the provided configuration files. Fix: Integrate automated dependency scanning tools (Bundler Audit), pin specific versions, regularly update dependencies, and audit transitive dependencies. - Low · Potential Command Injection via Shell Execution —
lib/dryrun/android_utils.rb, lib/dryrun/install_application_command.rb. Multiple files (android_utils.rb, install_application_command.rb) likely use shell commands to interact with Android tools and adb. Improper argument escaping could lead to command injection. Fix: Use parameterized command execution (avoid shell=true), properly escape all user-controlled input, prefer Ruby APIs over shell commands where possible. - Low · Missing Security Headers in Documentation Site —
docs/index.html, docs/js/index.js. The docs folder contains HTML/JS files that could be served as a website. No evidence of security headers or CSP policies in the provided structure. Fix: Add security headers (Content-Security-Policy, X-Frame-Options, X-Content-Type-Options) when serving documentation, minimize inline JavaScript.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.