forked from stevegrunwell/asimov
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathasimov
More file actions
executable file
·102 lines (89 loc) · 3.48 KB
/
asimov
File metadata and controls
executable file
·102 lines (89 loc) · 3.48 KB
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
#!/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
'.packages pubspec.yaml' # Pub (Dart)
'.stack-work stack.yaml' # Stack (Haskell)
'.vagrant Vagrantfile' # Vagrant
'Carthage Cartfile' # Carthage
'Pods Podfile' # CocoaPods
'bower_components bower.json' # Bower (JavaScript)
'node_modules package.json' # npm, Yarn (NodeJS)
'target Cargo.toml' # Cargo (Rust)
'target pom.xml' # Maven
'build build.gradle' # Gradle
'vendor composer.json' # Composer (PHP)
'vendor Gemfile' # Bundler (Ruby)
)
# 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 \
;