clean: code, add features, better cli

This commit is contained in:
mrjk 2023-10-09 03:46:53 -04:00
parent b8df31f036
commit eda4c8ffd9
13 changed files with 318 additions and 275 deletions

View File

@ -35,14 +35,6 @@ class App:
"Init application with ident"
self.ident_raw = ident
# # Split ident from scope
# scope = ""
# if "/" in ident:
# parts = ident.split("/", 2)
# ident = parts[0]
# scope = parts[1]
view = scoped_ident(ident)
# Save important vars
@ -69,8 +61,11 @@ class App:
else:
path = os.path.join(BaseDirectory.xdg_config_home, self.name)
self.config_dir = path
if os.path.isdir(path):
files = glob.glob("*.yml", root_dir=path)
# files = glob.glob("*.yml", root_dir=path) # Python > 3.10
files = glob.glob(f"{path}/*.yml")
for file_ in files:
file_ = os.path.join(path, file_)
@ -105,7 +100,6 @@ class App:
providers_conf = {}
providers_conf.update(self.plugin_providers)
providers_conf.update(db.get("providers", {}))
# pprint (providers_conf)
self.providers = Providers("ConfigProviders", providers_conf)
# Load idents
@ -159,20 +153,6 @@ class App:
return ret
# def get_resource(self, name):
# "Query and resolve a resource"
# return self.catalog.get_resource(name)
# # def get_service(self, name, resolve=False):
# # "Query and resolve a service"
# # return self.catalog.get_service(name, resolve=resolve)
# def list_resources(self):
# "List all resources"
# return self.catalog.resources
def list_services(self):
"List all services"
@ -190,17 +170,27 @@ class App:
return self.catalog.shell_disable(**kwargs)
def shell_install(self, shell="bash"):
"Install iam in shell"
def shell_install(self, shell="bash", completion=True):
"Show your install script for shell"
assets_dir = os.path.join(get_root_pkg_dir("iam"), "assets")
if shell == "bash":
# Shell selector
if shell.endswith("bash"):
config_file = ".bashrc"
template_file = os.path.join(assets_dir, "init_bash.sh")
init_file = os.path.join(assets_dir, "init_bash.sh")
completion_file = os.path.join(assets_dir, "iam_completion.sh")
else:
raise Exception(f"Unsupported shell: {shell}")
return f"source {template_file}"
# TOFIX: Implement for other shells ?
out = []
out.append(f"### IAM ###")
out.append(f"if command -v iam &>/dev/null; then")
out.append(f" source {init_file}")
if completion:
out.append(f" source {completion_file}")
out.append(f"fi")
out.append(f"### IAM ###")
return '\n'.join(out)

View File

@ -0,0 +1,29 @@
_iam_completion() {
local IFS=$'\n'
local response
response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _IAM_COMPLETE=bash_complete $1)
for completion in $response; do
IFS=',' read type value <<< "$completion"
if [[ $type == 'dir' ]]; then
COMPREPLY=()
compopt -o dirnames
elif [[ $type == 'file' ]]; then
COMPREPLY=()
compopt -o default
elif [[ $type == 'plain' ]]; then
COMPREPLY+=($value)
fi
done
return 0
}
_iam_completion_setup() {
complete -o nosort -F _iam_completion iam
}
_iam_completion_setup;

View File

@ -16,7 +16,7 @@
IAM_BIN=$(command -v iam)
IAM_IDENT=
_usage ()
i_usage ()
{
echo "iam shell wrapper"
@ -156,7 +156,7 @@ i ()
#echo $IAM_BIN shell status $current_ident
;;
help)
_usage
i_usage
;;
esac

View File

@ -1,12 +1,18 @@
import os
import logging
from collections import namedtuple
from pprint import pprint
from types import SimpleNamespace
import sh
# TO BE REMOVED !!!!
import click
from . import exceptions as error
from .framework import DictCtrl, DictItem, KeyValue, KeyValueExtra
from .idents import Ident
from .lib.utils import format_render, jinja_render, uniq
from .lib.utils import format_render, jinja_render, uniq, jinja_template_vars, empty
logger = logging.getLogger(__name__)
cli_logger = logging.getLogger("iam.cli")
@ -52,31 +58,38 @@ class ServiceCommand(DictItem):
"cmd": "", # Direct commands to launch
"shell": "", # Will be run in a shell (or specific shell below)
"shell_sh": "",
"shell_bash": "",
"shell_zsh": "",
"shell_fish": "",
"shell_bash": "",
"source": False, # True for enable commands !
# "shell_sh": "",
# "shell_bash": "",
# "shell_zsh": "",
# "shell_fish": "",
# "shell_bash": "",
# "source_output": False, # True for shell commands by default !
}
# Overrides
# ---------------
def payload_transform(self, name, kwargs=None):
def init(self):
"Transform short form into long form"
self.service = self.parent
payload = self._payload
if not isinstance(payload, dict):
payload = {"cmd": payload}
self._payload = payload
# def payload_transform(self, name, kwargs=None):
# "Transform short form into long form"
# self.service = self.parent
# payload = self._payload
# if not isinstance(payload, dict):
# payload = {"cmd": payload}
# self._payload = payload
def cmd_name(self):
return self.name.replace("_", " ")
class Service(DictItem):
"Hold provider services"
@ -772,9 +785,16 @@ class Context(DictItem):
assert isinstance(self.ident, Ident), f"Gotr: {self.ident}"
def init(self):
self.catalog = self.parent
root_dir = self.catalog.app.config_dir
self._vars = {
"ident": self.ident.name,
"user": self.ident.name,
"config_dir": root_dir,
"scripts_dir": os.path.join(root_dir, "scripts"),
"bin_dir": os.path.join(root_dir, "bin"),
}
def get_vars(self):
@ -790,16 +810,16 @@ class Context(DictItem):
class Catalog:
"Manage catalog resources"
def __init__(self, mgr, ident):
def __init__(self, app, ident):
# Prepare catalog
self.mgr = mgr
self.app = app
self.ident = ident
# Prepare context
ctx_conf = {
"ident": ident,
}
self.context = Context("current_context", ctx_conf)
self.context = Context("current_context", ctx_conf, parent=self)
self._prepare_catalog()
@ -807,7 +827,7 @@ class Catalog:
# ================
def _merge_inst_configs(self, merge=True):
plugins_confs = self.mgr.providers.get_resource_configs()
plugins_confs = self.app.providers.get_resource_configs()
user_confs = self.ident.get_resource_configs()
final_config = {}
@ -840,7 +860,7 @@ class Catalog:
"Prepare catalog resources configs"
# Get resources from providers and user
providers = self.mgr.providers
providers = self.app.providers
ident = self.ident
# Build kind catalog
@ -949,8 +969,8 @@ class Catalog:
continue
# Build loop with at least ONE item
cmd = command.cmd
if not cmd:
cmd_shell = command.shell
if not cmd_shell:
continue
# Create context var dict
@ -972,7 +992,7 @@ class Catalog:
logger.debug(f"{log_action_name} service: {res.name}")
# pprint (ctx_vars)
cmd = jinja_render(cmd, ctx_vars)
cmd = jinja_render(cmd_shell, ctx_vars)
output_code.append(f"# Loading: {action_name} {res.name} ({service.name})")
output_code.append(f"# =====================")
output_code.append(cmd)
@ -989,15 +1009,13 @@ class Catalog:
cmd, args = self.services.get_svc_command(cmd)
# pprint (cmd.cmd)
pprint (args)
# pprint (args)
service = cmd.service
pprint (service)
pprint (service.__dict__)
# pprint (service)
# pprint (service.__dict__)
# pprint (dir(service))
res = service.get_linked_resource()
# pprint (res)
@ -1020,25 +1038,82 @@ class Catalog:
# }
# )
pprint (ctx_vars)
# pprint (ctx_vars)
new_env = dict(os.environ)
new_env.update(ctx_vars)
# pprint(new_env)
if cmd.cmd and cmd.shell:
logger.warning(f"Duplicate cmd and shell for {service.name}")
out = None
if cmd.cmd:
if cmd.shell:
mode = "shell"
payload = cmd.shell
# Scan for missing vars !!!
tmp = jinja_template_vars(payload)
prompt_vars = []
for var_name in tmp:
if var_name not in ctx_vars:
prompt_vars.append(var_name)
else:
var_value = ctx_vars[var_name]
if empty(var_value):
prompt_vars.append(var_name)
# Ask for missing vars
if len(prompt_vars) > 0:
# print ("MISSING VARS")
# pprint (prompt_vars)
answered_items = {}
for missed in prompt_vars:
default = ctx_vars.get(missed, None)
result = click.prompt(f'Select value for {missed}', default=default)
answered_items[missed] = result
ctx_vars.update(answered_items)
real_cmd = jinja_render(payload, ctx_vars)
# print ("RUN SHELL")
builtins = sh.bash.bake("-c")
out = builtins(real_cmd, _fg=True, _env=new_env)
# print (out)
elif cmd.cmd:
mode = "cmd"
payload = cmd.cmd
real_cmd = jinja_render(payload, ctx_vars)
cmd_parts = real_cmd.split(" ", 1)
sh_cmd = cmd_parts[0]
sh_args = cmd_parts[1] if len(cmd_parts) > 0 else []
elif cmd.shell:
mode = "shell"
payload = cmd.shell
real_cmd = jinja_render(payload, ctx_vars)
# print ("Prepare", sh_cmd, " ||| ", sh_args)
# proc = sh.bake(sh_cmd)
# sh(sh_cmd, *sh_args, _fg=True)
cmd = sh.Command(sh_cmd)
if sh_args:
out = cmd(sh_args, _fg=True, _env=new_env)
else:
out = cmd( _fg=True, _env=new_env)
# print (out)
else:
raise Exception("MIssing cmd or shell in config !")
return out
print ("RUN CMD", mode, "\n\n\n====\n", real_cmd)
# print ("RUN CMD", mode, "\n\n\n====\n", real_cmd)

View File

@ -100,6 +100,7 @@ DEBUG = os.environ.get("IAM_DEBUG", "False")
DEFAULT_IDENT = os.environ.get("IAM_IDENT", os.environ.get("SHELL_IDENT", ""))
DEFAULT_FORMAT = os.environ.get("IAM_FORMAT", "table")
DEFAULT_HELP_OPTIONS=["-h", "--help"]
DEFAULT_SHELL = os.environ.get("SHELL", "bash")
# list_view.formats_enum
@ -849,7 +850,7 @@ class TmpGroup(click.Group):
@click.pass_context
def cli_app_run(ctx, cmd_params):
print("Will run cmd:", cmd_params)
# print("Will run cmd:", cmd_params)
# Check first help parameter only
show_help = False
@ -891,7 +892,8 @@ def cli_app_run(ctx, cmd_params):
# Run the output
ret = app.catalog.run_svc_cmd(cmd=cmd_params)
pprint (ret, expand_all=True)
print (ret)
# pprint (ret, expand_all=True)
@ -910,11 +912,14 @@ def cli_app_run(ctx, cmd_params):
@cli__shell.command("install")
@click.argument("shell",
required=False,
default=DEFAULT_SHELL)
@click.pass_context
def shell_install(ctx, verbose=None):
def shell_install(ctx, shell=None, verbose=None):
"Install iam in your shell"
ret = ctx.obj.app.shell_install()
ret = ctx.obj.app.shell_install(shell=shell)
# print("-- %< --" * 8)
print(ret)

View File

@ -1,5 +1,9 @@
import logging
import click
logger = logging.getLogger(__name__)
# Click Plugins
# ===============================
@ -9,8 +13,53 @@ class NestedHelpGroup(click.Group):
"""This class provides a way to show all commands of all children
instead of just the parent. Optionnaly accept to hides groups or not.
This class is aimed to serve simple resource based CLIs, à la [cliff](),
but with the click library.
This class provides:
* Recursive command listing
* Command aliasing as described in (documentation)[https://click.palletsprojects.com/en/8.1.x/advanced/#command-aliases]
* Rich support (TODO, more complete wrapper of click-rich)
* Basic views (TODO)
# Recursive command list
# =============
Recursive listing on help commands, this is helpful to
have an quick overview of all commands on small clis. It also provides
an option to hide groups if you don't use them, which may reduce the size of
the help message in case of many groups.
# Command shortcuts
# =============
Let's image a command line that provides:
```
myapp user show <USER>
myapp user state <USER>
myapp user disable <USER>
```
You could use as shortcuts:
```
mysapp u sh USER
mysapp u st USER
mysapp u sd USER
```
But `mysapp u s USER` would fail as it would not know if it have to redirect to
`show` or `state` command, as both starts with `s`
"""
# For partial name resolution
def resolve_command(self, ctx, args):
"Return the full command name if changed"
_, cmd, args = super().resolve_command(ctx, args)
if _ != cmd.name:
logger.debug(f"Rewrite command '{_}' to '{cmd.name}'")
return cmd.name, cmd, args
def get_command(self, ctx, cmd_name: str):
"""Given a context and a command name, this returns a :class:`Command`
object if it exists or returns ``None``.
@ -18,19 +67,37 @@ class NestedHelpGroup(click.Group):
# Resolve name part by part
parts = cmd_name.split(" ")
len_parts = len(parts) -1
curr = self
for idx, part in enumerate(parts):
curr = curr.commands.get(part)
match = curr.commands.get(part)
# Look for shortcut if last part
if match is None:
# Look for direct children only
matches = [x for x in self._resolve_children(self, ctx=ctx, ignore_groups=False, deep=0)
if x.startswith(cmd_name)]
# Look for possible matches
if not matches:
pass
elif len(matches) == 1:
match = click.Group.get_command(self, ctx, matches[0])
else:
ctx.fail(f"Too many matches for {cmd_name}: {', '.join(sorted(matches))}")
# Iterate over next child!
curr = match
return curr
def list_commands(self, ctx) -> list[str]:
"List all children commands"
return self._resolve_children(self, ctx=ctx, ignore_groups=True)
return sorted(self._resolve_children(self, ctx=ctx, ignore_groups=True))
@classmethod
def _resolve_children(cls, obj, ctx=None, ignore_groups=False, _parent=None):
def _resolve_children(cls, obj, ctx=None, ignore_groups=False, _parent=None, deep=-1):
"Resolve recursively all children"
# Source: Adapted from https://stackoverflow.com/a/56159096
@ -51,12 +118,15 @@ class NestedHelpGroup(click.Group):
ret.append(record)
# Recursive loop
if deep != 0:
deep = deep -1
ret.extend(
cls._resolve_children(
child, ctx=ctx, ignore_groups=ignore_groups, _parent=full_name
child, ctx=ctx, ignore_groups=ignore_groups, _parent=full_name, deep=deep
)
)
return ret
return []

View File

@ -83,6 +83,20 @@ def prune(items):
raise Exception(f"Function prune requires a list or a dict, got: {items}")
return ret
# from jinja2 import Environment, FileSystemLoader, meta
# env = Environment(loader=FileSystemLoader('templates'))
# parsed_content = env.parse(payload)
from jinja2 import Environment, PackageLoader, meta
def jinja_template_vars(payload):
env = Environment() #loader=PackageLoader('templates'))
parsed_content = env.parse(payload)
return meta.find_undeclared_variables(parsed_content)
def jinja_render(payload, vars):
"Parse a string with jinja"

View File

@ -43,19 +43,19 @@ plugin_base = {
"commands": {
"shell_enable": {
"desc": "Enable shell ident",
"cmd": "export SHELL_IDENT={{ident}}",
"shell": "export SHELL_IDENT={{ident}}",
},
"shell_disable": {
"desc": "Disable shell ident",
"cmd": "unset SHELL_IDENT",
"shell": "unset SHELL_IDENT",
},
"id new": {
"desc": "Create shell identy",
"cmd": "add_ident {{ param }}",
"shell": "add_ident {{ param }}",
},
"id delete": {
"desc": "Delete shell identy",
"cmd": "rm_ident {{ param }}",
"shell": "rm_ident {{ param }}",
},
},
},

View File

@ -17,13 +17,13 @@ providers:
shell_enable:
desc: Enable git identity
cmd: |
shell: |
export GH_TOKEN='{{gh_token}}'
export GH_REPO='{{ident}}'
shell_disable:
desc: Disable git identity
cmd: |
shell: |
unset GH_TOKEN GH_REPO
@ -69,13 +69,13 @@ providers:
shell_enable:
desc: Enable git identity
cmd: |
shell: |
export GITEA_SERVER_URL='{{gitea_server_url}}'
export GITEA_LOGIN='{{email}}'
shell_disable:
desc: Disable git identity
cmd: |
shell: |
unset GITEA_SERVER_URL GITEA_LOGIN
@ -120,7 +120,7 @@ providers:
shell_enable:
desc: Enable minio alias
cmd: |
shell: |
export MINIO_ACCESS_KEY={{minio_access}}
export MINIO_SECRET_KEY={{minio_secret}}
# cmd_FUTURE: |
@ -130,18 +130,18 @@ providers:
shell_disable:
desc: Disable minio alias
cmd: |
shell: |
unset MINIO_ACCESS_KEY MINIO_SECRET_KEY
minio new alias:
desc: Create alias
cmd: |
shell: |
mc alias set {{ident}} {{api_url}} {{minio_user}} {{minio_password}}
minio delete alias:
desc: Remove alias
cmd: |
shell: |
mc alias rm {{ident}}

View File

@ -5,174 +5,8 @@ from iam.lib.utils import get_pkg_dir, open_yaml, to_yaml
yml_dir = get_pkg_dir(__name__)
plugin_conf = open_yaml(os.path.join(yml_dir, "local.yml"))[0]
all = plugin_conf.get("providers", {})
# plugin_ssh = {
# "services": {
# "local.ssh_key": {
# "desc": "Local ssh key",
# # "input": {
# # "ssh_agent_socket_dir": "/run/user/ssh-agent",
# # "ssh_agent_tmout": "7d",
# # },
# "commands": {
# "shell_enable": {
# "cmd": """
# export SSH_AUTH_SOCK={{ssh_agent_socket_dir}}/{{user}} && \
# ssh-agent -a $SSH_AUTH_SOCK -t {{ssh_agent_tmout}}
# """,
# },
# "shell_disable": {
# "cmd": "ssh-agent -k && unset SSH_AUTH_SOCK",
# },
# },
# },
# },
# "resources_def": {
# "service.local.ssh_key": {
# "desc": "A local ssh key",
# },
# "auth.ssh_certificate": {
# "desc": "SSH Certificates",
# "input": {"ssh_cert_file": None},
# "needs": ["auth.ssh_key"],
# },
# "auth.ssh_key": {
# "desc": "ssh_key",
# "input": {
# "ssh_key_file": None,
# "ssh_key_secret": None
# },
# "needs": [
# {"kind": "auth.password", "remap": {"ssh_key_secret": "passord"}}
# ],
# },
# "account.ssh": {"desc": "An unix account", "input": {"host": None}},
# },
# "resources": {
# "service.local.ssh_agent": {
# "enabled": True,
# # "contains": [
# # "auth.ssh_key:{ident}/ed25519",
# # "auth.ssh_key:{ident}/rsa4096",
# # "auth.ssh_key:{ident}/rsa2048",
# # "auth.ssh_key:{ident}/rsa1024",
# # "auth.ssh_key:{ident}",
# # ],
# },
# "service.local.ssh_agent_keys": {
# "enabled": True,
# "loop_limit": 3,
# "loop": [
# "auth.ssh_key:{ident}/ed25519",
# "auth.ssh_key:{ident}/rsa4096",
# "auth.ssh_key:{ident}/rsa2048",
# "auth.ssh_key:{ident}/rsa1024",
# "auth.ssh_key:{ident}",
# ],
# },
# },
# }
# plugin_ssh_agent = {
# "services": {
# "local.ssh_agent": {
# "desc": "Local ssh-agent",
# "input": {
# "ssh_agent_socket_dir": "/run/user/ssh-agent",
# "ssh_agent_tmout": "7d",
# },
# "commands": {
# "shell_enable": {
# "cmd": """
# export SSH_AUTH_SOCK={{ssh_agent_socket_dir}}/{{user}} && \
# ssh-agent -a $SSH_AUTH_SOCK -t {{ssh_agent_tmout}}
# """,
# },
# "shell_disable": {
# "cmd": "ssh-agent -k && unset SSH_AUTH_SOCK",
# },
# },
# },
# "local.ssh_agent_keys": {
# "desc": "Local ssh-agent keys",
# "required_services": [
# "local.ssh_agent"
# ],
# "commands": {
# "shell_enable": {
# "cmd": """
# ssh-add {% for item in loop %} {{item.ssh_key_file}} {% endfor %}
# """,
# },
# "shell_disable": {
# "cmd": "ssh-agent -d {ssh_key_file}",
# },
# },
# },
# },
# "resources_def": {
# "service.local.ssh_agent": {
# "desc": "A local ssh_agent service",
# },
# "service.local.ssh_agent_keys": {
# "desc": "A local ssh_agent_keys service",
# },
# },
# "resources": {
# "service.local.ssh_agent": {
# "enabled": True,
# # "contains": [
# # "auth.ssh_key:{ident}/ed25519",
# # "auth.ssh_key:{ident}/rsa4096",
# # "auth.ssh_key:{ident}/rsa2048",
# # "auth.ssh_key:{ident}/rsa1024",
# # "auth.ssh_key:{ident}",
# # ],
# },
# "service.local.ssh_agent_keys": {
# "enabled": True,
# "loop_limit": 3,
# "loop": [
# "auth.ssh_key:{ident}/ed25519",
# "auth.ssh_key:{ident}/rsa4096",
# "auth.ssh_key:{ident}/rsa2048",
# "auth.ssh_key:{ident}/rsa1024",
# "auth.ssh_key:{ident}",
# ],
# },
# },
# }
# all = {
# "ssh": plugin_ssh,
# "ssh_agent": plugin_ssh_agent,
# }
# print (to_yaml(all))

View File

@ -17,18 +17,32 @@ providers:
ssh new:
desc: Create new SSH key
# shell: |
# echo "This is my shelll !!! $SHELL"
# env | grep jez
# cmd: |
# env
# # echo Create ssh key: {{ssh_key_alg}} for ident '{{ident}}' with pass: {{ssh_key_secret}}
shell: |
# env | sort
# echo
SSH_KEY_ALG={{ssh_key_alg}}
SSH_KEY_VERSION="$(date +'%Y%m%d')"
SSH_KEY_HOST="$(hostname -f)"
SSH_KEY_FILE=$HOME/.ssh/{ident}/{user}_${SSH_KEY_ALG}_${SSH_KEY_VERSION}
SSH_KEY_COMMENT={user}@${SSH_KEY_HOST}:${SSH_KEY_ALG}_${SSH_KEY_VERSION}
SSH_KEY_FILE=$HOME/.ssh/{{ident}}/{{user}}_${SSH_KEY_ALG}_${SSH_KEY_VERSION}
SSH_KEY_COMMENT={{user}}@${SSH_KEY_HOST}:${SSH_KEY_ALG}_${SSH_KEY_VERSION}
ssh-keygen -f "{SSH_KEY_FILE}" \
echo mkdir -p $HOME/.ssh/{{ident}}/
echo ssh-keygen -f "${SSH_KEY_FILE}" \
-t ed25519 -a 100 \
-N "{{ssh_key_secret}}" \
{% if ssh_key_secret %}-N "{{ssh_key_secret}}"{%endif%} \
-C "$SSH_KEY_COMMENT"
@ -36,7 +50,7 @@ providers:
ssh delete:
desc: Delete existing SSH key
cmd: |
find $HOME/.ssh/{ident}/ -name "{user}_*"
find $HOME/.ssh/{{ident}}/ -name "{{user}}_*"
@ -124,7 +138,7 @@ providers:
shell_start:
desc: Start ssh-agent
cmd: |
shell: |
socket=$HOME/.local/state/ssh-agent/{{user}}
start=true
@ -154,7 +168,7 @@ providers:
shell_enable:
desc: Enable ssh-agent
cmd: |
shell: |
socket=$HOME/.local/state/ssh-agent/{{user}}
if [[ -e "$socket.env" ]]; then
@ -168,13 +182,13 @@ providers:
shell_disable:
desc: Disable ssh-agent
cmd: |
shell: |
unset SSH_AUTH_SOCK SSH_AGENT_PID
shell_stop:
desc: Kill ssh-agent
cmd: |
shell: |
socket=$HOME/.local/state/ssh-agent/{{user}}
if [[ -e "$socket.env" ]]; then
@ -205,11 +219,11 @@ providers:
commands:
ssh add:
desc: Unload keys into ssh-agent
cmd: ssh-agent -d {ssh_key_file}
shell: ssh-agent -d {ssh_key_file}
ssh rm:
desc: Load keys into ssh-agent
cmd: |
shell: |
ssh-add {% for item in loop %} {{item.ssh_key_file}} {% endfor %}
@ -261,7 +275,7 @@ providers:
shell_enable:
desc: Enable git identity
cmd: |
shell: |
export GIT_AUTHOR_NAME='{{ident}}'
export GIT_AUTHOR_EMAIL='{{email}}'
export GIT_COMMITTER_NAME='{{ident}}'
@ -270,7 +284,7 @@ providers:
shell_disable:
desc: Disable git identity
cmd: |
shell: |
unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
@ -284,13 +298,13 @@ providers:
shell_enable:
desc: Enable git home management
cmd: |
shell: |
export GIT_DIR="{{git_dir}}"
export GIT_WORK_TREE="{{git_work_tree}}/{{ ident }}"
shell_disable:
desc: Disable git home management
cmd: |
shell: |
unset GIT_DIR GIT_WORK_TREE
required_services:
@ -331,13 +345,13 @@ providers:
shell_enable:
desc: Enable PS1
cmd: |
shell: |
export OLD_PS1=$PS1
export PS1="\033[0;34m\]({{ident}})\033[00m\] ${PS1}"
shell_disable:
desc: Disable PS1
cmd: |
shell: |
export PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
# export PS1="$OLD_PS1"

13
poetry.lock generated
View File

@ -424,6 +424,17 @@ rich = ">=10.7.0"
[package.extras]
dev = ["pre-commit"]
[[package]]
name = "sh"
version = "2.0.6"
description = "Python subprocess replacement"
optional = false
python-versions = ">=3.8.1,<4.0"
files = [
{file = "sh-2.0.6-py3-none-any.whl", hash = "sha256:ced8f2e081a858b66a46ace3703dec243779abbd5a1887ba7e3c34f34da70cd2"},
{file = "sh-2.0.6.tar.gz", hash = "sha256:9b2998f313f201c777e2c0061f0b1367497097ef13388595be147e2a00bf7ba1"},
]
[[package]]
name = "typer"
version = "0.9.0"
@ -459,4 +470,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "1747400a30523d50e0ccaf55386f60f05b4d6e5e222aeb8a737d4e78b702a210"
content-hash = "2673f8f06cf73701e5dac7ef463abeaf01bfb40b5c003e0898c7d97d0c589158"

View File

@ -21,6 +21,7 @@ coloredlogs = "^15.0.1"
rich = "^13.6.0"
rich-click = "^1.6.1"
colorama = "^0.4.6"
sh = "^2.0.6"
[tool.poetry.scripts]