v.0.4.0: Implemented all community PRs and Fixes. #35/#64/#69/#84/#87/#97, fix #72/#86/#101#103
Open
django23 wants to merge 30 commits intostevegrunwell:developfrom
Open
v.0.4.0: Implemented all community PRs and Fixes. #35/#64/#69/#84/#87/#97, fix #72/#86/#101#103django23 wants to merge 30 commits intostevegrunwell:developfrom
django23 wants to merge 30 commits intostevegrunwell:developfrom
Conversation
- Removed PHP-based testing infrastructure, including PHPUnit and related files. - Introduced Bats as the new testing framework with corresponding test scripts. - Replaced Travis CI configuration with GitHub Actions for CI/CD. - Updated README to reflect new installation and usage instructions. - Added Makefile for simplified commands: `make install` and `make uninstall`. - Updated `.gitignore` to exclude new files and directories. - Enhanced the changelog with recent changes and additions.
- Added `make install` and `make uninstall` targets for easier setup and removal. - Introduced `scripts/uninstall.sh` for clean removal of Asimov and its launchd schedule. - Updated `com.stevegrunwell.asimov.plist` with common interval reference comments. - Moved the install script to `scripts/install.sh`, now copying the binary instead of symlinking. - Revised README to reflect new installation instructions and optional plist editing.
Add tests for all 34 sentinel pairs (up from 12), plus negative cases, ~/Library skip path, mixed dependency types, nested project handling, and find -prune verification. Split monolithic asimov.bats into sentinels.bats and behavior.bats for better organization.
Add exclusion patterns for modern development tooling that has emerged since the last update, covering JS frameworks, Clojure, Zig, OCaml, Elm, Godot, R, direnv, and additional Python/Elixir/Terraform variants. New patterns: .next, .nuxt, .angular, .svelte-kit, .turbo, .yarn, target/project.clj, target/deps.edn, .cpcache, .shadow-cljs, venv/pyproject.toml, __pypackages__, _build/mix.exs, .terraform, .direnv, _build/dune-project, .zig-cache, zig-out, elm-stuff, .godot, renv.
… badges Tighten the intro, add a supported ecosystems table covering all 30+ patterns, add a quick start section, update badges with logos, fix the Isaac Asimov typo, and streamline installation/contributing sections.
Add a comprehensive contributing guide covering setup, adding new dependency patterns, commit conventions, and project structure. Update copyright year to 2017-2026.
…upport Add glob pattern support for sentinel definitions so wildcards like *.xcodeproj can be used. Sentinels containing '*' use sh -c with ls -d for glob expansion instead of test -e, with no performance impact. Add DerivedData *.xcodeproj entry to exclude Xcode build artifacts when an Xcode project is present alongside the DerivedData directory. Inspired by stevegrunwell#64 (props @mdab121).
…light (#10) Add a note explaining that asimov does not hide directories from Spotlight indexing, with guidance on how to configure Spotlight privacy settings separately. Addresses stevegrunwell#90.
Exclude bin/ and obj/ directories when *.csproj (C#) or *.fsproj (F#) project files are present, using glob sentinel patterns. Inspired by stevegrunwell#87, props @guigomesa.
* docs(readme): clarify that asimov only affects Time Machine, not Spotlight Add a note explaining that asimov does not hide directories from Spotlight indexing, with guidance on how to configure Spotlight privacy settings separately. Addresses stevegrunwell#90. * feat(sentinels): add .NET project build directory exclusions Exclude bin/ and obj/ directories when *.csproj (C#) or *.fsproj (F#) project files are present, using glob sentinel patterns. Inspired by stevegrunwell#87, props @guigomesa. * feat: skip already-excluded directories for faster subsequent runs Use Spotlight metadata (mdfind) to identify directories already excluded from Time Machine and skip them during the find traversal. Also fixes a comment typo and removes duplicate Gradle sentinel entries. Inspired by stevegrunwell#97, props @VladRassokhin. * feat: exclude well-known global cache directories Add fixed directory exclusions for common tool caches (~/.cache, ~/.gradle/caches, ~/.m2/repository, ~/.npm/_cacache, ~/.nuget/packages, ~/.kube/cache) that are always safe to exclude without sentinel files. Inspired by stevegrunwell#69, props @pkuczynski.
When asimov runs as root (via brew services or sudo), ~ expands to /var/root. Now detects the console user via stat/dscl and uses their home directory instead. Addresses stevegrunwell#72.
Show the total count and combined size of newly excluded directories after each run, making it easy to see the impact at a glance. Inspired by stevegrunwell#84, props @Vadorequest.
When tmutil addexclusion fails (e.g. Error -20 or -50 on paths inside app bundles or with permission issues), skip the path with a warning instead of crashing. This allows asimov to continue processing remaining directories. Addresses stevegrunwell#101 and stevegrunwell#86.
Added .cursor, .idea, and .vscode to the .gitignore file to prevent these IDE-specific and cursor-related files from being tracked in the repository.
Changed the GitHub repository links in CONTRIBUTING.md and README.md from django23 to stevegrunwell to reflect the new repository ownership.
Introduced a new --dry-run flag that allows users to see which directories would be excluded from Time Machine backups without actually modifying any settings. This feature enhances usability by providing a preview of actions before execution. Updated relevant functions and tests to support this functionality. Also, refactored the handling of ASIMOV_ROOT to ensure correct path resolution when running as root, and made adjustments to the exclusion logic for improved performance.
Introduced `--help` and `--version` flags to the asimov script, enhancing user experience by providing usage information and version details. Updated the command-line argument parsing to handle unknown options gracefully, displaying an error message and usage instructions. Refactored the exclusion summary logic to improve clarity and maintainability. Also, updated documentation and tests to reflect these new features.
Bumped the version to 0.4.0 and added a new function, `record_excluded_path()`, to streamline the logging of excluded paths and their sizes. Implemented validation to ensure `ASIMOV_ROOT` exists before execution, improving error handling. Updated tests to cover scenarios with spaces in project paths and the new root directory validation. Enhanced documentation to reflect these changes.
Author
|
@stevegrunwell do you have time to check this so we can help you? |
|
@django23 are there build artifacts for your fork/version? |
Dropped macOS 13 from the CI test matrix as it has been retired. This change streamlines the testing process and ensures compatibility with supported macOS versions.
Author
Yes @sraka1 , there is a version available at: https://github.com/django23/asimov/releases/tag/v0.4.2 More improvements are coming. |
Author
|
Even more releases: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR represents a comprehensive modernization of Asimov; migrating the test infrastructure, fixing long-standing bugs reported by the community, and implementing a
number of widely-requested features and sentinel patterns. Every change is covered by tests.
I'm also writing this in the context of #99; I'd love to be considered as a maintainer. I've spent meaningful time on this
project, understand the architecture deeply, and have been actively triaging open issues and community PRs. More on that at the bottom.
Infrastructure & Testing
Test Suite Migration: PHP/PHPUnit → Bats
The existing PHP test suite required contributors to have PHP, Composer, and PHPUnit installed; a significant friction point for a bash utility. This PR replaces it
with Bats (Bash Automated Testing System), which:
brew install bats-core; already available for any macOS developertmutilandmdfindbinaries live intests/bin/and are written in bashtests/behavior.batscovers: negative cases, multi-match, idempotency, skip paths, nesting, fixed dirs, error handling, and summary outputtests/sentinels.batshas one test per sentinel pairRemoved:
composer.json,phpunit.xml.dist, and all PHP test infrastructure.CI: Travis CI → GitHub Actions
Travis CI has become unreliable for open source projects. The new pipeline runs on GitHub Actions with a macOS 14 + 15 matrix. The workflow file is at
.github/workflows/.Bug Fixes
Fix:
tmutilerrors no longer crash AsimovCloses #101 | Related: #86
Previously, a non-zero exit from
tmutil addexclusion(e.g. error-20or-50) would stop script execution entirely. Paths that fail exclusion are now skipped with awarning, allowing the run to continue.
Fix: Correct home directory detection when running as root
Closes #72
When Asimov runs via
sudoor as alaunchdservice (e.g.brew services start asimov),$HOMEresolves to/var/rootinstead of the user's actual home directory.This fix detects the logged-in user via
who/statand uses their real home directory asASIMOV_ROOT.Features
Exclude well-known global cache directories
Implements #69 (props @pkuczynski) | Addresses #58
Many tools write large caches to fixed global locations; these are never project-specific and never need backing up. Added unconditional exclusions (via
ASIMOV_FIXED_DIRS) for:~/.cache~/.gradle/caches~/.m2/repository~/.npm/_cacache~/.nuget/packages~/.kube/cache~/.Trash(already mentioned in legacy code)These are excluded whenever the directory exists, without requiring a sentinel file.
Run summary: total count and size of newly excluded directories
Closes #84 (props @Vadorequest)
Asimov now prints a summary at the end of each run showing how many directories were newly excluded and their total disk size. Subsequent runs correctly show zero if
nothing new was found (idempotent).
Skip directories already excluded from Time Machine
Implements #97 (props @VladRassokhin)
Before calling
tmutil addexclusion, Asimov now checks whether the directory is already excluded (viamdfind). This makes repeated runs significantly faster andavoids redundant
tmutilcalls. The mockmdfindbinary intests/bin/supports simulating pre-existing exclusions viaASIMOV_TEST_MDFIND_RESULTS.New Sentinel Patterns
Xcode DerivedData (glob sentinel support)
Implements #64 (props @mdab121)
Excludes
DerivedDatawhen a*.xcodeprojfile is present in the same directory. This required adding glob-pattern support to the sentinel system; wildcard sentinelsuse
sh -c 'ls -d ...'via-execdir, enabling patterns like*.xcodeprojwithout breaking existing exact-match sentinels..NET build output (
bin/,obj/)Implements #87 (props @guigomesa)
Excludes
binandobjdirectories when a*.csprojor*.fsprojfile is present (also uses glob sentinel support).21 new dependency patterns across 10 ecosystems
.nextnext.config.js/next.config.ts.nuxtnuxt.config.js/nuxt.config.ts.angularangular.json.svelte-kitsvelte.config.js.turboturbo.json.yarnyarn.locktarget,.cpcacheproject.clj/deps.edn.shadow-cljsshadow-cljs.ednvenvpyproject.toml__pypackages__pyproject.toml_buildmix.exs.terraform.terraform.lock.hcl.direnv.envrc(implements #98)_builddune-project.zig-cache,zig-outbuild.zigelm-stuffelm.json.godotproject.godotrenvrenv.lockAlso addresses #60 (Swift Package Manager) and #59 (Container/VM
directories).
Install / Uninstall Improvements
Implements #35 (props @sylver)
scripts/install.shnow copies the binary (rather than symlinking) with shared variablesscripts/uninstall.shcleanly removes Asimov and itslaunchdscheduleMakefilegainsmake installandmake uninstalltargetscom.stevegrunwell.asimov.plistmake exclusionstarget lists current Time Machine exclusions for debuggingDocumentation
CONTRIBUTING.mdwith setup instructions, test workflow, and conventionsREADME.mdwith ecosystem table, quick-start section, and current badgesnode_modulesfrom Spotlight #90On Maintainership
I commented on #99 expressing interest. I want to be transparent about my intentions here: this PR is not a bid for
ownership but a demonstration of genuine commitment. I've:
ASIMOV_FIXED_DIRS,tmutil/mdfindmocking)I'm happy to iterate on any part of this, split it into smaller PRs if that's easier to review, or work under @pkuczynski if that arrangement moves forward. I just want
this project to keep being useful.
Testing
brew install bats-core shellcheck make check # runs all tests + shellcheck All tests pass on macOS 14 and macOS 15.