Git status checks and more hacking

This commit is contained in:
Luke Murphy 2020-04-11 22:47:16 +02:00
parent 0806b4e134
commit c69bdec4c9
No known key found for this signature in database
GPG Key ID: 5E2EF5A63E3718CC
9 changed files with 123 additions and 29 deletions

View File

@ -3,17 +3,19 @@
from os import environ from os import environ
import click import click
from PyInquirer import prompt
from autonomic.config import ACTIONS_DIR from autonomic.config import ACTIONS_DIR, INFRA_DIR
from autonomic.infra import get_passwd, run_play from autonomic.infra import get_passwd, run_play
from autonomic.utils import qlist from autonomic.utils import check_git, qlist
from PyInquirer import prompt
@click.command() @click.command()
@click.pass_context @click.pass_context
def actions(ctx): def actions(ctx):
"""Run an Ansible action.""" """Run an Ansible action."""
env = environ.copy()
choices = ["addusers", "newhetzner", "rmhetzner", "newdokku"] choices = ["addusers", "newhetzner", "rmhetzner", "newdokku"]
question = qlist("action", "Which Ansible action?", choices,) question = qlist("action", "Which Ansible action?", choices,)
action = prompt(question)["action"] action = prompt(question)["action"]
@ -25,13 +27,9 @@ def actions(ctx):
path = "logins/hetzner/{}/api_key".format(key) path = "logins/hetzner/{}/api_key".format(key)
secret = get_passwd(path) secret = get_passwd(path)
env = environ.copy()
env["HCLOUD_TOKEN"] = secret env["HCLOUD_TOKEN"] = secret
play = "{}/{}.yml".format(ACTIONS_DIR, action) play = "{}/{}.yml".format(ACTIONS_DIR, action)
run_play(play, env=env) run_play(play, env=env)
# TODO(decentral1se): check_git(INFRA_DIR)
# git commit and push on infrastructure if we:
# 1. ran an action that adds something new to the pass store
# 2. added another machine to the inventory

View File

@ -20,8 +20,7 @@ from autonomic.utils import is_proc, qlist, run
@click.pass_context @click.pass_context
def init(ctx): def init(ctx):
"""Initialise the toolbelt.""" """Initialise the toolbelt."""
create_configuration_directory() create_configuration()
create_settings_file()
clone_infrastructure_repo() clone_infrastructure_repo()
store_username() store_username()
install_dependencies() install_dependencies()
@ -31,11 +30,15 @@ def init(ctx):
log.success(emojize(msg, use_aliases=True)) log.success(emojize(msg, use_aliases=True))
def create_configuration_directory(): def create_configuration():
"""Create toolbelt config directory.""" """Create toolbelt config directory."""
if not exists(CONFIG_DIR): if not exists(CONFIG_DIR):
mkdir(CONFIG_DIR) mkdir(CONFIG_DIR)
if not exists(CONFIG_YAML):
with open(CONFIG_YAML, "w") as handle:
handle.write("---")
def clone_infrastructure_repo(): def clone_infrastructure_repo():
"""Clone or update the infrastructure repository.""" """Clone or update the infrastructure repository."""
@ -58,13 +61,6 @@ def store_username():
log.success(emojize(msg, use_aliases=True)) log.success(emojize(msg, use_aliases=True))
def create_settings_file():
"""Create settings file."""
if not exists(CONFIG_YAML):
with open(CONFIG_YAML, "w") as handle:
handle.write("---")
def install_dependencies(): def install_dependencies():
"""Install infrastructure dependencies.""" """Install infrastructure dependencies."""
cmd = ["/usr/bin/python3", "-m", "venv", ".venv"] cmd = ["/usr/bin/python3", "-m", "venv", ".venv"]
@ -86,7 +82,7 @@ def install_dependencies():
def ssh_sanity_check(): def ssh_sanity_check():
"""Try to recommend some SSH tips.""" """Try to recommend some SSH tips."""
if not is_proc("ssh-agent"): if not is_proc("ssh-agent"):
msg = "ssh-agent is not running :sob:" msg = "warning: ssh-agent is not running :sob:"
log.warning(emojize(msg, use_aliases=True)) log.warning(emojize(msg, use_aliases=True))
else: else:
msg = "ssh-agent is running :rocket:" msg = "ssh-agent is running :rocket:"

View File

@ -9,21 +9,36 @@ from autonomic.config import CONFIG_YAML
from autonomic.utils import yaml_dump, yaml_load from autonomic.utils import yaml_dump, yaml_load
def add(data): def add(yaml):
"""Add values to the settings file.""" """Add YAML to the settings file."""
from autonomic.command.init import create_configuration
create_configuration()
settings = yaml_load(CONFIG_YAML) settings = yaml_load(CONFIG_YAML)
if settings is None: if settings is None:
settings = {} settings = {}
for key in data: for key in yaml:
settings[key] = data[key] settings[key] = yaml[key]
yaml_dump(CONFIG_YAML, settings)
def remove(key):
"""Remove key from the settings file."""
settings = yaml_load(CONFIG_YAML)
if settings is None:
return
settings.pop(key, None)
yaml_dump(CONFIG_YAML, settings) yaml_dump(CONFIG_YAML, settings)
def get(key): def get(key):
"""Retrieve setting values.""" """Retrieve settings key."""
settings = yaml_load(CONFIG_YAML) settings = yaml_load(CONFIG_YAML)
try: try:

View File

@ -8,10 +8,11 @@ things here.
""" """
from os import chdir from os import chdir
from subprocess import CalledProcessError, check_output from subprocess import check_output
from psutil import process_iter from psutil import process_iter
from autonomic.config import INFRA_DIR
from autonomic.logger import log from autonomic.logger import log
from autonomic.yaml import yaml from autonomic.yaml import yaml
@ -29,7 +30,7 @@ def run(cmd, cwd=None, **kwargs):
log.info("Changed directory to {}".format(cwd)) log.info("Changed directory to {}".format(cwd))
log.info("Running {}".format(" ".join(cmd))) log.info("Running {}".format(" ".join(cmd)))
return check_output(cmd, **kwargs) return check_output(cmd, **kwargs)
except CalledProcessError as exception: except Exception as exception:
msg = "{} failed! Saw {}".format(" ".join(cmd), str(exception)) msg = "{} failed! Saw {}".format(" ".join(cmd), str(exception))
exit(msg) exit(msg)
@ -84,3 +85,13 @@ def is_proc(name):
except Exception: except Exception:
pass pass
return False return False
def git_status(fpath):
"""Check if Git reports changes to be committed."""
cmd = ["git", "status", "--porcelain"]
output = run(cmd, cwd=fpath)
if output is not None:
msg = "warning: git reports uncommitted changes in {}".format(fpath)
log.warning(msg)
log.warning(output)

View File

@ -6,7 +6,7 @@ max-line-length = 80
[isort] [isort]
known_first_party = autonomic known_first_party = autonomic
known_third_party = pytest known_third_party = pytest, psutil
line_length = 80 line_length = 80
multi_line_output = 3 multi_line_output = 3
skip = .venv, .tox skip = .venv, .tox

11
test/test_settings.py Normal file
View File

@ -0,0 +1,11 @@
from autonomic.settings import add, get, remove
def test_add_get_remove():
add({"foo": "bar"})
assert get("doesnt-exist") is None
assert get("foo") == "bar"
remove("foo")
assert get("foo") is None

58
test/test_utils.py Normal file
View File

@ -0,0 +1,58 @@
from subprocess import STDOUT
from autonomic.utils import is_proc, qlist, run, yaml_dump, yaml_load
def test_run_kwargs():
assert run(["whoami"], stderr=STDOUT) is not None
def test_run_cwd(tmp_path):
directory = tmp_path / "test"
directory.mkdir()
testfile = directory / "testfile.txt"
testfile.write_text("hello, world")
output = run(["ls"], cwd=directory.absolute())
assert "testfile.txt" in output.decode()
def test_make_qlist():
output = qlist("foo", "bar", ["bang"])
expected = {
"type": "list",
"name": "foo",
"message": "bar",
"choices": ["bang"],
}
for key, val in expected.items():
assert expected[key] == output[0][key]
def test_yaml_load(tmp_path):
directory = tmp_path / "test"
directory.mkdir()
testfile = directory / "testfile.yml"
testfile.write_text("---\nusername: foobar")
loaded = yaml_load(testfile.absolute())
assert loaded["username"] == "foobar"
def test_yaml_dump(tmp_path):
directory = tmp_path / "test"
directory.mkdir()
testfile = directory / "testfile.yml"
yaml_dump(testfile.absolute(), {"username": "foobar"})
loaded = yaml_load(testfile.absolute())
assert loaded["username"] == "foobar"
def test_is_proc():
assert is_proc("pytest") is True

View File

@ -2,9 +2,9 @@
def test_version_fails_gracefully(mocker): def test_version_fails_gracefully(mocker):
target = 'pkg_resources.get_distribution' target = "pkg_resources.get_distribution"
mocker.patch(target, side_effect=Exception()) mocker.patch(target, side_effect=Exception())
from autonomic.__init__ import __version__ from autonomic.__init__ import __version__
assert __version__ == 'unknown' assert __version__ == "unknown"

5
test/test_yaml.py Normal file
View File

@ -0,0 +1,5 @@
from autonomic.yaml import yaml
def test_yaml_config():
assert yaml.explicit_start is True