Compare commits

...

13 Commits

Author SHA1 Message Date
1b4060dd1c v4.4.4
=====================================================================

- improved compatibility of scwrypts.plugin.zsh; no longer relies on
  user default fzf configuration

- added temporary downgrade of fakeroot to archlinux publish CI due
  to a confirmed bug in v1.35 and v1.36
2024-08-23 11:43:42 -06:00
6aba11d0be v4.4.3
=====================================================================

--- Bug Fixes ----------------------------

- fixed a(nother) bug which emerged from the latest version of github's
  actions/runner-images; zx is now forcibly managed by the runner, so
  install scripts must be skipped in CI
2024-05-14 12:36:44 -06:00
a945daeecc v4.4.2
=====================================================================

--- Bug Fixes ----------------------------

- fixed a bug which emerged from the latest version of github's
  actions/runner-images
2024-05-10 14:14:08 -06:00
2ef20860c4 v4.4.1
=====================================================================

--- Bug Fixes ----------------------------

- scwrypts now run when using --group and --type options without --name
- fixed spacing issues in scwrypts --help
- added missing = sign in config

--- New Features -------------------------

- zsh completion now loads with scwrypts.plugin.zsh (requires compdef)
2024-05-09 16:46:57 -06:00
3fe01a7263 v4.4.0
=====================================================================

Increased non-scwrypts-runtime compatibility and improved clarity
in user environments after sourcing the scwrypts.plugin.zsh.

--- New Features -------------------------

- added experimental support for --output json
- added 'scwrypts --list-groups' to output the SCWRYPTS_GROUPS value
- added 'scwrypts --config' to be `eval`-ed in non-scwrypts-runtime zsh

--- Changes ------------------------------

- removed config variables which pertained to old scwrypts

- removed deprecated --no-log

- cleaned up environment requirements and improved import saftey for
  scwrypts.plugin.zsh; scwrypts is now *required* on $PATH in order to work

- refactored group configuration to match external group configuration
  (configuration now in scwrypts.scwrypts.zsh rather than zsh/lib/config.group.zsh)

- plugins/kubectl now forces an unalias of `f` (for fluxcd) on load

- the 'use' command now supports the '-c' short flag for ease of quick
  use

- upgraded max supported python version to 3.12; dropped support for
  python 3.9 (>3.10 required)

- remove old references to SCWRYPTS_ROOT in favour of SCWRYPTS_ROOT__scwrypts

- SCWRYPTS_LOG_LEVEL setting is now forwarded when using the SCWRYPTS__RUN
  meta execution function
2024-05-08 23:11:09 -06:00
4146a0d297 v4.3.1
=====================================================================

- MacOS does some weird stuff with the homebrew prefix apparently
2024-04-16 10:39:19 -06:00
8f3e862086 v4.3.0
=====================================================================

--- Changes ------------------------------

- updated python scwrypts API to use latest pattern established in the
  nodejs library

- SCWRYPTS_ROOT__scwrypts is now supports loading with each run and
  detects managed installations vs manual installations; this now means
  SCWRYPTS_ROOT can no longer be injected to scwrypts (this was a v2
  legacy support thing and probably does not apply to you)

--- New Features -------------------------

- pypi/scwrypts )
     added 'get_generator' API to testing utilities to provide a nice
     way to include default generator options

--- Bug Fixes ----------------------------

- scwrypts groups which use a required environment name regex no longer
  load specialized static files outside of the required environments.
2024-04-16 09:17:40 -06:00
aefd575539 v4.2.6
=====================================================================

- OK, I trust that the AUR testing pipeline will only publish proper
  builds which match all the correct versions and have all the correct
  checksums... so it's enabled now
2024-04-14 02:26:56 -06:00
26992d2f01 v4.2.5
=====================================================================

- Remove testing artifact from AUR publish
2024-04-14 02:21:40 -06:00
487fa65d38 v4.2.4
=====================================================================

--- Bug Fixes ----------------------------

- Reinclude publish credentials for pypi and npm
2024-04-14 02:17:16 -06:00
3ff44f8e58 v4.2.3
=====================================================================

--- Bug Fixes ----------------------------

- AUR test-before-publish requires usage of the CIRCLE_TAG rather than
  the CIRCLE_BRANCH
2024-04-14 02:15:31 -06:00
f0a6b16a0c v4.2.2
=====================================================================

--- Bug Fixes ----------------------------

- Ensure CircleCI automatic publishes actually trigger on expected tags
2024-04-14 02:04:44 -06:00
74fe48cc4a v4.2.1
=====================================================================

--- New Features -------------------------

- Automatic test-stable rolling release to AUR
2024-04-14 01:59:01 -06:00
26 changed files with 875 additions and 282 deletions

View File

@ -4,7 +4,14 @@ version: 2.1
orbs: orbs:
python: circleci/python@2.1.1 python: circleci/python@2.1.1
executors: executors:
archlinux:
docker:
- image: archlinux:base-devel
resource_class: small
working_directory: /
python: python:
docker: docker:
- image: cimg/python:3.11 - image: cimg/python:3.11
@ -16,30 +23,134 @@ executors:
resource_class: medium resource_class: medium
jobs: commands:
python-test: archlinux-run:
executor: python description: execute command steps in the archlinux container from the CI user
working_directory: ~/scwrypts/py/lib parameters:
_name:
type: string
command:
type: string
working_directory:
type: string
default: /home/ci
steps: steps:
- checkout:
path: ~/scwrypts
- run: - run:
name: pytest name: << parameters._name >>
working_directory: << parameters.working_directory >>
command: su ci -c '<< parameters.command >>'
custom:
archlinux:
prepare:
- &archlinux-prepare
run:
name: prepare archlinux dependencies
command: |
pacman --noconfirm -Syu git openssh ca-certificates-utils
useradd -m ci
echo "ci ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
temp-downgrade-fakeroot:
- &archlinux-temp-downgrade-fakeroot
run:
name: downgrade fakeroot to v1.34 (v1.35 and v1.36 are confirmed to break)
command: |
pacman -U --noconfirm https://archive.archlinux.org/packages/f/fakeroot/fakeroot-1.34-1-x86_64.pkg.tar.zst
clone-aur:
- &archlinux-clone-aur
archlinux-run:
_name: clone aur/scwrypts
command: git clone https://aur.archlinux.org/scwrypts.git aur
clone-scwrypts:
- &archlinux-clone-scwrypts
run:
name: clone wrynegade/scwrypts
working_directory: /home/ci
command: |
GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no" git clone -b "$(echo $CIRCLE_BRANCH | grep . || echo $CIRCLE_TAG)" "$CIRCLE_REPOSITORY_URL" scwrypts
chown -R ci:ci ./scwrypts
jobs:
require-full-semver:
executor: python
steps:
- run:
name: check CIRCLE_TAG for full semantic version
command: | command: |
: \ : \
&& pip install . .[test] \ && [ $CIRCLE_TAG ] \
&& pytest \ && [[ $CIRCLE_TAG =~ ^v[0-9]*.[0-9]*.[0-9]*$ ]] \
; ;
- run: pip install build && python -m build
python-publish: aur-test:
executor: python executor: archlinux
working_directory: ~/scwrypts/py/lib
steps: steps:
- checkout: - *archlinux-prepare
path: ~/scwrypts - *archlinux-temp-downgrade-fakeroot
- run: pip install build && python -m build - *archlinux-clone-aur
- run: pip install twine && twine upload dist/* - *archlinux-clone-scwrypts
- archlinux-run:
_name: test aur build on current source
working_directory: /home/ci/aur
command: >-
:
&& PKGVER=$(sed -n "s/^pkgver=//p" ./PKGBUILD)
&& cp -r ../scwrypts ../scwrypts-$PKGVER
&& rm -rf ../scwrypts-$PKGVER/.circleci
&& rm -rf ../scwrypts-$PKGVER/.git
&& rm -rf ../scwrypts-$PKGVER/.gitattributes
&& rm -rf ../scwrypts-$PKGVER/.gitignore
&& rm -rf ../scwrypts-$PKGVER/.github
&& tar -czf scwrypts.tar.gz ../scwrypts-$PKGVER
&& echo "source=(scwrypts.tar.gz)" >> PKGBUILD
&& echo "sha256sums=(SKIP)" >> PKGBUILD
&& makepkg --noconfirm -si
&& echo validating scwrypts version
&& scwrypts --version | grep "^scwrypts v$PKGVER$"
;
aur-publish:
executor: archlinux
steps:
- *archlinux-prepare
- *archlinux-temp-downgrade-fakeroot
- *archlinux-clone-aur
- archlinux-run:
_name: update PKGBUILD and .SRCINFO
working_directory: /home/ci/aur
command: >-
:
&& NEW_VERSION=$(echo $CIRCLE_TAG | sed 's/^v//')
&& sed "s/pkgver=.*/pkgver=$NEW_VERSION/; s/^pkgrel=.*/pkgrel=1/; /sha256sums/d" PKGBUILD -i
&& makepkg -g >> PKGBUILD
&& makepkg --printsrcinfo > .SRCINFO
;
- archlinux-run:
_name: sanity check for version build
working_directory: /home/ci/aur
command: >-
:
&& makepkg --noconfirm -si
&& scwrypts --version
&& scwrypts --version | grep -q "^scwrypts $CIRCLE_TAG\$"
;
- archlinux-run:
_name: publish new version
working_directory: /home/ci/aur
command: >-
:
&& git add PKGBUILD .SRCINFO
&& git -c user.email=yage@yage.io -c user.name=yage commit -am "$CIRCLE_TAG"
&& eval $(ssh-agent)
&& echo -e $SSH_KEY_PRIVATE__AUR | ssh-add -
&& git remote add upstream ssh://aur@aur.archlinux.org/scwrypts.git
&& GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no" git push upstream
;
nodejs-test: nodejs-test:
executor: nodejs executor: nodejs
@ -108,51 +219,83 @@ jobs:
&& pnpm publish --no-git-checks \ && pnpm publish --no-git-checks \
; ;
python-test:
executor: python
working_directory: ~/scwrypts/py/lib
steps:
- checkout:
path: ~/scwrypts
- run:
name: pytest
command: |
: \
&& pip install . .[test] \
&& pytest \
;
- run: pip install build && python -m build
python-publish:
executor: python
working_directory: ~/scwrypts/py/lib
steps:
- checkout:
path: ~/scwrypts
- run: pip install build && python -m build
- run: pip install twine && twine upload dist/*
workflows: workflows:
python-dev: test:
jobs: jobs:
- python-test: - aur-test:
&dev-filters
filters: filters:
branches: branches:
ignore: /^main$/ ignore: /^main$/
python: - python-test: *dev-filters
- nodejs-test: *dev-filters
publish:
jobs: jobs:
- python-test: - require-full-semver:
filters: filters:
&only-run-on-full-semver-tag-filters
tags: tags:
only: /^v\d+\.\d+\.\d+.*$/ only: /^v\d+\.\d+\.\d+.*$/
branches: branches:
ignore: /^.*$/ ignore: /^.*$/
- aur-test:
&only-publish-for-full-semver
filters: *only-run-on-full-semver-tag-filters
requires:
- require-full-semver
- aur-publish:
#
# there's a crazy-low-chance race-condition between this job and the GH Action '../.github/workflows/automatic-release.yaml'
# - automatic-release creates the release artifact, but takes no more than 15-30 seconds (current avg:16s max:26s)
# - this publish step requires the release artifact, but waits for all language-repository publishes to complete first (a few minutes at least)
#
# if something goes wrong, this step can be safely rerun after fixing the release artifact :)
#
filters: *only-run-on-full-semver-tag-filters
context: [aur-yage]
requires:
- aur-test
- python-publish
- nodejs-publish
- python-test: *only-publish-for-full-semver
- python-publish: - python-publish:
requires: [python-test] filters: *only-run-on-full-semver-tag-filters
context: [pypi-yage] context: [pypi-yage]
filters: requires:
tags: - python-test
only: /^v\d+\.\d+\.\d+.*$/
branches:
ignore: /^.*$/
nodejs-dev: - nodejs-test: *only-publish-for-full-semver
jobs:
- nodejs-test:
filters:
branches:
ignore: /^main$/
nodejs:
jobs:
- nodejs-test:
filters:
tags:
only: /^v\d+\.\d+\.\d+.*$/
branches:
ignore: /^.*$/
- nodejs-publish: - nodejs-publish:
requires: [nodejs-test] filters: *only-run-on-full-semver-tag-filters
context: [npm-wrynegade] context: [npm-wrynegade]
filters: requires:
tags: - nodejs-test
only: /^v\d+\.\d+\.\d+.*$/
branches:
ignore: /^.*$/

View File

@ -12,13 +12,9 @@ export DISCORD__DEFAULT_AVATAR_URL=
export DISCORD__DEFAULT_CHANNEL_ID= export DISCORD__DEFAULT_CHANNEL_ID=
export DISCORD__DEFAULT_USERNAME= export DISCORD__DEFAULT_USERNAME=
export DISCORD__DEFAULT_WEBHOOK= export DISCORD__DEFAULT_WEBHOOK=
export I3__BORDER_PIXEL_SIZE=
export I3__DMENU_FONT_SIZE=
export I3__GLOBAL_FONT_SIZE=
export I3__MODEL_CONFIG=
export LINEAR__API_TOKEN= export LINEAR__API_TOKEN=
export MEDIA_SYNC__S3_BUCKET export MEDIA_SYNC__S3_BUCKET=
export MEDIA_SYNC__TARGETS export MEDIA_SYNC__TARGETS=
export REDIS_AUTH= export REDIS_AUTH=
export REDIS_HOST= export REDIS_HOST=
export REDIS_PORT= export REDIS_PORT=

View File

@ -15,11 +15,6 @@ DISCORD__DEFAULT_CHANNEL_ID |
DISCORD__DEFAULT_USERNAME | DISCORD__DEFAULT_USERNAME |
DISCORD__DEFAULT_WEBHOOK | DISCORD__DEFAULT_WEBHOOK |
I3__BORDER_PIXEL_SIZE | custom i3 configuration settings
I3__DMENU_FONT_SIZE |
I3__GLOBAL_FONT_SIZE |
I3__MODEL_CONFIG |
LINEAR__API_TOKEN | linear.app project management configuration LINEAR__API_TOKEN | linear.app project management configuration
MEDIA_SYNC__S3_BUCKET | s3 bucket name and filesystem targets for media backups MEDIA_SYNC__S3_BUCKET | s3 bucket name and filesystem targets for media backups

View File

@ -1,11 +1,10 @@
[[ $SCWRYPTS_KUBECTL_DRIVER_READY -eq 1 ]] && return 0 [[ $SCWRYPTS_KUBECTL_DRIVER_READY -eq 1 ]] && return 0
unalias k h >/dev/null 2>&1 unalias k h f >/dev/null 2>&1
k() { _SCWRYPTS_KUBECTL_DRIVER kubectl $@; } k() { _SCWRYPTS_KUBECTL_DRIVER kubectl $@; }
h() { _SCWRYPTS_KUBECTL_DRIVER helm $@; } h() { _SCWRYPTS_KUBECTL_DRIVER helm $@; }
f() { _SCWRYPTS_KUBECTL_DRIVER flux $@; } f() { _SCWRYPTS_KUBECTL_DRIVER flux $@; }
_SCWRYPTS_KUBECTL_DRIVER() { _SCWRYPTS_KUBECTL_DRIVER() {
[ ! $SCWRYPTS_ENV ] && { [ ! $SCWRYPTS_ENV ] && {
ERROR "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'" ERROR "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'"

View File

@ -4,7 +4,7 @@ from .scwrypts.exceptions import MissingVariableError
def getenv(name, required=True): def getenv(name, required=True):
value = os_getenv(name, None) value = os_getenv(f'{name}__override', os_getenv(name))
if required and not value: if required and not value:
raise MissingVariableError(name) raise MissingVariableError(name)

View File

@ -2,23 +2,22 @@ from types import SimpleNamespace
from pytest import fixture from pytest import fixture
from scwrypts.test import generate from scwrypts.test import get_generator
from scwrypts.test.character_set import uri from scwrypts.test.character_set import uri
options = { generate = get_generator({
'str_length_minimum': 8, 'str_length_minimum': 8,
'str_length_maximum': 128, 'str_length_maximum': 128,
'uuid_output_type': str, 'uuid_output_type': str,
} })
def get_request_client_sample_data(): def get_request_client_sample_data():
return { return {
'base_url' : generate(str, options | {'character_set': uri}), 'base_url' : generate(str, {'character_set': uri}),
'endpoint' : generate(str, options | {'character_set': uri}), 'endpoint' : generate(str, {'character_set': uri}),
'method' : generate(str, options), 'method' : generate(str),
'response' : generate('requests_Response', options | {'depth': 4}), 'response' : generate('requests_Response', {'depth': 4}),
'payload' : generate(dict, { 'payload' : generate(dict, {
**options,
'depth': 1, 'depth': 1,
'data_types': { str, 'uuid' }, 'data_types': { str, 'uuid' },
}), }),
@ -30,13 +29,11 @@ def fixture_sample():
**get_request_client_sample_data(), **get_request_client_sample_data(),
headers = generate(dict, { headers = generate(dict, {
**options,
'depth': 1, 'depth': 1,
'data_types': { str, 'uuid' }, 'data_types': { str, 'uuid' },
}), }),
payload_headers = generate(dict, { payload_headers = generate(dict, {
**options,
'depth': 1, 'depth': 1,
'data_types': { str, 'uuid' }, 'data_types': { str, 'uuid' },
}), }),

View File

@ -2,15 +2,14 @@ from types import SimpleNamespace
from pytest import fixture from pytest import fixture
from scwrypts.test import generate
from scwrypts.test.character_set import uri from scwrypts.test.character_set import uri
from ..conftest import options, get_request_client_sample_data from ..conftest import generate, get_request_client_sample_data
@fixture(name='sample') @fixture(name='sample')
def fixture_sample(): def fixture_sample():
return SimpleNamespace( return SimpleNamespace(
**get_request_client_sample_data(), **get_request_client_sample_data(),
api_token = generate(str, options | {'character_set': uri}), api_token = generate(str, {'character_set': uri}),
query = generate(str, options), query = generate(str),
) )

View File

@ -3,9 +3,8 @@ from types import SimpleNamespace
from pytest import fixture from pytest import fixture
from scwrypts.test import generate
from scwrypts.test.character_set import uri from scwrypts.test.character_set import uri
from ..conftest import options, get_request_client_sample_data from ..conftest import generate, get_request_client_sample_data
@fixture(name='sample') @fixture(name='sample')
def fixture_sample(): def fixture_sample():
@ -14,12 +13,12 @@ def fixture_sample():
**get_request_client_sample_data(), **get_request_client_sample_data(),
'base_url': 'https://discord.com/api', 'base_url': 'https://discord.com/api',
}, },
bot_token = generate(str, options | {'character_set': uri}), bot_token = generate(str, {'character_set': uri}),
username = generate(str, options | {'character_set': ascii_letters + digits}), username = generate(str, {'character_set': ascii_letters + digits}),
avatar_url = generate(str, options | {'character_set': uri}), avatar_url = generate(str, {'character_set': uri}),
webhook = generate(str, options | {'character_set': uri}), webhook = generate(str, {'character_set': uri}),
channel_id = generate(str, options | {'character_set': uri}), channel_id = generate(str, {'character_set': uri}),
content_header = generate(str, options), content_header = generate(str),
content_footer = generate(str, options), content_footer = generate(str),
content = generate(str, options), content = generate(str),
) )

View File

@ -3,9 +3,8 @@ from types import SimpleNamespace
from pytest import fixture from pytest import fixture
from scwrypts.test import generate
from scwrypts.test.character_set import uri from scwrypts.test.character_set import uri
from ..conftest import options, get_request_client_sample_data from ..conftest import generate, get_request_client_sample_data
@fixture(name='sample') @fixture(name='sample')
def fixture_sample(): def fixture_sample():
@ -14,6 +13,6 @@ def fixture_sample():
**get_request_client_sample_data(), **get_request_client_sample_data(),
'base_url': 'https://api.linear.app', 'base_url': 'https://api.linear.app',
}, },
api_token = generate(str, options | {'character_set': uri}), api_token = generate(str, {'character_set': uri}),
query = generate(str, options), query = generate(str),
) )

View File

@ -13,7 +13,7 @@ class MissingFlagAndEnvironmentVariableError(EnvironmentError, ArgumentError):
class MissingScwryptsExecutableError(EnvironmentError): class MissingScwryptsExecutableError(EnvironmentError):
def __init__(self): def __init__(self):
super().__init__(f'scwrypts must be installed and available on your PATH') super().__init__('scwrypts must be installed and available on your PATH')
class BadScwryptsLookupError(ValueError): class BadScwryptsLookupError(ValueError):

View File

@ -5,44 +5,54 @@ from subprocess import run
from .exceptions import MissingScwryptsExecutableError, BadScwryptsLookupError, MissingScwryptsGroupOrTypeError from .exceptions import MissingScwryptsExecutableError, BadScwryptsLookupError, MissingScwryptsGroupOrTypeError
def scwrypts(*args, patterns=None, name=None, group=None, _type=None, log_level=None): def scwrypts(patterns=None, args=None, executable_args=None, name=None, group=None, _type=None):
''' '''
top-level scwrypts invoker from python top-level scwrypts invoker from python
- patterns allows for pattern-based scwrypt lookup patterns str / list pattern-based scwrypt lookup
- name/group/type allos for precise-match lookup args str / list arguments forwarded to the invoked scwrypt
executable_args str / list arguments for the 'scwrypts' executable
(str above assumes space-delimited values)
*args should be a list of strings and is forwarded to the name str exact scwrypt lookup name (requires group and _type)
invoked scwrypt group str exact scwrypt lookup group
_type str exact scwrypt lookup type
SCWRYPTS_EXECUTABLE configuration variable which defines the full path to scwrypts executable
see 'scwrypts --help' for more information see 'scwrypts --help' for more information
''' '''
executable = which('scwrypts')
if executable is None:
raise MissingScwryptsExecutableError()
if patterns is None and name is None: if patterns is None and name is None:
raise BadScwryptsLookupError() raise BadScwryptsLookupError()
pre_args = [] if name is not None and (group is None or _type is None):
if name is None:
pre_args += patterns
else:
pre_args += ['--name', name, '--group', group, '--type', _type]
if group is None or _type is None:
raise MissingScwryptsGroupOrTypeError(group, _type) raise MissingScwryptsGroupOrTypeError(group, _type)
if log_level is not None: executable = which(getenv('SCWRYPTS_EXECUTABLE', 'scwrypts'))
pre_args += ['--log-level', log_level]
if executable is None:
raise MissingScwryptsExecutableError()
lookup = _parse(patterns) if name is None else f'--name {name} --group {group} --type {_type}'
depth = getenv('SUBSCWRYPT', '') depth = getenv('SUBSCWRYPT', '')
if depth != '': if depth != '':
depth = int(depth) + 1 depth = int(depth) + 1
return run( return run(
f'SUBSCWRYPT={depth} {executable} {" ".join(pre_args)} -- {" ".join(args)}', f'SUBSCWRYPT={depth} {executable} {_parse(executable_args)} {lookup} -- {_parse(args)}',
shell=True, shell=True,
executable='/bin/zsh', executable='/bin/zsh',
check=False, check=False,
capture_output=True,
text=True,
) )
def _parse(string_or_list_args):
if string_or_list_args is None:
return ''
if isinstance(string_or_list_args, list):
return ' '.join(string_or_list_args)
return str(string_or_list_args)

View File

@ -0,0 +1,184 @@
from random import choice
from re import search
from string import ascii_letters, digits
from types import SimpleNamespace
from unittest.mock import patch
from pytest import fixture, raises
from scwrypts.test import get_generator
from .exceptions import MissingScwryptsExecutableError, BadScwryptsLookupError, MissingScwryptsGroupOrTypeError
from .scwrypts import scwrypts
#####################################################################
def test_scwrypts(sample, _scwrypts):
assert validate_scwrypts_output(sample, _scwrypts)
def test_scwrypts_finds_system_executable(sample, _scwrypts, mock_which):
mock_which.assert_called_once_with(sample.env['SCWRYPTS_EXECUTABLE'])
def test_scwrypts_uses_configured_executable_path(_scwrypts, mock_getenv):
mock_getenv.assert_any_call('SCWRYPTS_EXECUTABLE', 'scwrypts')
def test_scwrypts_uses_correct_depth(_scwrypts, mock_getenv):
mock_getenv.assert_any_call('SUBSCWRYPT', '')
def test_scwrypts_runs_subprocess(_scwrypts, mock_run):
mock_run.assert_called_once()
##########################################
def test_scwrypts_omit_optionals(sample, _scwrypts_omit_optionals):
assert validate_scwrypts_output(sample, _scwrypts_omit_optionals)
def test_scwrypts_omit_optionals_finds_system_executable(sample, _scwrypts_omit_optionals, mock_which):
mock_which.assert_called_once_with('scwrypts')
def test_scwrypts_omit_optionals_uses_configured_executable_path(_scwrypts_omit_optionals, mock_getenv):
mock_getenv.assert_any_call('SCWRYPTS_EXECUTABLE', 'scwrypts')
def test_scwrypts_omit_optionals_uses_correct_depth(_scwrypts_omit_optionals, mock_getenv):
mock_getenv.assert_any_call('SUBSCWRYPT', '')
def test_scwrypts_omit_optionals_runs_subprocess(_scwrypts_omit_optionals, mock_run):
mock_run.assert_called_once()
##########################################
def test_invalid_lookup_missing_patterns_and_name(sample):
sample.patterns = None
sample.name = None
with raises(BadScwryptsLookupError):
scwrypts(**get_scwrypts_args(sample))
def test_invalid_name_lookup_missing_group(sample):
sample.group = None
with raises(MissingScwryptsGroupOrTypeError):
scwrypts(**get_scwrypts_args(sample))
def test_invalid_name_lookup_missing_type(sample):
sample._type = None # pylint: disable=protected-access
with raises(MissingScwryptsGroupOrTypeError):
scwrypts(**get_scwrypts_args(sample))
def test_invalid_scwrypts_installation(sample, mock_which):
mock_which.return_value = None
with raises(MissingScwryptsExecutableError):
scwrypts(**get_scwrypts_args(sample))
#####################################################################
generate = get_generator({
'str_length_minimum': 8,
'str_length_maximum': 128,
'character_set': ascii_letters + digits + '/-_'
})
def _generate_str_or_list_arg():
random_arg = generate(list, {'data_types': {str}})
return random_arg if choice([str, list]) == list else ' '.join(random_arg)
@fixture(name='sample')
def fixture_sample():
sample = SimpleNamespace(
patterns = _generate_str_or_list_arg(),
args = _generate_str_or_list_arg(),
executable_args = _generate_str_or_list_arg(),
name = generate(str),
group = generate(str),
_type = generate(str),
executable = generate(str),
env = {
'SCWRYPTS_EXECUTABLE': generate(str),
'SUBSCWRYPT': str(generate(int, {'minimum': 1, 'maximum': 99})),
},
returncode = generate(int),
stdout = generate(str),
stderr = generate(str),
)
return sample
def get_scwrypts_args(sample):
return {
key: getattr(sample, key)
for key in [
'patterns',
'args',
'executable_args',
'name',
'group',
'_type',
]
}
#####################################################################
@fixture(name='mock_which', autouse=True)
def fixture_mock_which(sample):
with patch('scwrypts.scwrypts.scwrypts.which') as mock:
mock.return_value = sample.executable
yield mock
@fixture(name='mock_getenv', autouse=True)
def fixture_mock_getenv(sample):
with patch('scwrypts.scwrypts.scwrypts.getenv') as mock:
mock.side_effect = sample.env.get
yield mock
@fixture(name='mock_run', autouse=True)
def fixture_mock_run(sample):
with patch('scwrypts.scwrypts.scwrypts.run') as mock:
mock.side_effect = lambda *args, **_kwargs: SimpleNamespace(
args = args,
returncode = sample.returncode,
stdout = sample.stdout,
stderr = sample.stderr,
)
yield mock
#####################################################################
@fixture(name='_scwrypts')
def fixture_scwrypts(sample):
return scwrypts(**get_scwrypts_args(sample))
@fixture(name='_scwrypts_omit_optionals')
def fixture_scwrypts_omit_optionals(sample):
sample.args = None
sample.executable_args = None
del sample.env['SCWRYPTS_EXECUTABLE']
del sample.env['SUBSCWRYPT']
return scwrypts(**get_scwrypts_args(sample))
def validate_scwrypts_output(sample, output):
#
# I would love to use 'assert _scwrypts == SimpleNamespace(...expected...)'
# but the output.args is difficult to recreate without copying all the
# processing logic over from the scwrypts function
#
# opting for a bit of a strange equality test here, checking the args
# as closely as possible without copying parsing logic
#
run_args_reduced_to_a_single_string = len(output.args) == 1
run_args_follow_expected_form = search(
fr'^SUBSCWRYPT=.* {sample.executable} .*-- .*$',
output.args[0],
)
return all([
run_args_reduced_to_a_single_string,
run_args_follow_expected_form,
output.returncode == sample.returncode,
output.stdout == sample.stdout,
output.stderr == sample.stderr,
])

View File

@ -5,6 +5,6 @@ __all__ = [
'generate', 'generate',
] ]
from .generate import generate from .generate import generate, get_generator
from .character_set import * from .character_set import *

View File

@ -45,6 +45,21 @@ DEFAULT_OPTIONS = {
'requests_response_status_code': status_codes.codes[200], 'requests_response_status_code': status_codes.codes[200],
} }
def get_generator(default_options=None):
if default_options is None:
default_options = {}
def generator_function(data_type=None, options_overrides=None):
if options_overrides is None:
options_overrides = {}
return generate(
data_type = data_type,
options = default_options | options_overrides,
)
return generator_function
def generate(data_type=None, options=None): def generate(data_type=None, options=None):
''' '''
generate random data with the call of a function generate random data with the call of a function

113
scwrypts
View File

@ -1,16 +1,12 @@
#!/bin/zsh #!/bin/zsh
export EXECUTION_DIR=$(pwd) export EXECUTION_DIR=$(pwd)
export SCWRYPTS_RUNTIME_ID=$(uuidgen)
source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42 source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
##################################################################### #####################################################################
() { () {
cd "$SCWRYPTS_ROOT__scwrypts" cd "$SCWRYPTS_ROOT__scwrypts"
GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; } GIT_SCWRYPTS() { git -C "$SCWRYPTS_ROOT__scwrypts" $@; }
local INSTALLATION_TYPE
[ ! -d "$SCWRYPTS_ROOT__scwrypts/.git" ] && [ ! -f "$SCWRYPTS_ROOT__scwrypts/.git" ] \
&& INSTALLATION_TYPE=$(cat "$SCWRYPTS_ROOT__scwrypts/MANAGED_BY" 2>/dev/null) \
|| INSTALLATION_TYPE=manual \
;
local ERRORS=0 local ERRORS=0
local USAGE=' local USAGE='
@ -26,18 +22,24 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
runtime runtime
-y, --yes auto-accept all [yn] prompts through current scwrypt -y, --yes auto-accept all [yn] prompts through current scwrypt
-e, --env <env-name> set environment; overwrites SCWRYPTS_ENV -e, --env <env-name> set environment; overwrites SCWRYPTS_ENV
-n shorthand for "--log-level 0" -n shorthand for "--log-level 0"
-v, --log-level [0-4] set incremental scwrypts log level to one of the following: -v, --log-level <0-4> set incremental scwrypts log level to one of the following:
0 : only command output and critical failures; skips logfile 0 : only command output and critical failures; skips logfile
1 : include success / failure messages 1 : include success / failure messages
2 : include status update messages 2 : include status update messages
3 : (default) include warning messages 3 : (default) include warning messages
4 : include debug messages 4 : include debug messages
-o, --output <format> specify output format; one of: pretty,json (default: pretty)
alternate commands alternate commands
-h, --help display this message and exit -h, --help display this message and exit
-l, --list print out command list and exit -l, --list print out command list and exit
--list-envs print out environment list and exit --list-envs print out environment list and exit
--list-groups print out configured scwrypts groups and exit
--config "eval"-ed to enable config and "use" import in non-scwrypts environments
--root print out SCWRYPTS_ROOT__scwrypts and exit
--update update scwrypts library to latest version --update update scwrypts library to latest version
--version print out scwrypts version and exit --version print out scwrypts version and exit
@ -60,8 +62,10 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
[ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=3 [ ! $SCWRYPTS_LOG_LEVEL ] && local SCWRYPTS_LOG_LEVEL=3
local SHIFT_COUNT
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
SHIFT_COUNT=1
case $1 in case $1 in
-[a-z][a-z]* ) -[a-z][a-z]* )
VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/') VARSPLIT=$(echo "$1 " | sed 's/^\(-.\)\(.*\) /\1 -\2/')
@ -85,16 +89,33 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
return 0 return 0
;; ;;
--list-groups )
echo "${SCWRYPTS_GROUPS[@]}" | sed 's/\s\+/\n/g' | sort -u
return 0
;;
--version ) --version )
case $INSTALLATION_TYPE in case $SCWRYPTS_INSTALLATION_TYPE in
manual ) echo "scwrypts $(GIT_SCWRYPTS describe --tags) (via GIT)" ;; manual ) echo "scwrypts $(GIT_SCWRYPTS describe --tags) (via GIT)" ;;
* ) echo scwrypts $(cat "$SCWRYPTS_ROOT__scwrypts/VERSION") ;; * ) echo "scwrypts $(cat "$SCWRYPTS_ROOT__scwrypts/VERSION")" ;;
esac esac
return 0 return 0
;; ;;
--root )
echo "$SCWRYPTS_ROOT__scwrypts"
return 0
;;
--config )
echo "source '$SCWRYPTS_ROOT__scwrypts/zsh/lib/import.driver.zsh'"
echo "CHECK_ENVIRONMENT --no-fail --no-usage"
echo "unset __SCWRYPT"
return 0
;;
--update ) --update )
case $INSTALLATION_TYPE in case $SCWRYPTS_INSTALLATION_TYPE in
aur ) aur )
SCWRYPTS_LOG_LEVEL=3 REMINDER " SCWRYPTS_LOG_LEVEL=3 REMINDER "
This installation is built from the AUR. Update through 'makepkg' or use This installation is built from the AUR. Update through 'makepkg' or use
@ -102,6 +123,10 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
" "
;; ;;
homebrew )
SCWRYPTS_LOG_LEVEL=3 REMINDER "This installation is managed by homebrew. Update me with 'brew update'"
;;
manual ) manual )
GIT_SCWRYPTS fetch --quiet origin main GIT_SCWRYPTS fetch --quiet origin main
GIT_SCWRYPTS fetch --quiet origin main --tags GIT_SCWRYPTS fetch --quiet origin main --tags
@ -137,46 +162,54 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
### scwrypts filters ##################### ### scwrypts filters #####################
-m | --name ) -m | --name )
((SHIFT_COUNT+=1))
[ $2 ] || { ERROR "missing value for argument $1"; break; } [ $2 ] || { ERROR "missing value for argument $1"; break; }
SEARCH_NAME=$2 SEARCH_NAME=$2
shift 1
;; ;;
-g | --group ) -g | --group )
((SHIFT_COUNT+=1))
[ $2 ] || { ERROR "missing value for argument $1"; break; } [ $2 ] || { ERROR "missing value for argument $1"; break; }
SEARCH_GROUP=$2 SEARCH_GROUP=$2
shift 1 GROUP=$2
;; ;;
-t | --type ) -t | --type )
((SHIFT_COUNT+=1))
[ $2 ] || { ERROR "missing value for argument $1"; break; } [ $2 ] || { ERROR "missing value for argument $1"; break; }
SEARCH_TYPE=$2 SEARCH_TYPE=$2
shift 1 TYPE=$2
;; ;;
### runtime settings ##################### ### runtime settings #####################
-y | --yes ) export __SCWRYPTS_YES=1 ;; -y | --yes ) export __SCWRYPTS_YES=1 ;;
-n | --no-log ) -n ) SCWRYPTS_LOG_LEVEL=0 ;;
SCWRYPTS_LOG_LEVEL=0
[[ $1 =~ ^--no-log$ ]] && WARNING 'the --no-log flag is deprecated and will be removed in scwrypts v4.2'
;;
-v | --log-level ) -v | --log-level )
((SHIFT_COUNT+=1))
[[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'" [[ $2 =~ ^[0-4]$ ]] || ERROR "invalid setting for log-level '$2'"
SCWRYPTS_LOG_LEVEL=$2 SCWRYPTS_LOG_LEVEL=$2
shift 1 ;;
-o | --output )
((SHIFT_COUNT+=1))
export SCWRYPTS_OUTPUT_FORMAT=$2
case $SCWRYPTS_OUTPUT_FORMAT in
pretty | json ) ;;
* ) ERROR "unsupported format '$SCWRYPTS_OUTPUT_FORMAT'" ;;
esac
;; ;;
-e | --env ) -e | --env )
((SHIFT_COUNT+=1))
[ $2 ] || { ERROR "missing value for argument $1"; break; } [ $2 ] || { ERROR "missing value for argument $1"; break; }
[ $ENV_NAME ] && DEBUG 'overwriting session environment' [ $ENV_NAME ] && DEBUG 'overwriting session environment'
ENV_NAME="$2" ENV_NAME="$2"
STATUS "using CLI environment '$ENV_NAME'" STATUS "using CLI environment '$ENV_NAME'"
shift 1
;; ;;
########################################## ##########################################
@ -185,9 +218,11 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
--* ) ERROR "unrecognized argument '$1'" ;; --* ) ERROR "unrecognized argument '$1'" ;;
* ) SEARCH_PATTERNS+=($1) ;; * ) SEARCH_PATTERNS+=($1) ;;
esac esac
shift 1 shift $SHIFT_COUNT
done done
[ $SCWRYPTS_OUTPUT_FORMAT ] || export SCWRYPTS_OUTPUT_FORMAT=pretty
[ $SEARCH_NAME ] && { [ $SEARCH_NAME ] && {
[ $SEARCH_TYPE ] || ERROR '--name requires --type argument' [ $SEARCH_TYPE ] || ERROR '--name requires --type argument'
[ $SEARCH_GROUP ] || ERROR '--name requires --group argument' [ $SEARCH_GROUP ] || ERROR '--name requires --group argument'
@ -214,7 +249,6 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
echo $SCWRYPTS_AVAILABLE | head -n1 echo $SCWRYPTS_AVAILABLE | head -n1
echo $SCWRYPTS_AVAILABLE | grep ' [^/]*'$SEARCH_TYPE'[^/]* ' echo $SCWRYPTS_AVAILABLE | grep ' [^/]*'$SEARCH_TYPE'[^/]* '
} \ } \
| awk '{$2=""; print $0;}' \
| sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \
| column -ts '^' | column -ts '^'
) )
@ -224,9 +258,8 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
SCWRYPTS_AVAILABLE=$( SCWRYPTS_AVAILABLE=$(
{ {
echo $SCWRYPTS_AVAILABLE | head -n1 echo $SCWRYPTS_AVAILABLE | head -n1
echo $SCWRYPTS_AVAILABLE | grep "$SEARCH_GROUP"'[^/]*$' echo $SCWRYPTS_AVAILABLE | grep "$SEARCH_GROUP"'[^/ ]*$'
} \ } \
| awk '{$NF=""; print $0;}' \
| sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \ | sed 's/ \+$/'$(printf $__COLOR_RESET)'/; s/ \+/^/g' \
| column -ts '^' | column -ts '^'
) )
@ -294,9 +327,17 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
[[ $ENV_REQUIRED =~ true ]] && { [[ $ENV_REQUIRED =~ true ]] && {
[ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV) [ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV)
[ ! $ENV_NAME ] && ABORT
export ENV_NAME
export SCWRYPTS_ENV=$ENV_NAME
for GROUP in ${SCWRYPTS_GROUPS[@]} for GROUP in ${SCWRYPTS_GROUPS[@]}
do do
local REQUIRED_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$GROUP)
[ $REQUIRED_REGEX ] && {
[[ $ENV_NAME =~ $REQUIRED_REGEX ]] || continue
}
local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP") local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP")
source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'" source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'"
@ -305,8 +346,6 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
source "$f" || FAIL 5 "invalid static config '$f'" source "$f" || FAIL 5 "invalid static config '$f'"
done done
done done
export ENV_NAME
} }
[ $REQUIRED_ENVIRONMENT_REGEX ] && { [ $REQUIRED_ENVIRONMENT_REGEX ] && {
@ -314,11 +353,12 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
|| FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)" || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment name to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)"
} }
########################################## ##########################################
[ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0 [ ! $SUBSCWRYPT ] && export SUBSCWRYPT=0
[[ $INSTALLATION_TYPE =~ ^manual$ ]] && { [[ $SCWRYPTS_INSTALLATION_TYPE =~ ^manual$ ]] && {
[[ $SUBSCWRYPT -eq 0 ]] && [[ $ENV_NAME =~ prod ]] && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] && { [[ $SUBSCWRYPT -eq 0 ]] && [[ $ENV_NAME =~ prod ]] && [[ $SCWRYPTS_LOG_LEVEL -gt 0 ]] && {
STATUS "on '$ENV_NAME'; checking diff against origin/main" STATUS "on '$ENV_NAME'; checking diff against origin/main"
@ -372,12 +412,13 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
[[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive [[ $SCWRYPT_NAME =~ interactive ]] && RUN_MODE=interactive
local HEADER FOOTER local HEADER FOOTER
[[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && { [[ $SCWRYPTS_LOG_LEVEL -ge 2 ]] && {
case $SCWRYPTS_OUTPUT_FORMAT in
pretty )
HEADER=$( HEADER=$(
echo " echo "
===================================================================== =====================================================================
script : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME scwrypt : $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME
run at : $(date) run at : $(date)
config : $ENV_NAME config : $ENV_NAME
log level : $SCWRYPTS_LOG_LEVEL log level : $SCWRYPTS_LOG_LEVEL
@ -386,11 +427,27 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
) )
FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m" FOOTER="\\033[1;33m--- SCWRYPT END ---------------------------------------------------\\033[0m"
;;
json )
HEADER=$(echo '{}' | jq -c ".
| .timestamp = \"$(date +%s)\"
| .runtime = \"$SCWRYPTS_RUNTIME_ID\"
| .scwrypt = \"start of $SCWRYPT_NAME $SCWRYPT_GROUP $SCWRYPT_TYPE\"
| .config = \"$ENV_NAME\"
| .logLevel = \"$SCWRYPTS_LOG_LEVEL\"
| .subscwrypt = $SUBSCWRYPT
")
;;
esac
} }
[[ $SUBSCWRYPT -eq 0 ]] || { [[ $SUBSCWRYPT -eq 0 ]] || {
case $SCWRYPTS_OUTPUT_FORMAT in
pretty )
HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" HEADER="\\033[0;33m--- ($SUBSCWRYPT) BEGIN $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---"
FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---" FOOTER="\\033[0;33m--- ($SUBSCWRYPT) END $SCWRYPT_GROUP $SCWRYPT_TYPE $SCWRYPT_NAME ---"
;;
esac
} }
##################################################################### #####################################################################
@ -421,5 +478,5 @@ source "$(dirname $(readlink -f "$0"))/zsh/lib/import.driver.zsh" || exit 42
&& echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m" && echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
return $EXIT_CODE return $EXIT_CODE
} 2>&1 | tee --append "$LOGFILE" } | tee --append "$LOGFILE"
} $@ } $@

View File

@ -1,46 +1,57 @@
#
# typically you do not need to reload this plugin in a single session;
# if for some reason you do, you can run the following command and
# source this file again
#
# unset __SCWRYPTS_PLUGIN_LOADED
#
[[ $__SCWRYPTS_PLUGIN_LOADED =~ true ]] && return 0
##################################################################### #####################################################################
command -v scwrypts &>/dev/null || { : \
echo 'scwrypts is required in your PATH in order to use the zsh plugins; skipping' >&2 && command -v scwrypts &>/dev/null \
&& eval "$(scwrypts --config)" \
|| {
echo 'scwrypts must be in PATH and properly configured; skipping zsh plugin setup' >&2
return 0 return 0
} }
NO_EXPORT_CONFIG=1 source "${0:a:h}/zsh/lib/import.driver.zsh" || return 42 __SCWRYPTS_PARSE() {
SCWRYPT_SELECTION=$(scwrypts --list | fzf --ansi --prompt 'select a script : ' --header-lines 1)
LBUFFER= RBUFFER=
[ $SCWRYPT_SELECTION ] || return 1
NAME=$(echo "$SCWRYPT_SELECTION" | awk '{print $1;}')
TYPE=$(echo "$SCWRYPT_SELECTION" | awk '{print $2;}')
GROUP=$(echo "$SCWRYPT_SELECTION" | awk '{print $3;}')
[ $NAME ] && [ $TYPE ] && [ $GROUP ]
}
##################################################################### #####################################################################
SCWRYPTS__ZSH_PLUGIN() { [ $SCWRYPTS_SHORTCUT ] && {
local SCWRYPT_SELECTION=$(scwrypts --list | FZF 'select a script' --header-lines 1) SCWRYPTS__ZSH_PLUGIN() {
local NAME local SCWRYPT_SELECTION NAME TYPE GROUP
local TYPE __SCWRYPTS_PARSE || { zle accept-line; return 0; }
local GROUP
LBUFFER= RBUFFER=
[ ! $SCWRYPT_SELECTION ] && { zle accept-line; return 0; }
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION RBUFFER="scwrypts --name $NAME --type $TYPE --group $GROUP"
which scwrypts >/dev/null 2>&1\
&& RBUFFER="scwrypts" || RBUFFER="$SCWRYPTS_ROOT/scwrypts"
RBUFFER+=" --name $NAME --group $GROUP --type $TYPE"
zle accept-line zle accept-line
} }
zle -N scwrypts SCWRYPTS__ZSH_PLUGIN zle -N scwrypts SCWRYPTS__ZSH_PLUGIN
bindkey $SCWRYPTS_SHORTCUT scwrypts bindkey $SCWRYPTS_SHORTCUT scwrypts
unset SCWRYPTS_SHORTCUT
}
##################################################################### #####################################################################
SCWRYPTS__ZSH_BUILDER_PLUGIN() { [ $SCWRYPTS_BUILDER_SHORTCUT ] && {
local SCWRYPT_SELECTION=$(scwrypts --list | FZF 'select a script' --header-lines 1) SCWRYPTS__ZSH_BUILDER_PLUGIN() {
local SCWRYPT_SELECTION NAME TYPE GROUP
__SCWRYPTS_PARSE || { echo >&2; zle accept-line; return 0; }
echo $SCWRYPT_SELECTION >&2 echo $SCWRYPT_SELECTION >&2
local NAME
local TYPE
local GROUP
LBUFFER= RBUFFER=
[ ! $SCWRYPT_SELECTION ] && { zle accept-line; return 0; }
SCWRYPTS__SEPARATE_SCWRYPT_SELECTION $SCWRYPT_SELECTION
scwrypts -n --name $NAME --group $GROUP --type $TYPE -- --help >&2 || { scwrypts -n --name $NAME --group $GROUP --type $TYPE -- --help >&2 || {
zle accept-line zle accept-line
@ -49,22 +60,22 @@ SCWRYPTS__ZSH_BUILDER_PLUGIN() {
echo echo
zle reset-prompt zle reset-prompt
which scwrypts >/dev/null 2>&1\ LBUFFER="scwrypts --name $NAME --type $TYPE --group $GROUP -- "
&& LBUFFER="scwrypts" || LBUFFER="$SCWRYPTS_ROOT/scwrypts" }
LBUFFER+=" --name $NAME --group $GROUP --type $TYPE -- " zle -N scwrypts-builder SCWRYPTS__ZSH_BUILDER_PLUGIN
bindkey $SCWRYPTS_BUILDER_SHORTCUT scwrypts-builder
unset SCWRYPTS_BUILDER_SHORTCUT
} }
zle -N scwrypts-builder SCWRYPTS__ZSH_BUILDER_PLUGIN
bindkey $SCWRYPTS_BUILDER_SHORTCUT scwrypts-builder
##################################################################### #####################################################################
SCWRYPTS__ZSH_PLUGIN_ENV() { [ $SCWRYPTS_ENV_SHORTCUT ] && {
SCWRYPTS__ZSH_PLUGIN_ENV() {
local RESET='reset' local RESET='reset'
local SELECTED=$(\ local SELECTED=$(\
{ [ $SCWRYPTS_ENV ] && echo $RESET; SCWRYPTS__GET_ENV_NAMES; } \ { [ $SCWRYPTS_ENV ] && echo $RESET; scwrypts --list-envs; } \
| FZF 'select an environment' \ | fzf --prompt 'select an environment : ' \
) )
zle clear-command-line zle clear-command-line
@ -74,7 +85,139 @@ SCWRYPTS__ZSH_PLUGIN_ENV() {
|| RBUFFER="export SCWRYPTS_ENV=$SELECTED" || RBUFFER="export SCWRYPTS_ENV=$SELECTED"
} }
zle accept-line zle accept-line
}
zle -N scwrypts-setenv SCWRYPTS__ZSH_PLUGIN_ENV
bindkey $SCWRYPTS_ENV_SHORTCUT scwrypts-setenv
unset SCWRYPTS_ENV_SHORTCUT
} }
zle -N scwrypts-setenv SCWRYPTS__ZSH_PLUGIN_ENV #####################################################################
bindkey $SCWRYPTS_ENV_SHORTCUT scwrypts-setenv
# badass(/terrifying?) zsh autocompletion
command -v compdef &>/dev/null && {
_scwrypts() {
echo $words | grep -q "\s--\s" && _arguments && return 0
eval "_arguments $(
{
HELP=$(scwrypts --help 2>&1 | sed -n 's/^\s\+\(-.* .\)/\1/p' | sed 's/[[]/(/g; s/[]]/)/g')
echo $HELP \
| sed 's/^\(\(-[^-\s]\),*\s*\|\)\(\(--[-a-z0-9A-Z\]*\)\s\(<\([^>]*\)>\|\)\|\)\s\+\(.*\)/\2[\7]:\6:->\2/' \
| grep -v '^[[]' \
;
echo $HELP \
| sed 's/^\(\(-[^-\s]\),*\s*\|\)\(\(--[-a-z0-9A-Z\]*\)\s\(<\([^>]*\)>\|\)\|\)\s\+\(.*\)/\4[\7]:\6:->\4/' \
| grep -v '^[[]' \
;
echo ":pattern:->pattern"
echo ":pattern:->pattern"
echo ":pattern:->pattern"
echo ":pattern:->pattern"
echo ":pattern:->pattern"
} | sed 's/::->.*$//g' | sed "s/\\(^\\|$\\)/'/g" | tr '\n' ' '
)"
local _group=''
echo $words | grep -q ' -g [^\s]' \
&& _group=$(echo $words | sed 's/.*-g \([^ ]\+\)\s*.*/\1/')
echo $words | grep -q ' --group .' \
&& _group=$(echo $words | sed 's/.*--group \([^ ]\+\)\s*.*/\1/')
local _type=''
echo $words | grep -q ' -t [^\s]' \
&& _type=$(echo $words | sed 's/.*-t \([^ ]\+\)\s*.*/\1/')
echo $words | grep -q ' --type .' \
&& _type=$(echo $words | sed 's/.*--type \([^ ]\+\)\s*.*/\1/')
local _name=''
echo $words | grep -q ' -m [^\s]' \
&& _name=$(echo $words | sed 's/.*-m \([^ ]\+\)\s*.*/\1/')
echo $words | grep -q ' --name .' \
&& _name=$(echo $words | sed 's/.*--name \([^ ]\+\)\s*.*/\1/')
local _pattern _patterns=()
[ ! $_name ] \
&& _patterns=($(echo "${words[@]:1}" | sed 's/\s\+/\n/g' | grep -v '^-'))
_get_remaining_scwrypts() {
[ $_name ] || local _name='[^ ]\+'
[ $_type ] || local _type='[^ ]\+'
[ $_group ] || local _group='[^ ]\+'
local remaining=$(\
scwrypts --list \
| sed "1d; s,\x1B\[[0-9;]*[a-zA-Z],,g" \
| grep "^$_name\s" \
| grep "\s$_group$" \
| grep "\s$_type\s" \
)
for _pattern in ${_patterns[@]}
do
remaining=$(echo "$remaining" | grep "$_pattern")
done
echo "$remaining"
}
case $state in
( -m | --name )
compadd $(_get_remaining_scwrypts | awk '{print $1;}' | sort -u)
;;
( -t | --type )
compadd $(_get_remaining_scwrypts | awk '{print $2;}' | sort -u)
;;
( -g | --group )
[[ $_name$_type$_group =~ ^$ ]] \
&& compadd $(scwrypts --list-groups) \
|| compadd $(_get_remaining_scwrypts | awk '{print $3;}' | sort -u) \
;;
( -e | --env )
compadd $(scwrypts --list-envs)
;;
( -v | --log-level )
local _help="$(\
scwrypts --help 2>&1 \
| sed -n '/-v, --log-level/,/^$/p' \
| sed -n 's/\s\+\([0-9]\) : \(.*\)/\1 -- \2/p' \
)"
eval "local _descriptions=($(echo "$_help" | sed "s/\\(^\|$\\)/'/g"))"
local _values=($(echo "$_help" | sed 's/ --.*//'))
compadd -d _descriptions -a _values
;;
( -o | --output )
compadd pretty json
;;
( pattern )
[[ $_name =~ ^$ ]] && {
local _remaining_scwrypts="$(_get_remaining_scwrypts)"
# stop providing suggestions if your pattern is sufficient
[[ $(echo $_remaining_scwrypts | wc -l) -le 1 ]] && return 0
local _remaining_patterns="$(echo "$_remaining_scwrypts" | sed 's/\s\+/\n/g; s|/|\n|g;' | sort -u)"
for _pattern in ${_patterns[@]}
do
_remaining_patterns="$(echo "$_remaining_patterns" | grep -v "^$_pattern$")"
done
compadd $(echo $_remaining_patterns)
}
;;
( * ) ;;
esac
}
compdef _scwrypts scwrypts
}
__SCWRYPTS_PLUGIN_LOADED=true

11
scwrypts.scwrypts.zsh Normal file
View File

@ -0,0 +1,11 @@
SCWRYPTS_GROUPS+=(scwrypts)
export SCWRYPTS_ROOT__scwrypts="$SCWRYPTS_ROOT"
export SCWRYPTS_COLOR__scwrypts='\033[0;32m'
#export SCWRYPTS_TYPE__scwrypts=
#export SCWRYPTS_LIBRARY_ROOT__scwrypts=
export SCWRYPTS_VIRTUALENV_PATH__scwrypts="$SCWRYPTS_DATA_PATH/virtualenv"
export SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts=(3.12 3.11 3.10)
export SCWRYPTS_NODE_VERSION__scwrypts=18.0.0

View File

@ -1,10 +0,0 @@
export SCWRYPTS_ROOT__scwrypts="$SCWRYPTS_ROOT"
export SCWRYPTS_LIBRARY_ROOT__scwrypts="$SCWRYPTS_ROOT/zsh/lib"
export SCWRYPTS_COLOR__scwrypts='\033[0;32m'
export SCWRYPTS_VIRTUALENV_PATH__scwrypts="$SCWRYPTS_DATA_PATH/virtualenv"
[ ! -d "$SCWRYPTS_VIRTUALENV_PATH__scwrypts" ] && mkdir -p "$SCWRYPTS_VIRTUALENV_PATH__scwrypts"
export SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts=(3.11 3.10 3.9)
export SCWRYPTS_NODE_VERSION__scwrypts=18.0.0

View File

@ -1,17 +1,31 @@
[[ $__SCWRYPT -eq 1 ]] && return 0 [[ $__SCWRYPT -eq 1 ]] && return 0
##################################################################### #####################################################################
[ ! $SCWRYPTS_ROOT ] \ # Apparently MacOS puts ALL of the homebrew stuff inside of a top level git repository
&& SCWRYPTS_ROOT="$(cd $(dirname "${0:a:h}"); git rev-parse --show-toplevel 2>/dev/null)" # with bizarre git ignores; so:
# - USE the git root if it's a manual install...
# - UNLESS that git root is just the $(brew --prefix)
SCWRYPTS_ROOT="$(cd -- ${0:a:h}; git rev-parse --show-toplevel 2>/dev/null | grep -v "^$(brew --prefix 2>/dev/null)$")"
[ ! $SCWRYPTS_ROOT ] && [ -d /usr/share/scwrypts ] \ [ $SCWRYPTS_ROOT ] && [ -d "$SCWRYPTS_ROOT" ] \
&& SCWRYPTS_ROOT=/usr/share/scwrypts || SCWRYPTS_ROOT="$(echo "${0:a:h}" | sed -n 's|\(share/scwrypts\).*$|\1|p')"
[ $SCWRYPTS_ROOT ] && [ -d "$SCWRYPTS_ROOT" ] || {
echo "cannot determine scwrypts root path for current installation; aborting"
exit 1
}
export SCWRYPTS_ROOT__scwrypts="$SCWRYPTS_ROOT" export SCWRYPTS_ROOT__scwrypts="$SCWRYPTS_ROOT"
[ -f "$SCWRYPTS_ROOT__scwrypts/MANAGED_BY" ] \
&& export SCWRYPTS_INSTALLATION_TYPE=$(cat "$SCWRYPTS_ROOT__scwrypts/MANAGED_BY") \
|| export SCWRYPTS_INSTALLATION_TYPE=manual \
;
##################################################################### #####################################################################
DEFAULT_CONFIG="$SCWRYPTS_ROOT/zsh/lib/config.user.zsh" DEFAULT_CONFIG="$SCWRYPTS_ROOT__scwrypts/zsh/lib/config.user.zsh"
source "$DEFAULT_CONFIG" source "$DEFAULT_CONFIG"
USER_CONFIG_OVERRIDES="$SCWRYPTS_CONFIG_PATH/config.zsh" USER_CONFIG_OVERRIDES="$SCWRYPTS_CONFIG_PATH/config.zsh"
@ -21,11 +35,13 @@ USER_CONFIG_OVERRIDES="$SCWRYPTS_CONFIG_PATH/config.zsh"
} }
source "$USER_CONFIG_OVERRIDES" source "$USER_CONFIG_OVERRIDES"
[ ! -d $SCWRYPTS_CONFIG_PATH ] && mkdir -p $SCWRYPTS_CONFIG_PATH mkdir -p \
[ ! -d $SCWRYPTS_DATA_PATH ] && mkdir -p $SCWRYPTS_DATA_PATH "$SCWRYPTS_CONFIG_PATH" \
[ ! -d $SCWRYPTS_ENV_PATH ] && mkdir -p $SCWRYPTS_ENV_PATH "$SCWRYPTS_DATA_PATH" \
[ ! -d $SCWRYPTS_LOG_PATH ] && mkdir -p $SCWRYPTS_LOG_PATH "$SCWRYPTS_ENV_PATH" \
[ ! -d $SCWRYPTS_OUTPUT_PATH ] && mkdir -p $SCWRYPTS_OUTPUT_PATH "$SCWRYPTS_LOG_PATH" \
"$SCWRYPTS_OUTPUT_PATH" \
;
export \ export \
SCWRYPTS_GROUPS \ SCWRYPTS_GROUPS \
@ -37,11 +53,10 @@ export \
SCWRYPTS_OUTPUT_PATH \ SCWRYPTS_OUTPUT_PATH \
; ;
SCWRYPTS_GROUPS=(scwrypts $(echo $SCWRYPTS_GROUPS | sed 's/\s\+/\n/g' | sort -u)) source "$SCWRYPTS_ROOT/scwrypts.scwrypts.zsh" \
source "$SCWRYPTS_ROOT/zsh/lib/config.group.zsh" \
|| FAIL 69 'failed to set up scwrypts group; aborting' || FAIL 69 'failed to set up scwrypts group; aborting'
##################################################################### #####################################################################
for plugin in $(ls $SCWRYPTS_ROOT__scwrypts/plugins) for plugin in $(ls $SCWRYPTS_ROOT__scwrypts/plugins)
@ -62,7 +77,8 @@ done
&& [ ! "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] \ && [ ! "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] \
&& [ $GITHUB_WORKSPACE ] \ && [ $GITHUB_WORKSPACE ] \
&& [ ! $SCWRYPTS_GITHUB_NO_AUTOLOAD ] \ && [ ! $SCWRYPTS_GITHUB_NO_AUTOLOAD ] \
&& SCWRYPTS_AUTODETECT_GROUP_BASEDIR="$GITHUB_WORKSPACE" && SCWRYPTS_AUTODETECT_GROUP_BASEDIR="$GITHUB_WORKSPACE" \
;
[ "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] && [ -d "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] && { [ "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] && [ -d "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" ] && {
for GROUP_LOADER in $(find "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" -type f -name \*scwrypts.zsh) for GROUP_LOADER in $(find "$SCWRYPTS_AUTODETECT_GROUP_BASEDIR" -type f -name \*scwrypts.zsh)
@ -72,5 +88,8 @@ done
} }
##################################################################### #####################################################################
[ $NO_EXPORT_CONFIG ] || __SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt
true SCWRYPTS_GROUPS=(scwrypts $(echo $SCWRYPTS_GROUPS | sed 's/\s\+/\n/g' | sort -u | grep -v '^scwrypts$'))
#####################################################################
__SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt

View File

@ -34,7 +34,7 @@ source "${0:a:h}/config.zsh"
use() { use() {
local SCWRYPTS_LIBRARY SCWRYPTS_LIBRARY_ROOT SCWRYPTS_LIBRARY_GROUP local SCWRYPTS_LIBRARY SCWRYPTS_LIBRARY_ROOT SCWRYPTS_LIBRARY_GROUP
local DEFER_ENVIRONMENT_CHECK=1 local DEFER_ENVIRONMENT_CHECK=true
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
@ -49,8 +49,8 @@ use() {
SCWRYPTS_LIBRARY_ROOT=$2 SCWRYPTS_LIBRARY_ROOT=$2
shift 1 shift 1
;; ;;
--check-environment ) -c | --check-environment )
DEFER_ENVIRONMENT_CHECK=0 DEFER_ENVIRONMENT_CHECK=false
;; ;;
* ) * )
[ ! $SCWRYPTS_LIBRARY ] \ [ ! $SCWRYPTS_LIBRARY ] \
@ -106,7 +106,7 @@ use() {
return 1 return 1
} }
[[ $DEFER_ENVIRONMENT_CHECK -eq 0 ]] && { [[ $DEFER_ENVIRONMENT_CHECK =~ false ]] && {
CHECK_ENVIRONMENT || { CHECK_ENVIRONMENT || {
((IMPORT_ERRORS+=1)) ((IMPORT_ERRORS+=1))
ERROR "import error for '$SCWRYPTS_LIBRARY_GROUP/$SCWRYPTS_LIBRARY'" ERROR "import error for '$SCWRYPTS_LIBRARY_GROUP/$SCWRYPTS_LIBRARY'"

View File

@ -12,7 +12,10 @@ SCWRYPTS__RUN() { # context wrapper to run scwrypts within scwrypts
local EXIT_CODE=0 local EXIT_CODE=0
((SUBSCWRYPT+=1)) ((SUBSCWRYPT+=1))
SUBSCWRYPT=$SUBSCWRYPT $SCWRYPTS_ROOT/scwrypts $@ SCWRYPTS_LOG_LEVEL=$SCWRYPTS_LOG_LEVEL \
SUBSCWRYPT=$SUBSCWRYPT \
$SCWRYPTS_ROOT__scwrypts/scwrypts $@
EXIT_CODE=$? EXIT_CODE=$?
((SUBSCWRYPT-=1)) ((SUBSCWRYPT-=1))

View File

@ -12,7 +12,7 @@ SCWRYPTS__GET_AVAILABLE_SCWRYPTS() {
local GROUP GROUP_PATH GROUP_COLOR LOOKUP_PIDS=() local GROUP GROUP_PATH GROUP_COLOR LOOKUP_PIDS=()
{ {
echo 'NAME^TYPE^GROUP' echo 'NAME^TYPE^GROUP'
for GROUP in ${SCWRYPTS_GROUPS} for GROUP in ${SCWRYPTS_GROUPS[@]}
do do
GROUP_PATH=$(eval echo '$SCWRYPTS_ROOT__'$GROUP) GROUP_PATH=$(eval echo '$SCWRYPTS_ROOT__'$GROUP)
GROUP_COLOR=$(eval echo '$SCWRYPTS_COLOR__'$GROUP) GROUP_COLOR=$(eval echo '$SCWRYPTS_COLOR__'$GROUP)
@ -94,7 +94,7 @@ SCWRYPTS__GET_RUNSTRING() {
} }
RUNSTRING="SCWRYPTS_ENV=$ENV_NAME; $RUNSTRING" RUNSTRING="SCWRYPTS_ENV=$ENV_NAME; $RUNSTRING"
RUNSTRING="source $SCWRYPTS_ROOT/zsh/lib/import.driver.zsh; $RUNSTRING" RUNSTRING="source $SCWRYPTS_ROOT__scwrypts/zsh/lib/import.driver.zsh; $RUNSTRING"
local _VIRTUALENV=$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$SCWRYPT_GROUP'/$SCWRYPT_TYPE/bin/activate') local _VIRTUALENV=$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$SCWRYPT_GROUP'/$SCWRYPT_TYPE/bin/activate')
[ -f $_VIRTUALENV ] && RUNSTRING="source $_VIRTUALENV; $RUNSTRING" [ -f $_VIRTUALENV ] && RUNSTRING="source $_VIRTUALENV; $RUNSTRING"

View File

@ -74,6 +74,8 @@ _VIRTUALENV__GET_PATH() {
local ENV_PATH="$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$GROUP 2>/dev/null)" local ENV_PATH="$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$GROUP 2>/dev/null)"
[ ! $ENV_PATH ] && ENV_PATH="$SCWRYPTS_VIRTUALENV_PATH__scwrypts" [ ! $ENV_PATH ] && ENV_PATH="$SCWRYPTS_VIRTUALENV_PATH__scwrypts"
mkdir -p "$ENV_PATH/$TYPE" &>/dev/null
echo $ENV_PATH/$TYPE echo $ENV_PATH/$TYPE
} }
@ -95,7 +97,7 @@ CREATE_VIRTUALENV__scwrypts__py() {
} }
done done
[ ! $PYTHON ] && { [ ! $PYTHON ] && {
ERROR 'python>=3.9 not available; skipping python env' ERROR 'python>=3.10 not available; skipping python env'
return 1 return 1
} }
@ -122,7 +124,7 @@ UPDATE_VIRTUALENV__scwrypts__py() {
PIP_INSTALL_ARGS+=(--no-cache-dir) PIP_INSTALL_ARGS+=(--no-cache-dir)
PIP_INSTALL_ARGS+=(-r requirements.txt) PIP_INSTALL_ARGS+=(-r requirements.txt)
cd "$SCWRYPTS_ROOT/py" cd "$SCWRYPTS_ROOT__scwrypts/py"
pip install ${PIP_INSTALL_ARGS[@]} pip install ${PIP_INSTALL_ARGS[@]}
} }
@ -159,7 +161,9 @@ ACTIVATE_VIRTUALENV__scwrypts__zx() {
UPDATE_VIRTUALENV__scwrypts__zx() { UPDATE_VIRTUALENV__scwrypts__zx() {
local NPM_INSTALL_ARGS=() local NPM_INSTALL_ARGS=()
cd "$SCWRYPTS_ROOT/zx" [ $CI ] && NPM_INSTALL_ARGS+=(--ignore-scripts)
cd "$SCWRYPTS_ROOT__scwrypts/zx"
npm install ${NPM_INSTALL_ARGS[@]} npm install ${NPM_INSTALL_ARGS[@]}
} }

View File

@ -1,5 +1,8 @@
FZF() { FZF() {
[ $CI ] && FAIL 1 'currently in CI, but FZF requires user input' [ $CI ] && {
DEBUG "invoked FZF with $@"
FAIL 1 'currently in CI, but FZF requires user input'
}
local FZF_ARGS=() local FZF_ARGS=()

View File

@ -5,20 +5,29 @@ PRINT() {
local STDOUT=0 local STDOUT=0
local LTRIM=1 local LTRIM=1
local FORMAT=$SCWRYPTS_OUTPUT_FORMAT
local _S
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
_S=1
case $1 in case $1 in
-n | --no-trim-tabs ) LTRIM=0 ;; -n | --no-trim-tabs ) LTRIM=0 ;;
-x | --no-line-end ) LAST_LINE_END='' ;; -x | --no-line-end ) LAST_LINE_END='' ;;
-o | --use-stdout ) STDOUT=1; STDERR=0 ;; -o | --use-stdout ) STDOUT=1; STDERR=0 ;;
-f | --format ) ((_S+=1)); FORMAT=$2 ;;
* ) MESSAGE+="$(echo $1) " ;; * ) MESSAGE+="$(echo $1) " ;;
esac esac
shift 1 shift $_S
done done
MESSAGE="$(echo "$MESSAGE" | sed 's/%/%%/g')" [ $FORMAT ] || FORMAT=pretty
local STYLED_MESSAGE
local STYLED_MESSAGE="$({ case $FORMAT in
pretty )
STYLED_MESSAGE="$(echo "$MESSAGE" | sed 's/%/%%/g')"
STYLED_MESSAGE="$({
printf "${COLOR}" printf "${COLOR}"
while IFS='' read line while IFS='' read line
do do
@ -30,9 +39,27 @@ PRINT() {
done <<< $MESSAGE done <<< $MESSAGE
})" })"
STYLED_MESSAGE="${COLOR}$(echo "$STYLED_MESSAGE" | sed 's/%/%%/g')${__COLOR_RESET}${LAST_LINE_END}" STYLED_MESSAGE="${COLOR}$(echo "$STYLED_MESSAGE" | sed 's/%/%%/g')${__COLOR_RESET}${LAST_LINE_END}"
;;
json )
STYLED_MESSAGE="$(
echo '{}' | jq -c ".
| .timestamp = \"$(date +%s)\"
| .runtime = \"$SCWRYPTS_RUNTIME_ID\"
| .status = \"$(echo "$PREFIX" | sed 's/ .*//')\"
| .message = $(echo $MESSAGE | sed 's/^\t\+//' | jq -Rs)
" | sed 's/\\/\\\\/g'
)\n"
;;
* )
echo "ERROR : unsupported format '$FORMAT'" >&2
return 1
;;
esac
[[ $STDERR -eq 1 ]] && printf $STYLED_MESSAGE >&2
[[ $STDOUT -eq 1 ]] && printf $STYLED_MESSAGE
[[ $STDERR -eq 1 ]] && printf -- "$STYLED_MESSAGE" >&2
[[ $STDOUT -eq 1 ]] && printf -- "$STYLED_MESSAGE"
return 0 return 0
} }

View File

@ -72,7 +72,7 @@ CHECK_ENVIRONMENT() {
$E "environment errors found (see above)\n$ERROR_MESSAGE" $E "environment errors found (see above)\n$ERROR_MESSAGE"
} }
[[ $MISSING_ENVIRONMENT_VARIABLES -ne 0 ]] && { [[ $MISSING_ENVIRONMENT_VARIABLES -ne 0 ]] && [[ $__SCWRYPT ]] && {
REMINDER " REMINDER "
to quickly update missing environment variables, run: to quickly update missing environment variables, run:
'scwrypts zsh/scwrypts/environment/edit' 'scwrypts zsh/scwrypts/environment/edit'