Worked on new docs/tutorial output.

development
Shawn Davis 3 years ago
parent 10c1c88b0b
commit 7ecdb3c1f3
  1. 111
      sandbox/cli.py
  2. 1
      scripttease/data/inventory/radicale/steps.ini
  3. 52
      scripttease/lib/contexts.py
  4. 3
      scripttease/lib/loaders/__init__.py
  5. 122
      scripttease/lib/loaders/base.py
  6. 18
      scripttease/lib/snippets/messages.py

@ -1,17 +1,17 @@
#! /usr/bin/env python #! /usr/bin/env python
from argparse import ArgumentParser, RawDescriptionHelpFormatter from argparse import ArgumentParser, RawDescriptionHelpFormatter
from commonkit import highlight_code, smart_cast from commonkit import highlight_code, indent, smart_cast
from commonkit.logging import LoggingHelper from commonkit.logging import LoggingHelper
from commonkit.shell import EXIT from commonkit.shell import EXIT
from markdown import markdown
import sys import sys
sys.path.insert(0, "../") sys.path.insert(0, "../")
from scripttease.constants import LOGGER_NAME from scripttease.constants import LOGGER_NAME
from scripttease.lib.contexts import load_variables, Context from scripttease.lib.contexts import Context
from scripttease.lib.loaders.ini import INILoader from scripttease.lib.loaders import load_variables, INILoader, YMLLoader
from scripttease.lib.loaders.yaml import YMLLoader
from scripttease.version import DATE as VERSION_DATE, VERSION from scripttease.version import DATE as VERSION_DATE, VERSION
DEBUG = 10 DEBUG = 10
@ -59,10 +59,11 @@ This command is used to parse configuration files and output the commands.
) )
parser.add_argument( parser.add_argument(
"-d", "-d=",
"--docs", "--docs=",
action="store_true", choices=["html", "markdown", "plain", "rst"],
dest="docs_enabled", # default="markdown",
dest="docs",
help="Output documentation instead of code." help="Output documentation instead of code."
) )
@ -172,7 +173,7 @@ This command is used to parse configuration files and output the commands.
filters[key].append(value) filters[key].append(value)
# Handle options. # Handle global command options.
options = dict() options = dict()
if args.options: if args.options:
for token in args.options: for token in args.options:
@ -208,8 +209,96 @@ This command is used to parse configuration files and output the commands.
exit(EXIT.ERROR) exit(EXIT.ERROR)
# Generate output. # Generate output.
if args.docs_enabled: if args.docs:
pass output = list()
for snippet in loader.get_snippets():
if snippet is None:
continue
if snippet.name == "explain":
output.append(snippet.args[0])
output.append("")
elif snippet.name == "screenshot":
if args.docs == "html":
b = list()
b.append('<img src="%s"' % snippet.args[0])
if snippet.caption:
b.append('alt="%s"' % snippet.caption)
if snippet.classes:
b.append('class="%s"' % snippet.classes)
if snippet.height:
b.append('height="%s"' % snippet.height)
if snippet.width:
b.append('width="%s"' % snippet)
output.append(" ".join(b) + ">")
elif args.docs == "plain":
output.append(snippet.args[0])
output.append("")
elif args.docs == "rst":
output.append(".. figure:: %s" % snippet.args[0])
if snippet.caption:
output.append(indent(":alt: %s" % snippet.caption))
if snippet.height:
output.append(indent(":height: %s" % snippet.height))
if snippet.width:
output.append(indent(":width: %s" % snippet.width))
output.append("")
else:
if snippet.caption:
output.append("![%s](%s)" % (snippet.caption, snippet.args[0]))
else:
output.append("![](%s)" % (snippet.args[0]))
output.append("")
elif snippet.name == "template":
if args.docs == "plain":
output.append("+++")
output.append(snippet.get_content())
output.append("+++")
elif args.docs == "rst":
output.append(".. code-block:: %s" % snippet.get_target_language())
output.append("")
output.append(indent(snippet.get_content()))
output.append("")
else:
output.append("```%s" % snippet.get_target_language())
output.append(snippet.get_content())
output.append("```")
else:
statement = snippet.get_statement(include_comment=False, include_register=False, include_stop=False)
if statement is not None:
line = snippet.comment.replace("#", "")
output.append("%s:" % line.capitalize())
output.append("")
if args.docs == "plain":
output.append("---")
output.append(statement)
output.append("---")
output.append("")
elif args.docs == "rst":
output.append(".. code-block:: bash")
output.append("")
output.append(indent(statement))
output.append("")
else:
output.append("```bash")
output.append(statement)
output.append("```")
output.append("")
if args.docs == "html":
print(markdown("\n".join(output), extensions=['fenced_code']))
else:
print("\n".join(output))
else: else:
commands = list() commands = list()
for snippet in loader.get_snippets(): for snippet in loader.get_snippets():

@ -24,6 +24,7 @@ system: yes
[create the systemd service file for radicale] [create the systemd service file for radicale]
template: radicale.service /etc/systemd/system/radicale.service template: radicale.service /etc/systemd/system/radicale.service
lang: ini
[start the radicale service] [start the radicale service]
start: radicale start: radicale

@ -1,58 +1,16 @@
# Imports # Imports
from commonkit import smart_cast
from configparser import ParsingError, RawConfigParser
import logging import logging
import os
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Exports # Exports
__all__ = ( __all__ = (
"load_variables",
"Context", "Context",
"Variable", "Variable",
) )
# Functions
def load_variables(path):
"""Load variables from an INI file.
:param path: The path to the INI file.
:type path: str
:rtype: list[scripttease.lib.contexts.Variable]
"""
if not os.path.exists(path):
log.warning("Variables file does not exist: %s" % path)
return list()
ini = RawConfigParser()
try:
ini.read(path)
except ParsingError as e:
log.warning("Failed to parse %s variables file: %s" % (path, str(e)))
return list()
variables = list()
for variable_name in ini.sections():
_value = None
kwargs = dict()
for key, value in ini.items(variable_name):
if key == "value":
_value = smart_cast(value)
continue
kwargs[key] = smart_cast(value)
variables.append(Variable(variable_name, _value, **kwargs))
return variables
# Classes # Classes
@ -108,11 +66,10 @@ class Context(object):
return d return d
class Variable(object): class Variable(object):
"""An individual variable.""" """An individual variable."""
def __init__(self, name, value, **kwargs): def __init__(self, name, value, environment=None, **kwargs):
"""Initialize a variable. """Initialize a variable.
:param name: The name of the variable. :param name: The name of the variable.
@ -120,13 +77,18 @@ class Variable(object):
:param value: The value of the variable. :param value: The value of the variable.
:param environment: The environment in which the variable is used.
:type environment: str
kwargs are available as dynamic attributes. kwargs are available as dynamic attributes.
""" """
self.attributes = kwargs self.environment = environment
self.name = name self.name = name
self.value = value self.value = value
self.attributes = kwargs
def __getattr__(self, item): def __getattr__(self, item):
return self.attributes.get(item) return self.attributes.get(item)

@ -1,3 +1,6 @@
""" """
The job of a loader is to collect commands and their arguments from a text file. The job of a loader is to collect commands and their arguments from a text file.
""" """
from .base import filter_snippets, load_variables
from .ini import INILoader
from .yaml import YMLLoader

@ -1,21 +1,111 @@
# Imports # Imports
from commonkit import parse_jinja_string, parse_jinja_template, pick, read_file, smart_cast, split_csv, File from commonkit import any_list_item, parse_jinja_string, parse_jinja_template, pick, read_file, smart_cast, split_csv, \
File
from configparser import ParsingError, RawConfigParser
from jinja2.exceptions import TemplateError, TemplateNotFound from jinja2.exceptions import TemplateError, TemplateNotFound
import logging import logging
import os import os
from ..contexts import Variable
from ..snippets.mappings import MAPPINGS from ..snippets.mappings import MAPPINGS
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Exports # Exports
__all__ = ( __all__ = (
"filter_snippets",
"load_variables",
"BaseLoader", "BaseLoader",
"Snippet", "Snippet",
"Sudo", "Sudo",
"Template", "Template",
) )
# Functions
def filter_snippets(snippets, environments=None, tags=None):
"""Filter snippets based on the given criteria.
:param snippets: The snippets to be filtered.
:type snippets: list[scripttease.lib.loaders.base.Snippet]
:param environments: Environment names to be matched.
:type environments: list[str]
:param tags: Tag names to be matched.
:type tags: list[str]
"""
filtered = list()
for snippet in snippets:
if environments is not None and len(snippet.environments) > 0:
if not any_list_item(environments, snippet.environments):
continue
if tags is not None:
if not any_list_item(tags, snippet.tags):
continue
filtered.append(snippet)
return filtered
def load_variables(path, env=None):
"""Load variables from an INI file.
:param path: The path to the INI file.
:type path: str
:param env: The environment name of variables to return.
:type env: str
:rtype: list[scripttease.lib.contexts.Variable]
"""
if not os.path.exists(path):
log.warning("Variables file does not exist: %s" % path)
return list()
ini = RawConfigParser()
try:
ini.read(path)
except ParsingError as e:
log.warning("Failed to parse %s variables file: %s" % (path, str(e)))
return list()
variables = list()
for variable_name in ini.sections():
if ":" in variable_name:
variable_name, _environment = variable_name.split(":")
else:
_environment = None
variable_name = variable_name
kwargs = {
'environment': _environment,
}
_value = None
for key, value in ini.items(variable_name):
if key == "value":
_value = smart_cast(value)
continue
kwargs[key] = smart_cast(value)
variables.append(Variable(variable_name, _value, **kwargs))
if env is not None:
filtered_variables = list()
for var in variables:
if var.environment and var.environment == env or var.environment is None:
filtered_variables.append(var)
return filtered_variables
return variables
# Classes # Classes
@ -305,6 +395,9 @@ class Snippet(object):
self.kwargs = kwargs or dict() self.kwargs = kwargs or dict()
self.name = name self.name = name
self.environments = kwargs.pop("environments", list())
self.tags = kwargs.pop("tags", list())
sudo = self.kwargs.pop("sudo", None) sudo = self.kwargs.pop("sudo", None)
if isinstance(sudo, Sudo): if isinstance(sudo, Sudo):
self.sudo = sudo self.sudo = sudo
@ -509,14 +602,14 @@ class Template(object):
def __init__(self, source, target, backup=True, parser=PARSER_JINJA, **kwargs): def __init__(self, source, target, backup=True, parser=PARSER_JINJA, **kwargs):
self.backup_enabled = backup self.backup_enabled = backup
self.context = kwargs.pop("context", dict()) self.context = kwargs.pop("context", dict())
self.kwargs = kwargs self.name = "template"
self.parser = parser self.parser = parser
self.language = kwargs.pop("lang", None)
self.locations = kwargs.pop("locations", list()) self.locations = kwargs.pop("locations", list())
self.source = os.path.expanduser(source) self.source = os.path.expanduser(source)
self.target = target self.target = target
sudo = self.kwargs.pop("sudo", None) sudo = kwargs.pop("sudo", None)
if isinstance(sudo, Sudo): if isinstance(sudo, Sudo):
self.sudo = sudo self.sudo = sudo
elif type(sudo) is str: elif type(sudo) is str:
@ -526,6 +619,8 @@ class Template(object):
else: else:
self.sudo = Sudo() self.sudo = Sudo()
self.kwargs = kwargs
def __getattr__(self, item): def __getattr__(self, item):
return self.kwargs.get(item) return self.kwargs.get(item)
@ -603,6 +698,25 @@ class Template(object):
return "\n".join(lines) return "\n".join(lines)
def get_target_language(self):
if self.language is not None:
return self.language
if self.target.endswith(".conf"):
return "conf"
elif self.target.endswith(".ini"):
return "ini"
elif self.target.endswith(".php"):
return "php"
elif self.target.endswith(".py"):
return "python"
elif self.target.endswith(".sh"):
return "bash"
elif self.target.endswith(".yml"):
return "yaml"
else:
return "text"
def get_template(self): def get_template(self):
"""Get the template path. """Get the template path.

@ -7,22 +7,8 @@ messages = {
'clear;' 'clear;'
], ],
'echo': 'echo "{{ args[0] }}"', 'echo': 'echo "{{ args[0] }}"',
'explain': "{{ args[0] }} ", 'explain': None,
'screenshot': [ 'screenshot': None,
'{% if output == "md" %}',
"![{% if caption %}{{ caption }}]({{ args[0] }})",
'{% elif output == "rst" %}',
'.. figure:: {{ args[0] }}',
'{% if caption %}\n :alt: {{ caption }}{% endif %}',
'{% if height %}\n :height: {{ height }}{% endif %}',
'{% if width %}\n :width: {{ width }}{% endif %}'
'\n',
'{% else %}',
'<img src="{{ args[0] }}"{% if caption %} alt="{{ caption }}{% endif %}'
'{% if classes %} class={{ classes }}{% endif %}'
'{% if height %} height="{{ height }}{% endif %}{% if width %} width="{{ width }}"{% endif %}>',
'{% endif %}',
],
'slack': [ 'slack': [
"curl -X POST -H 'Content-type: application/json' --data", "curl -X POST -H 'Content-type: application/json' --data",
'{"text": "{{ args[0] }}"}', '{"text": "{{ args[0] }}"}',

Loading…
Cancel
Save