mirror of
https://github.com/kennethreitz/bake.git
synced 2026-06-05 23:00:17 +00:00
tests
This commit is contained in:
+7
-5
@@ -27,13 +27,14 @@ class Bakefile:
|
||||
if not os.path.exists(path):
|
||||
raise NoBakefileFound()
|
||||
|
||||
self.cache = Cache(bf=self, debug=self.debug)
|
||||
self.skip_cache = Cache(bf=self, namespace="skips", debug=self.debug)
|
||||
self.env_cache = Cache(bf=self, namespace="env.allowed", debug=self.debug)
|
||||
|
||||
# Set environment variables for 'bake's that run underneath of us.
|
||||
os.environ["BAKE_SKIP_DONE"] = "1"
|
||||
os.environ["BAKE_SILENT"] = "1"
|
||||
os.environ["PYTHONUNBUFFERED"] = "1"
|
||||
os.environ["BAKEFILE_PATH"] = self.path
|
||||
os.environ["BAKEFILE"] = self.path
|
||||
|
||||
self.chunks
|
||||
self._tasks = None
|
||||
@@ -141,6 +142,7 @@ class Bakefile:
|
||||
root=os.getcwd(),
|
||||
max_depth=4,
|
||||
topdown=False,
|
||||
**kwargs,
|
||||
):
|
||||
"""Returns the path of a Bakefile in parent directories."""
|
||||
|
||||
@@ -149,7 +151,7 @@ class Bakefile:
|
||||
if i > max_depth:
|
||||
break
|
||||
elif filename in f:
|
||||
return Class(path=os.path.join(c, filename))
|
||||
return Class(path=os.path.join(c, filename), **kwargs)
|
||||
i += 1
|
||||
|
||||
raise NoBakefileFound(f"No {filename} found!")
|
||||
@@ -347,13 +349,13 @@ class TaskFilter(BaseAction):
|
||||
return
|
||||
|
||||
key = sha256(key.encode("utf-8")).hexdigest()
|
||||
old_hash = str(self.bf.cache[key])
|
||||
old_hash = str(self.bf.skip_cache[key])
|
||||
|
||||
# Get the current filestate hashsum.
|
||||
with open(key_path, "r") as f:
|
||||
current_hash = sha256(f.read().encode("utf-8")).hexdigest()
|
||||
|
||||
self.bf.cache[key] = current_hash
|
||||
self.bf.skip_cache[key] = current_hash
|
||||
|
||||
if old_hash == current_hash:
|
||||
self.do_skip = True
|
||||
|
||||
+8
-5
@@ -11,11 +11,12 @@ class Cache:
|
||||
prefix = PREFIX
|
||||
seperator = SEPERATOR
|
||||
|
||||
def __init__(self, *, bf, debug=False, enabled=True):
|
||||
def __init__(self, *, bf, namespace="hashes", debug=False, enabled=True):
|
||||
|
||||
self.bf = bf
|
||||
self.enabled = enabled
|
||||
self.debug = debug
|
||||
self.namespace = namespace
|
||||
|
||||
try:
|
||||
# Assert git exists, and appears functioning.
|
||||
@@ -46,7 +47,7 @@ class Cache:
|
||||
return f"<Cache enabled={self.enabled}>"
|
||||
|
||||
def _key_for_hashes(self, key):
|
||||
return self.seperator.join((self.prefix, "hashes", key))
|
||||
return self.seperator.join((self.prefix, self.namespace, key))
|
||||
|
||||
def clear(self):
|
||||
for key in self:
|
||||
@@ -65,8 +66,9 @@ class Cache:
|
||||
c = delegator.run(cmd)
|
||||
for result in c.out.split("\n"):
|
||||
if result.startswith(self.prefix):
|
||||
print(result.split("=", -1)[0])
|
||||
yield result.split("=", -1)[0]
|
||||
yield result.split("=", -1)[0][
|
||||
len(self.prefix + "." + self.namespace + ".") :
|
||||
]
|
||||
|
||||
def __getitem__(self, k):
|
||||
key = self._key_for_hashes(k)
|
||||
@@ -92,7 +94,8 @@ class Cache:
|
||||
return c.ok
|
||||
|
||||
def __delitem__(self, k):
|
||||
cmd = f"git config --local --unset {k}"
|
||||
key = self._key_for_hashes(k)
|
||||
cmd = f"git config --local --unset {key}"
|
||||
|
||||
if self.debug:
|
||||
click.echo(f" {click.style('$', fg='green')} {cmd}", err=True)
|
||||
|
||||
+24
-11
@@ -82,7 +82,7 @@ def echo_json(obj):
|
||||
"--bakefile",
|
||||
"-b",
|
||||
default="__BAKEFILE__",
|
||||
envvar="BAKEFILE_PATH",
|
||||
envvar="BAKEFILE",
|
||||
nargs=1,
|
||||
type=click.Path(),
|
||||
help="The Bakefile to use.",
|
||||
@@ -95,7 +95,13 @@ def echo_json(obj):
|
||||
help="Lists available tasks (and their dependencies).",
|
||||
)
|
||||
@click.option(
|
||||
"--clear-cache", default=False, is_flag=True, help="Clears the cache (e.g. @skip)."
|
||||
"--clear-skips", default=False, is_flag=True, help="Clears the skip cache."
|
||||
)
|
||||
@click.option(
|
||||
"--clear-envs",
|
||||
default=False,
|
||||
is_flag=True,
|
||||
help="Clears the allowed environment variable cache.",
|
||||
)
|
||||
@click.option(
|
||||
"--levels",
|
||||
@@ -114,7 +120,6 @@ def echo_json(obj):
|
||||
"--allow",
|
||||
default=False,
|
||||
nargs=1,
|
||||
multiple=True,
|
||||
hidden=False,
|
||||
help="Whitelist an environment variable for use.",
|
||||
)
|
||||
@@ -189,7 +194,8 @@ def entrypoint(
|
||||
allow,
|
||||
_json,
|
||||
no_deps,
|
||||
clear_cache,
|
||||
clear_skips,
|
||||
clear_envs,
|
||||
interactive,
|
||||
yes,
|
||||
help,
|
||||
@@ -204,9 +210,6 @@ def entrypoint(
|
||||
if _json or source:
|
||||
silent = True
|
||||
|
||||
# Allow explicitly–passed environment variables.
|
||||
SAFE_ENVIRONS.extend(allow)
|
||||
|
||||
# Enable list functionality, by default.
|
||||
if task == "__LIST_ALL__":
|
||||
_list = True
|
||||
@@ -215,9 +218,9 @@ def entrypoint(
|
||||
# Establish the Bakefile.
|
||||
try:
|
||||
bf = (
|
||||
Bakefile.find(root=".", filename="Bakefile")
|
||||
Bakefile.find(root=".", filename="Bakefile", debug=debug)
|
||||
if bakefile == "__BAKEFILE__"
|
||||
else Bakefile(path=bakefile)
|
||||
else Bakefile(path=bakefile, debug=debug)
|
||||
)
|
||||
|
||||
except NoBakefileFound:
|
||||
@@ -225,12 +228,22 @@ def entrypoint(
|
||||
do_help(1)
|
||||
sys.exit(0)
|
||||
|
||||
if allow:
|
||||
bf.env_cache[allow] = 1
|
||||
|
||||
# Clear the cache, if asked to do so.
|
||||
if clear_envs:
|
||||
bf.env_cache.clear()
|
||||
|
||||
# Allow explicitly–passed environment variables.
|
||||
SAFE_ENVIRONS.extend([g.upper() for g in bf.env_cache])
|
||||
|
||||
if debug:
|
||||
click.echo(f" + Bakefile: {bf.path}", err=True)
|
||||
|
||||
# Clear the cache, if asked to do so.
|
||||
if clear_cache:
|
||||
bf.cache.clear()
|
||||
if clear_skips:
|
||||
bf.skip_cache.clear()
|
||||
|
||||
# --source (internal API)
|
||||
if source:
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ SAFE_ENVIRONS = [
|
||||
"USER",
|
||||
"TERM",
|
||||
"VIRTUAL_ENV",
|
||||
"BAKEFILE_PATH",
|
||||
"BAKEFILE",
|
||||
"PYTHONUNBUFFERED",
|
||||
"PYTHONDONTWRITEBYTECODE",
|
||||
"BAKE_SILENT",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
|
||||
import click
|
||||
from click.utils import strip_ansi
|
||||
|
||||
|
||||
@click.command(context_settings=dict(help_option_names=["-h", "--help"]))
|
||||
@@ -13,4 +14,4 @@ def entrypoint(s, *, err):
|
||||
|
||||
s = s.rstrip()
|
||||
|
||||
click.echo(s)
|
||||
click.echo(strip_ansi(s))
|
||||
|
||||
@@ -12,18 +12,24 @@ colorama.init(strip=False)
|
||||
@click.command(context_settings=dict(help_option_names=["-h", "--help"]))
|
||||
@click.argument("s", type=click.STRING, default=False, required=False)
|
||||
@click.option(
|
||||
"--read-stderr", is_flag=True, type=click.BOOL, default=True, help="Read stderr."
|
||||
"--read-stderr", is_flag=True, type=click.BOOL, default=False, help="Read stderr."
|
||||
)
|
||||
@click.option(
|
||||
"--no-color", is_flag=True, type=click.BOOL, default=False, help="Read stderr."
|
||||
)
|
||||
@click.option("--char", nargs=1, type=click.STRING, default="+", help="Prefix char.")
|
||||
@click.option(
|
||||
"--color", nargs=1, type=click.STRING, default="yellow", help="Color to use."
|
||||
)
|
||||
def entrypoint(s, *, char, read_stderr, color):
|
||||
def entrypoint(s, *, char, read_stderr, no_color, color):
|
||||
|
||||
pipe = sys.stdin if not read_stderr else sys.stderr
|
||||
if s is False:
|
||||
s = pipe.read()
|
||||
|
||||
if no_color:
|
||||
color = "NOTACOLOR"
|
||||
|
||||
for line in s.strip().split("\n"):
|
||||
try:
|
||||
title = str(click.style(line, fg=color))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
timeout() {
|
||||
time=$1
|
||||
command="/bin/sh -c \"$2\""
|
||||
|
||||
expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 0 } eof { exit 1 }"
|
||||
|
||||
}
|
||||
export timeout
|
||||
@@ -0,0 +1,4 @@
|
||||
argv:
|
||||
set -u
|
||||
echo "${@}"
|
||||
echo "${KEY}"
|
||||
@@ -0,0 +1,15 @@
|
||||
@test "arguments don't work (set -u)" {
|
||||
run bake -b args.Bakefile argv
|
||||
[ "${status}" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "arguments do work [argv]" {
|
||||
run bake --silent -b args.Bakefile argv 1 2 KEY=VALUE 3
|
||||
[[ "${lines[0]}" == *"1 2 3"* ]]
|
||||
}
|
||||
|
||||
|
||||
@test "arguments do work [environ]" {
|
||||
run bake --silent -b args.Bakefile argv 1 2 KEY=VALUE 3
|
||||
[[ "${lines[1]}" == *"VALUE"* ]]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
//two:
|
||||
one/two/three/four:
|
||||
one/two/:
|
||||
|
||||
echo:
|
||||
echo ${1}
|
||||
|
||||
echo/dep: dep
|
||||
bake echo ${1} | red
|
||||
|
||||
dep:
|
||||
echo 'Installing dep…'
|
||||
exit 0
|
||||
|
||||
fail:
|
||||
exit 1
|
||||
|
||||
deps/fail: fail
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
@test "bake --h" {
|
||||
run bake -b basics.Bakefile --help
|
||||
[ "${lines[0]}" = "Usage: [OPTIONS] [TASK] [ARGUMENTS]..." ]
|
||||
}
|
||||
|
||||
@test "bake --help" {
|
||||
run bake -b basics.Bakefile --help
|
||||
[ "${lines[0]}" = "Usage: [OPTIONS] [TASK] [ARGUMENTS]..." ]
|
||||
}
|
||||
|
||||
@test "bake --json" {
|
||||
run bake -b basics.Bakefile --json
|
||||
[ "${#lines[@]}" -eq 23 ]
|
||||
}
|
||||
|
||||
@test "bake --json --levels 0" {
|
||||
run bake -b basics.Bakefile --json --levels 0
|
||||
[ "${#lines[@]}" -eq 3 ]
|
||||
}
|
||||
|
||||
@test "bake --levels 0" {
|
||||
run bake -b basics.Bakefile --levels 0
|
||||
[ "${lines[0]}" = "" ]
|
||||
}
|
||||
|
||||
@test "bake --levels 1" {
|
||||
run bake -b basics.Bakefile --levels 1
|
||||
[ "${#lines[@]}" -eq 4 ]
|
||||
}
|
||||
|
||||
@test "bake --levels 2" {
|
||||
run bake -b basics.Bakefile --levels 3
|
||||
[ "${#lines[@]}" -eq 10 ]
|
||||
}
|
||||
|
||||
@test "bake --levels 3" {
|
||||
run bake -b basics.Bakefile --levels 3
|
||||
[ "${#lines[@]}" -eq 10 ]
|
||||
}
|
||||
|
||||
@test "bake --levels 4" {
|
||||
run bake -b basics.Bakefile --levels 4
|
||||
[ "${#lines[@]}" -eq 10 ]
|
||||
}
|
||||
|
||||
|
||||
@test "bake fails on 'exit 1'" {
|
||||
run bake -b basics.Bakefile fail
|
||||
[ "${status}" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "bake fails on sub–task 'exit 1'" {
|
||||
run bake -b basics.Bakefile deps/fail
|
||||
[ "${status}" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "bake runs tasks" {
|
||||
run bake -b basics.Bakefile echo
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "bake runs sub-tasks" {
|
||||
run bake -b basics.Bakefile echo/dep
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "bake --no-deps" {
|
||||
run bake -b basics.Bakefile deps/fail --no-deps
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
task: skipme
|
||||
exit 0
|
||||
skipme: @skip:key=cache.Bakefile
|
||||
exit 0
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
@test "skips clear" {
|
||||
bake -b cache.Bakefile --clear-skips
|
||||
}
|
||||
|
||||
@test "cache runs" {
|
||||
run bake -b cache.Bakefile task
|
||||
[[ $output != *Skipping* ]]
|
||||
}
|
||||
|
||||
@test "cache skips" {
|
||||
run bake -b cache.Bakefile task
|
||||
[[ $output == *Skipping* ]]
|
||||
}
|
||||
|
||||
@test "skip skips" {
|
||||
run bake -b cache.Bakefile --no-deps task
|
||||
[[ $output != *Skipping* ]]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
secure: @confirm
|
||||
exit 0
|
||||
|
||||
secure/real: @confirm:secure
|
||||
exit 1
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
source ./_common.sh
|
||||
|
||||
@test "confirm works" {
|
||||
timeout 1 "bake -b confirm.Bakefile secure"
|
||||
}
|
||||
|
||||
@test "confirm --yes works" {
|
||||
bake -b confirm.Bakefile secure --yes
|
||||
}
|
||||
|
||||
@test "confirm:secure works" {
|
||||
timeout 1 "bake -b confirm.Bakefile secure/real"
|
||||
}
|
||||
|
||||
@test "confirm:secure --yes don't work" {
|
||||
timeout 1 "bake -b confirm.Bakefile secure/real --yes"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
env:
|
||||
env
|
||||
@@ -0,0 +1,19 @@
|
||||
export HELLO=WORLD
|
||||
|
||||
|
||||
@test "env cache clear" {
|
||||
bake -b env.Bakefile --clear-envs env
|
||||
}
|
||||
|
||||
|
||||
@test "removal of environment untrusted variables" {
|
||||
run bake -b env.Bakefile env
|
||||
[[ "${output}" != *HELLO=WORLD* ]]
|
||||
}
|
||||
|
||||
|
||||
@test "allowance of environment untrusted variables" {
|
||||
run bake --allow HELLO
|
||||
run bake -b env.Bakefile env
|
||||
[[ "${output}" == *"WORLD"* ]]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
python:
|
||||
#!/usr/bin/env python
|
||||
print('not bash')
|
||||
@@ -0,0 +1,4 @@
|
||||
@test "python" {
|
||||
run bake --silent -b python.Bakefile python
|
||||
[[ "${lines[0]}" == "not bash" ]]
|
||||
}
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
declare -a COLORS=('white', 'red', 'green', 'blue', 'cyan', 'purple', 'magenta')
|
||||
|
||||
@test "$(red red) --help" {
|
||||
run red --help
|
||||
[ "${lines[0]}" = "Usage: red [OPTIONS] [S]" ]
|
||||
}
|
||||
|
||||
@test "$(red red) \${s}" {
|
||||
run red test
|
||||
[[ "${lines[0]}" == *"test"* ]]
|
||||
}
|
||||
|
||||
@test "echo \${s} | $(red red)" {
|
||||
output=$(echo test | red)
|
||||
[[ "$output" == *"test"* ]]
|
||||
}
|
||||
|
||||
|
||||
@test "$(red red) --fg \${COLOR}" {
|
||||
for COLOR in "${COLORS[@]}"; do
|
||||
output=$(echo test | red --fg ${COLOR} )
|
||||
[[ "$output" == *"test"* ]]
|
||||
done
|
||||
}
|
||||
|
||||
@test "$(red red) --fg \${COLOR} --bold" {
|
||||
for COLOR in "${COLORS[@]}"; do
|
||||
output=$(echo test | red --fg ${COLOR} --bold)
|
||||
[[ "$output" == *"test"* ]]
|
||||
done
|
||||
}
|
||||
|
||||
@test "$(red red) --bg \${COLOR}" {
|
||||
for COLOR in "${COLORS[@]}"; do
|
||||
output=$(echo test | red --bg ${COLOR} )
|
||||
[[ "$output" == *"test"* ]]
|
||||
done
|
||||
}
|
||||
|
||||
@test "$(red red) --bg \${COLOR} --bold" {
|
||||
for COLOR in "${COLORS[@]}"; do
|
||||
output=$(echo test | red --bg ${COLOR} --bold)
|
||||
[[ "$output" == *"test"* ]]
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@test "$(red notred --fg blue) \${s}" {
|
||||
run notred test
|
||||
[[ "${lines[0]}" == "test" ]]
|
||||
}
|
||||
|
||||
@test "$(red red) \${s} | $(red notred --fg blue)" {
|
||||
output=$(red test | notred)
|
||||
[[ "$output" == *"test"* ]]
|
||||
}
|
||||
|
||||
@test "which $(red red)" {
|
||||
run which red
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "which $(red notred --fg blue)" {
|
||||
run which notred
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "which $(red bake_indent --fg cyan)" {
|
||||
run which bake_indent
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "which $(red bake_step --fg cyan)" {
|
||||
run which bake_step
|
||||
[ "${status}" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "$(red bake_step --fg cyan) \${s}" {
|
||||
run bake_step --no-color 'Step 1'
|
||||
[[ "${lines[0]}" == " + Step 1: " ]]
|
||||
}
|
||||
|
||||
|
||||
@test "$(red bake_step --fg cyan) --help" {
|
||||
run bake_step --help
|
||||
[ "${lines[0]}" = "Usage: bake_step [OPTIONS] [S]" ]
|
||||
}
|
||||
|
||||
@test "$(red bake_indent --fg cyan) --help" {
|
||||
run bake_indent --help
|
||||
[ "${lines[0]}" = "Usage: bake_indent [OPTIONS]" ]
|
||||
}
|
||||
Reference in New Issue
Block a user