-
-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
995f763
commit 0a22f98
Showing
43 changed files
with
1,844 additions
and
0 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
pkgs/build-support/setup-hooks/arrayUtilities/arrayDifference/arrayDifference.bash
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# shellcheck shell=bash | ||
|
||
# arrayDifference | ||
# Computes the difference of two arrays. | ||
# Arguments: | ||
# - inputArr1Ref: a reference to an array (not mutated) | ||
# - inputArr2Ref: a reference to an array (not mutated) | ||
# - outputArrRef: a reference to an array (mutated) | ||
# Returns 0. | ||
arrayDifference() { | ||
if (($# != 3)); then | ||
nixErrorLog "expected three arguments!" | ||
nixErrorLog "usage: arrayDifference inputArr1Ref inputArr2Ref outputArrRef" | ||
exit 1 | ||
fi | ||
|
||
local -rn inputArr1Ref="$1" | ||
local -rn inputArr2Ref="$2" | ||
# shellcheck disable=SC2178 | ||
# don't warn about outputArrRef being used as an array because it is an array. | ||
local -rn outputArrRef="$3" | ||
|
||
if ! isDeclaredArray "${!inputArr1Ref}"; then | ||
nixErrorLog "first arugment inputArr1Ref must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
if ! isDeclaredArray "${!inputArr2Ref}"; then | ||
nixErrorLog "second arugment inputArr2Ref must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
if ! isDeclaredArray "${!outputArrRef}"; then | ||
nixErrorLog "third arugment outputArrRef must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
# TODO: Use an O(n) algorithm instead of O(n^2). | ||
local entry | ||
for entry in "${inputArr1Ref[@]}"; do | ||
if ! occursInArray "$entry" "${!inputArr2Ref}"; then | ||
outputArrRef+=("$entry") | ||
fi | ||
done | ||
|
||
return 0 | ||
} | ||
|
||
# Prevent re-declaration | ||
readonly -f arrayDifference |
20 changes: 20 additions & 0 deletions
20
pkgs/build-support/setup-hooks/arrayUtilities/arrayDifference/package.nix
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
callPackages, | ||
isDeclaredArray, | ||
lib, | ||
makeSetupHook', | ||
occursInArray, | ||
}: | ||
makeSetupHook' { | ||
name = "arrayDifference"; | ||
script = ./arrayDifference.bash; | ||
nativeBuildInputs = [ | ||
isDeclaredArray | ||
occursInArray | ||
]; | ||
passthru.tests = callPackages ./tests.nix { }; | ||
meta = { | ||
description = "Computes the difference of two arrays"; | ||
maintainers = [ lib.maintainers.connorbaker ]; | ||
}; | ||
} |
91 changes: 91 additions & 0 deletions
91
pkgs/build-support/setup-hooks/arrayUtilities/arrayDifference/tests.nix
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# NOTE: Tests related to arrayDifference go here. | ||
{ | ||
arrayDifference, | ||
lib, | ||
testers, | ||
}: | ||
let | ||
inherit (lib.attrsets) recurseIntoAttrs removeAttrs; | ||
inherit (testers) testEqualArrayOrMap; | ||
check = | ||
args: | ||
(testEqualArrayOrMap ( | ||
(removeAttrs args [ "valuesToRemoveArray" ]) | ||
// { | ||
script = '' | ||
set -eu | ||
if isDeclaredArray valuesToRemoveArray; then | ||
nixLog "using valuesToRemoveArray: $(declare -p valuesToRemoveArray)" | ||
else | ||
nixErrorLog "valuesToRemoveArray must be a declared array" | ||
fi | ||
nixLog "running arrayDifference with valuesArray and valuesToRemoveArray to populate actualArray" | ||
arrayDifference valuesArray valuesToRemoveArray actualArray | ||
''; | ||
} | ||
)).overrideAttrs | ||
(prevAttrs: { | ||
inherit (args) valuesToRemoveArray; | ||
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [ arrayDifference ]; | ||
}); | ||
in | ||
recurseIntoAttrs { | ||
empty = check { | ||
name = "empty"; | ||
valuesArray = [ ]; | ||
valuesToRemoveArray = [ ]; | ||
expectedArray = [ ]; | ||
}; | ||
singleton = check { | ||
name = "singleton"; | ||
valuesArray = [ "apple" ]; | ||
valuesToRemoveArray = [ ]; | ||
expectedArray = [ "apple" ]; | ||
}; | ||
singleton-made-empty = check { | ||
name = "singleton-made-empty"; | ||
valuesArray = [ "apple" ]; | ||
valuesToRemoveArray = [ "apple" ]; | ||
expectedArray = [ ]; | ||
}; | ||
singleton-none-matching = check { | ||
name = "singleton-none-matching"; | ||
valuesArray = [ "apple" ]; | ||
valuesToRemoveArray = [ "bee" ]; | ||
expectedArray = [ "apple" ]; | ||
}; | ||
preserves-duplicates = check { | ||
name = "preserves-duplicates"; | ||
valuesArray = [ | ||
"apple" | ||
"bee" | ||
"apple" | ||
]; | ||
valuesToRemoveArray = [ "bee" ]; | ||
expectedArray = [ | ||
"apple" | ||
"apple" | ||
]; | ||
}; | ||
order-of-first-array-preserved = check { | ||
name = "order-of-first-array-preserved"; | ||
valuesArray = [ | ||
"apple" | ||
"cat" | ||
"bee" | ||
"dog" | ||
"apple" | ||
"bee" | ||
]; | ||
valuesToRemoveArray = [ | ||
"bee" | ||
"apple" | ||
]; | ||
expectedArray = [ | ||
"cat" | ||
"dog" | ||
]; | ||
}; | ||
# TODO: Negative tests. | ||
} |
70 changes: 70 additions & 0 deletions
70
pkgs/build-support/setup-hooks/arrayUtilities/arrayReplace/arrayReplace.bash
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# shellcheck shell=bash | ||
|
||
# arrayReplace | ||
# Replaces all occurrences of each key of inputMapRef in inputArrRef with the values provided by the delimted string in | ||
# the corresponding value of inputMapRef. | ||
# Arguments: | ||
# - inputArrRef: a reference to an array (not mutated) | ||
# - inputMapRef: a reference to an associative array (not mutated) | ||
# - delimiter: a character used to delimit the values in inputMapRef | ||
# - outputArrRef: a reference to an array (mutated) | ||
arrayReplace() { | ||
if (($# != 4)); then | ||
nixErrorLog "expected four arguments!" | ||
nixErrorLog "usage: arrayReplace inputArrRef inputMapRef delimiter outputArrRef" | ||
exit 1 | ||
fi | ||
|
||
local -rn inputArrRef="$1" | ||
local -rn inputMapRef="$2" | ||
local -r delimiter="$3" | ||
# shellcheck disable=SC2178 | ||
local -rn outputArrRef="$4" | ||
|
||
if ! isDeclaredArray "${!inputArrRef}"; then | ||
nixErrorLog "first arugment inputArrRef must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
if ! isDeclaredMap "${!inputMapRef}"; then | ||
nixErrorLog "second arugment inputMapRef must be an associative array reference" | ||
exit 1 | ||
fi | ||
|
||
if ! isDeclaredArray "${!outputArrRef}"; then | ||
nixErrorLog "third arugment outputArrRef must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
# Early return for empty array and replacement map. | ||
if ((${#inputArrRef[@]} == 0)); then | ||
outputArrRef=() | ||
return 0 | ||
elif ((${#inputMapRef[@]} == 0)); then | ||
outputArrRef=("${inputArrRef[@]}") | ||
return 0 | ||
fi | ||
|
||
local elem | ||
local replacementString | ||
local -a replacementElemArray=() | ||
for elem in "${inputArrRef[@]}"; do | ||
# NOTE: We must use the slow check for key presence because we need to be able to discern between the key being | ||
# absent and the key being present with an empty string as the value. | ||
if occursInMapKeys "$elem" "${!inputMapRef}"; then | ||
replacementString="${inputMapRef["$elem"]}" | ||
replacementElemArray=() | ||
if [[ -n $replacementString ]]; then | ||
mapfile -d "$delimiter" -t replacementElemArray < <(echo -n "$replacementString") | ||
fi | ||
outputArrRef+=("${replacementElemArray[@]}") | ||
else | ||
outputArrRef+=("$elem") | ||
fi | ||
done | ||
|
||
return 0 | ||
} | ||
|
||
# Prevent re-declaration | ||
readonly -f arrayReplace |
22 changes: 22 additions & 0 deletions
22
pkgs/build-support/setup-hooks/arrayUtilities/arrayReplace/package.nix
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
callPackages, | ||
lib, | ||
makeSetupHook', | ||
isDeclaredArray, | ||
isDeclaredMap, | ||
occursInMapKeys, | ||
}: | ||
makeSetupHook' { | ||
name = "arrayReplace"; | ||
script = ./arrayReplace.bash; | ||
nativeBuildInputs = [ | ||
isDeclaredArray | ||
isDeclaredMap | ||
occursInMapKeys | ||
]; | ||
passthru.tests = callPackages ./tests.nix { }; | ||
meta = { | ||
description = "Replaces all occurrences of a value in an array with other value(s)"; | ||
maintainers = [ lib.maintainers.connorbaker ]; | ||
}; | ||
} |
102 changes: 102 additions & 0 deletions
102
pkgs/build-support/setup-hooks/arrayUtilities/arrayReplace/tests.nix
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# NOTE: Tests related to arrayReplace go here. | ||
{ | ||
arrayReplace, | ||
lib, | ||
testers, | ||
}: | ||
let | ||
inherit (lib.attrsets) recurseIntoAttrs removeAttrs; | ||
inherit (testers) testEqualArrayOrMap; | ||
check = | ||
args: | ||
(testEqualArrayOrMap ( | ||
(removeAttrs args [ "delimiter" ]) | ||
// { | ||
script = '' | ||
set -eu | ||
nixLog "running arrayReplace with valuesArray and valuesMap to populate actualArray" | ||
arrayReplace valuesArray valuesMap "$delimiter" actualArray | ||
''; | ||
} | ||
)).overrideAttrs | ||
(prevAttrs: { | ||
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [ arrayReplace ]; | ||
inherit (args) delimiter; | ||
}); | ||
in | ||
recurseIntoAttrs { | ||
empty-with-string = check { | ||
name = "empty"; | ||
valuesArray = [ ]; | ||
valuesMap = { }; | ||
delimiter = " "; | ||
expectedArray = [ ]; | ||
}; | ||
singleton = check { | ||
name = "singleton"; | ||
valuesArray = [ "apple" ]; | ||
valuesMap = { }; | ||
delimiter = " "; | ||
expectedArray = [ "apple" ]; | ||
}; | ||
singleton-made-empty = check { | ||
name = "singleton-made-empty"; | ||
valuesArray = [ "apple" ]; | ||
valuesMap = { | ||
"apple" = ""; | ||
}; | ||
delimiter = " "; | ||
expectedArray = [ ]; | ||
}; | ||
singleton-made-singleton = check { | ||
name = "singleton-made-singleton"; | ||
valuesArray = [ "apple" ]; | ||
valuesMap = { | ||
"apple" = "bee"; | ||
}; | ||
delimiter = " "; | ||
expectedArray = [ "bee" ]; | ||
}; | ||
singleton-none-matching = check { | ||
name = "singleton-none-matching"; | ||
valuesArray = [ "apple" ]; | ||
valuesMap = { | ||
"bee" = "cat"; | ||
}; | ||
delimiter = " "; | ||
expectedArray = [ "apple" ]; | ||
}; | ||
# preserves-duplicates = check { | ||
# name = "preserves-duplicates"; | ||
# valuesArray = [ | ||
# "apple" | ||
# "bee" | ||
# "apple" | ||
# ]; | ||
# valuesToRemoveArray = [ "bee" ]; | ||
# expectedArray = [ | ||
# "apple" | ||
# "apple" | ||
# ]; | ||
# }; | ||
# order-of-first-array-preserved = check { | ||
# name = "order-of-first-array-preserved"; | ||
# valuesArray = [ | ||
# "apple" | ||
# "cat" | ||
# "bee" | ||
# "dog" | ||
# "apple" | ||
# "bee" | ||
# ]; | ||
# valuesToRemoveArray = [ | ||
# "bee" | ||
# "apple" | ||
# ]; | ||
# expectedArray = [ | ||
# "cat" | ||
# "dog" | ||
# ]; | ||
# }; | ||
# TODO: Negative tests. | ||
} |
31 changes: 31 additions & 0 deletions
31
pkgs/build-support/setup-hooks/arrayUtilities/arraysAreEqual/arraysAreEqual.bash
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# shellcheck shell=bash | ||
|
||
arraysAreEqual() { | ||
if (($# != 2)); then | ||
nixErrorLog "expected two arguments!" | ||
nixErrorLog "usage: arraysAreEqual inputArr1Ref inputArr2Ref" | ||
exit 1 | ||
fi | ||
|
||
local -rn inputArr1Ref="$1" | ||
local -rn inputArr2Ref="$2" | ||
|
||
if ! isDeclaredArray "${!inputArr1Ref}"; then | ||
nixErrorLog "first arugment inputArr1Ref must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
if ! isDeclaredArray "${!inputArr2Ref}"; then | ||
nixErrorLog "second arugment inputArr2Ref must be an array reference" | ||
exit 1 | ||
fi | ||
|
||
if [[ ${#inputArr1Ref[@]} -ne ${#inputArr2Ref[@]} || ${inputArr1Ref[*]@K} != "${inputArr2Ref[*]@K}" ]]; then | ||
return 1 | ||
fi | ||
|
||
return 0 | ||
} | ||
|
||
# Prevent re-declaration | ||
readonly -f arraysAreEqual |
Oops, something went wrong.