nix-helpers: 7088ca92cb14775b21217c274acb49fbca96e915
1: # A wrapper around the 'replace' command, which is simpler and saner. We used to
2: # use a binary from MariaDB but it's now removed, and it was a heavy dependency.
3: { bash, die, fail, mkBin, runCommand, nixpkgs }:
4:
5: with builtins;
6: assert nixpkgs ? replace || die { error = "No 'replace' in given nixpkgs."; };
7: with { delim = x: "$" + "{" + x + "}"; };
8: mkBin {
9: name = "replace";
10: paths = [ bash fail ];
11: script = ''
12: #!${bash}/bin/bash
13: set -e
14:
15: REPLACEMENTS=()
16: FILES=()
17:
18: function nonEven {
19: fail "Non-even number of replacement strings. Found string pairs '${
20: delim "REPLACEMENTS[*]"
21: }' and failed with leftovers '$*'."
22: }
23:
24: function dodgy {
25: # Check for strings beginning with "-" in case 'go' treats them as flags
26: # FIXME: There should be a way to do this.
27: if [[ "x${delim "1:0:1"}" = "x-" ]]
28: then
29: return 0
30: else
31: return 1
32: fi
33: }
34:
35: # Keep popping off pairs of strings, until we run out or hit "--"
36: while [[ "$#" -gt 0 ]]
37: do
38: # "--" should only appear after a pair of strings, not a single string.
39: if [[ "x$2" = "x--" ]]
40: then
41: nonEven
42: exit 1 # Just in case
43: fi
44:
45: # If we find "--" then shift it off and break the loop; any remaining
46: # arguments will be treated as filenames.
47: if [[ "x$1" = "x--" ]]
48: then
49: shift
50: break
51: fi
52:
53: # Shouldn't have a lone replacement string, even without "--"
54: if [[ "$#" -lt 2 ]]
55: then
56: nonEven
57: exit 1 # Just in case
58: fi
59:
60: [[ -z "$1" ]] && fail "Can't replace empty string"
61: dodgy "$1" && fail "Can't replace strings ($1) beginning with '-'"
62: dodgy "$2" && fail "Can't insert strings ($2) beginning with '-'"
63:
64: # If we reach here we have another old/new pair of strings to replace
65: if [[ "${delim "#REPLACEMENTS[@]"}" -gt 0 ]]
66: then
67: REPLACEMENTS=("${delim "REPLACEMENTS[@]"}" -a "$1" "$2")
68: else
69: # First pair doesn't need "-a" flag
70: REPLACEMENTS=("${delim "REPLACEMENTS[@]"}" "$1" "$2")
71: fi
72: shift
73: shift
74: done
75:
76: [[ "${delim "#REPLACEMENTS[@]"}" -gt 0 ]] || fail "No replacements given?"
77:
78: # Gather up remain args as filenames to process in-place
79: while [[ "$#" -gt 0 ]]
80: do
81: dodgy "$1" && fail "Spotted dodgy argument '$1' (empty or '-')"
82: FILES=("${delim "FILES[@]"}" "$1")
83: shift
84: done
85:
86: function go {
87: # Do the actual replacement. The 'replace' command does the magic, but
88: # we constrain its peculiar defaults:
89: # -e forces case sensitivity
90: # -s allows replacement anywhere, not just at "word boundaries"
91: # -f forces in-place replacement,
92: "${nixpkgs.replace}/bin/replace-literal" -e -s "$@"
93: }
94:
95: if [[ "${delim "#FILES[@]"}" -eq 0 ]]
96: then
97: # No files, use stdio
98: go "${delim "REPLACEMENTS[@]"}"
99: exit 0
100: else
101: # Filenames given, replace them without backing up
102: go -f "${delim "REPLACEMENTS[@]"}" "${delim "FILES[@]"}"
103: exit 0
104: fi
105: '';
106: }
Generated by git2html.