-
Notifications
You must be signed in to change notification settings - Fork 87
/
asimov
executable file
·125 lines (112 loc) · 4.88 KB
/
asimov
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env bash
set -Eeu -o pipefail
# Look through the local filesystem and exclude development dependencies
# from Apple Time Machine backups.
#
# Since these files can be restored easily via their respective installation
# tools, there's no reason to waste time/bandwidth on backing them up.
#
# To retrieve a full list of excluded files, you may run:
#
# sudo mdfind "com_apple_backup_excludeItem = 'com.apple.backupd'"
#
# For a full explanation, please see https://apple.stackexchange.com/a/25833/206772
#
# @version 0.3.0
# @author Steve Grunwell
# @license MIT
readonly ASIMOV_ROOT=~
# Paths to unconditionally skip over. This prevents Asimov from modifying the
# Time Machine exclusions for these paths (and decendents). It has an important
# side-effect of speeding up the search.
readonly ASIMOV_SKIP_PATHS=(
~/.Trash
~/Library
)
# A list of "directory"/"sentinel" pairs.
#
# Directories will only be excluded if the dependency ("sentinel") file exists.
#
# For example, 'node_modules package.json' means "exclude node_modules/ from the
# Time Machine backups if there is a package.json file next to it."
readonly ASIMOV_VENDOR_DIR_SENTINELS=(
'.build Package.swift' # Swift
'.gradle build.gradle' # Gradle
'.gradle build.gradle.kts' # Gradle Kotlin Script
'build build.gradle' # Gradle build files
'build build.gradle.kts' # Gradle Kotlin Script build files
'.dart_tool pubspec.yaml' # Flutter (Dart)
'.packages pubspec.yaml' # Pub (Dart)
'.stack-work stack.yaml' # Stack (Haskell)
'.tox tox.ini' # Tox (Python)
'.nox noxfile.py' # Nox (Python)
'.vagrant Vagrantfile' # Vagrant
'.venv requirements.txt' # virtualenv (Python)
'.venv pyproject.toml' # virtualenv (Python)
'Carthage Cartfile' # Carthage
'Pods Podfile' # CocoaPods
'bower_components bower.json' # Bower (JavaScript)
'build build.gradle' # Gradle
'build build.gradle.kts' # Gradle Kotlin Script
'build pubspec.yaml' # Flutter (Dart)
'build setup.py' # Python
'dist setup.py' # PyPI Publishing (Python)
'node_modules package.json' # npm, Yarn (NodeJS)
'.parcel-cache package.json' # Parcel v2 cache (JavaScript)
'target Cargo.toml' # Cargo (Rust)
'target pom.xml' # Maven
'target build.sbt' # Sbt (Scala)
'target plugins.sbt' # Sbt plugins (Scala)
'vendor composer.json' # Composer (PHP)
'vendor Gemfile' # Bundler (Ruby)
'vendor go.mod' # Go Modules (Golang)
'venv requirements.txt' # virtualenv (Python)
'deps mix.exs' # Mix dependencies (Elixir)
'.build mix.exs' # Mix build files (Elixir)
'.terraform.d .terraformrc' # Terraform plugin cache
'.terragrunt-cache terragrunt.hcl' # Terragrunt
'cdk.out cdk.json' # AWS CDK
)
# Exclude the given paths from Time Machine backups.
# Reads the newline-separated list of paths from stdin.
exclude_file() {
local path
while IFS=$'\n' read -r path; do
if tmutil isexcluded "${path}" | grep -Fq '[Excluded]'; then
echo "- ${path} is already excluded, skipping."
continue
fi
tmutil addexclusion "${path}"
sizeondisk=$(du -hs "${path}" | cut -f1)
echo "- ${path} has been excluded from Time Machine backups (${sizeondisk})."
done
}
# Iterate over the skip directories to construct the `find` expression.
declare -a find_parameters_skip=()
for d in "${ASIMOV_SKIP_PATHS[@]}"; do
find_parameters_skip+=( -not \( -path "${d}" -prune \) )
done
# Iterate over the directory/sentinel pairs to construct the `find` expression.
declare -a find_parameters_vendor=()
for i in "${ASIMOV_VENDOR_DIR_SENTINELS[@]}"; do
read -ra parts <<< "${i}"
# Add this folder to the `find` list, allowing a single `find` command to find all
_exclude_name="${parts[0]}"
_sibling_sentinel_name="${parts[1]}"
# Given a directory path, determine if the corresponding file (relative
# to that directory) is available.
#
# For example, when looking at a /vendor directory, we may choose to
# ensure a composer.json file is available.
find_parameters_vendor+=( -or \( \
-type d \
-name "${_exclude_name}" \
-execdir test -e "${_sibling_sentinel_name}" \; \
-prune \
-print \
\) )
done
printf '\n\033[0;36mFinding dependency directories with corresponding definition files…\033[0m\n'
find "${ASIMOV_ROOT}" \( "${find_parameters_skip[@]}" \) \( -false "${find_parameters_vendor[@]}" \) \
| exclude_file \
;