parent
6fec406d04
commit
1376d33e0a
67 changed files with 4093 additions and 987 deletions
@ -1,8 +1,9 @@ |
|||||||
[run] |
[run] |
||||||
omit = |
omit = |
||||||
docs/* |
docs/* |
||||||
scripttease/cli/__init__.py |
scripttease/cli/* |
||||||
sandbox |
sandbox |
||||||
setup.py |
setup.py |
||||||
|
tests/* |
||||||
tmp/* |
tmp/* |
||||||
tmp.* |
tmp.* |
||||||
|
@ -1 +1 @@ |
|||||||
5.8.18-d |
6.0.0-d |
@ -0,0 +1,229 @@ |
|||||||
|
# Makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
|
# You can set these variables from the command line.
|
||||||
|
SPHINXOPTS =
|
||||||
|
SPHINXBUILD = sphinx-build
|
||||||
|
PAPER =
|
||||||
|
BUILDDIR = build
|
||||||
|
|
||||||
|
# User-friendly check for sphinx-build
|
||||||
|
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) |
||||||
|
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||||
|
endif |
||||||
|
|
||||||
|
# Internal variables.
|
||||||
|
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||||
|
PAPEROPT_letter = -D latex_paper_size=letter
|
||||||
|
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||||
|
# the i18n builder cannot share the environment and doctrees with the others
|
||||||
|
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
|
||||||
|
|
||||||
|
.PHONY: help |
||||||
|
help: |
||||||
|
@echo "Please use \`make <target>' where <target> is one of"
|
||||||
|
@echo " html to make standalone HTML files"
|
||||||
|
@echo " dirhtml to make HTML files named index.html in directories"
|
||||||
|
@echo " singlehtml to make a single large HTML file"
|
||||||
|
@echo " pickle to make pickle files"
|
||||||
|
@echo " json to make JSON files"
|
||||||
|
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||||
|
@echo " qthelp to make HTML files and a qthelp project"
|
||||||
|
@echo " applehelp to make an Apple Help Book"
|
||||||
|
@echo " devhelp to make HTML files and a Devhelp project"
|
||||||
|
@echo " epub to make an epub"
|
||||||
|
@echo " epub3 to make an epub3"
|
||||||
|
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||||
|
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||||
|
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||||
|
@echo " text to make text files"
|
||||||
|
@echo " man to make manual pages"
|
||||||
|
@echo " texinfo to make Texinfo files"
|
||||||
|
@echo " info to make Texinfo files and run them through makeinfo"
|
||||||
|
@echo " gettext to make PO message catalogs"
|
||||||
|
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||||
|
@echo " xml to make Docutils-native XML files"
|
||||||
|
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||||
|
@echo " linkcheck to check all external links for integrity"
|
||||||
|
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||||
|
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||||
|
|
||||||
|
.PHONY: clean |
||||||
|
clean: |
||||||
|
rm -rf $(BUILDDIR)/*
|
||||||
|
|
||||||
|
.PHONY: html |
||||||
|
html: |
||||||
|
#./generate_command_signatures.py > source/_command-examples.rst
|
||||||
|
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||||
|
|
||||||
|
.PHONY: dirhtml |
||||||
|
dirhtml: |
||||||
|
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||||
|
|
||||||
|
.PHONY: singlehtml |
||||||
|
singlehtml: |
||||||
|
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||||
|
|
||||||
|
.PHONY: pickle |
||||||
|
pickle: |
||||||
|
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can process the pickle files."
|
||||||
|
|
||||||
|
.PHONY: json |
||||||
|
json: |
||||||
|
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can process the JSON files."
|
||||||
|
|
||||||
|
.PHONY: htmlhelp |
||||||
|
htmlhelp: |
||||||
|
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||||
|
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||||
|
|
||||||
|
.PHONY: qthelp |
||||||
|
qthelp: |
||||||
|
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||||
|
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||||
|
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/BasisHR.qhcp"
|
||||||
|
@echo "To view the help file:"
|
||||||
|
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/BasisHR.qhc"
|
||||||
|
|
||||||
|
.PHONY: applehelp |
||||||
|
applehelp: |
||||||
|
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||||
|
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||||
|
"~/Library/Documentation/Help or install it in your application" \
|
||||||
|
"bundle."
|
||||||
|
|
||||||
|
.PHONY: devhelp |
||||||
|
devhelp: |
||||||
|
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||||
|
@echo
|
||||||
|
@echo "Build finished."
|
||||||
|
@echo "To view the help file:"
|
||||||
|
@echo "# mkdir -p $$HOME/.local/share/devhelp/BasisHR"
|
||||||
|
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/BasisHR"
|
||||||
|
@echo "# devhelp"
|
||||||
|
|
||||||
|
.PHONY: epub |
||||||
|
epub: |
||||||
|
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||||
|
|
||||||
|
.PHONY: epub3 |
||||||
|
epub3: |
||||||
|
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
|
||||||
|
|
||||||
|
.PHONY: latex |
||||||
|
latex: |
||||||
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
|
@echo
|
||||||
|
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||||
|
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||||
|
"(use \`make latexpdf' here to do that automatically)."
|
||||||
|
|
||||||
|
.PHONY: latexpdf |
||||||
|
latexpdf: |
||||||
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
|
@echo "Running LaTeX files through pdflatex..."
|
||||||
|
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||||
|
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||||
|
|
||||||
|
.PHONY: latexpdfja |
||||||
|
latexpdfja: |
||||||
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
|
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||||
|
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||||
|
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||||
|
|
||||||
|
.PHONY: text |
||||||
|
text: |
||||||
|
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||||
|
|
||||||
|
.PHONY: man |
||||||
|
man: |
||||||
|
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||||
|
|
||||||
|
.PHONY: texinfo |
||||||
|
texinfo: |
||||||
|
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||||
|
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||||
|
"(use \`make info' here to do that automatically)."
|
||||||
|
|
||||||
|
.PHONY: info |
||||||
|
info: |
||||||
|
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||||
|
@echo "Running Texinfo files through makeinfo..."
|
||||||
|
make -C $(BUILDDIR)/texinfo info
|
||||||
|
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||||
|
|
||||||
|
.PHONY: gettext |
||||||
|
gettext: |
||||||
|
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||||
|
|
||||||
|
.PHONY: changes |
||||||
|
changes: |
||||||
|
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||||
|
@echo
|
||||||
|
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||||
|
|
||||||
|
.PHONY: linkcheck |
||||||
|
linkcheck: |
||||||
|
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||||
|
@echo
|
||||||
|
@echo "Link check complete; look for any errors in the above output " \
|
||||||
|
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||||
|
|
||||||
|
.PHONY: doctest |
||||||
|
doctest: |
||||||
|
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||||
|
@echo "Testing of doctests in the sources finished, look at the " \
|
||||||
|
"results in $(BUILDDIR)/doctest/output.txt."
|
||||||
|
|
||||||
|
.PHONY: coverage |
||||||
|
coverage: |
||||||
|
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||||
|
@echo "Testing of coverage in the sources finished, look at the " \
|
||||||
|
"results in $(BUILDDIR)/coverage/python.txt."
|
||||||
|
|
||||||
|
.PHONY: xml |
||||||
|
xml: |
||||||
|
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||||
|
|
||||||
|
.PHONY: pseudoxml |
||||||
|
pseudoxml: |
||||||
|
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||||
|
@echo
|
||||||
|
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
||||||
|
|
||||||
|
.PHONY: robots |
||||||
|
robots: |
||||||
|
cp source/robots.txt build/html/;
|
||||||
|
|
@ -0,0 +1,65 @@ |
|||||||
|
#! /usr/bin/env python |
||||||
|
|
||||||
|
from collections import OrderedDict |
||||||
|
import inspect |
||||||
|
import sys |
||||||
|
|
||||||
|
sys.path.append("../") |
||||||
|
|
||||||
|
from script_tease.mappings import MAPPING |
||||||
|
|
||||||
|
|
||||||
|
# https://stackoverflow.com/a/52003056/241720 |
||||||
|
def get_signature(fn): |
||||||
|
params = inspect.signature(fn).parameters |
||||||
|
args = [] |
||||||
|
kwargs = OrderedDict() |
||||||
|
for p in params.values(): |
||||||
|
if p.default is p.empty: |
||||||
|
args.append(p.name) |
||||||
|
else: |
||||||
|
kwargs[p.name] = p.default |
||||||
|
return args, kwargs |
||||||
|
|
||||||
|
|
||||||
|
keys = list(MAPPING.keys()) |
||||||
|
keys.sort() |
||||||
|
|
||||||
|
for key in keys: |
||||||
|
cls = MAPPING[key] |
||||||
|
|
||||||
|
print(key) |
||||||
|
print("." * len(key)) |
||||||
|
print("") |
||||||
|
|
||||||
|
extra = cls.get_docs() |
||||||
|
if extra is not None: |
||||||
|
print(extra) |
||||||
|
print("") |
||||||
|
|
||||||
|
# if cls.__init__.__doc__: |
||||||
|
# print(cls.__init__.__doc__) |
||||||
|
# print("") |
||||||
|
|
||||||
|
print(".. code-block:: cfg") |
||||||
|
print("") |
||||||
|
|
||||||
|
if cls.__doc__: |
||||||
|
print(" [%s]" % cls.__doc__.strip().replace(".", "").lower()) |
||||||
|
else: |
||||||
|
print(" [run a %s command]" % cls.__name__.lower()) |
||||||
|
|
||||||
|
args, kwargs = get_signature(cls.__init__) |
||||||
|
|
||||||
|
line = list() |
||||||
|
for a in args: |
||||||
|
if a not in ("self", "kwargs"): |
||||||
|
line.append(a) |
||||||
|
|
||||||
|
print(" %s = %s" % (key, " ".join(line))) |
||||||
|
|
||||||
|
for option, value in kwargs.items(): |
||||||
|
print(" %s = %s" % (option, value)) |
||||||
|
|
||||||
|
print("") |
||||||
|
|
@ -0,0 +1,272 @@ |
|||||||
|
@ECHO OFF |
||||||
|
|
||||||
|
REM Command file for Sphinx documentation |
||||||
|
|
||||||
|
if "%SPHINXBUILD%" == "" ( |
||||||
|
set SPHINXBUILD=sphinx-build |
||||||
|
) |
||||||
|
set BUILDDIR=build |
||||||
|
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source |
||||||
|
set I18NSPHINXOPTS=%SPHINXOPTS% source |
||||||
|
if NOT "%PAPER%" == "" ( |
||||||
|
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% |
||||||
|
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "" goto help |
||||||
|
|
||||||
|
if "%1" == "help" ( |
||||||
|
:help |
||||||
|
echo.Please use `make ^<target^>` where ^<target^> is one of |
||||||
|
echo. html to make standalone HTML files |
||||||
|
echo. dirhtml to make HTML files named index.html in directories |
||||||
|
echo. singlehtml to make a single large HTML file |
||||||
|
echo. pickle to make pickle files |
||||||
|
echo. json to make JSON files |
||||||
|
echo. htmlhelp to make HTML files and a HTML help project |
||||||
|
echo. qthelp to make HTML files and a qthelp project |
||||||
|
echo. devhelp to make HTML files and a Devhelp project |
||||||
|
echo. epub to make an epub |
||||||
|
echo. epub3 to make an epub3 |
||||||
|
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter |
||||||
|
echo. text to make text files |
||||||
|
echo. man to make manual pages |
||||||
|
echo. texinfo to make Texinfo files |
||||||
|
echo. gettext to make PO message catalogs |
||||||
|
echo. changes to make an overview over all changed/added/deprecated items |
||||||
|
echo. xml to make Docutils-native XML files |
||||||
|
echo. pseudoxml to make pseudoxml-XML files for display purposes |
||||||
|
echo. linkcheck to check all external links for integrity |
||||||
|
echo. doctest to run all doctests embedded in the documentation if enabled |
||||||
|
echo. coverage to run coverage check of the documentation if enabled |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "clean" ( |
||||||
|
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i |
||||||
|
del /q /s %BUILDDIR%\* |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
REM Check if sphinx-build is available and fallback to Python version if any |
||||||
|
%SPHINXBUILD% 1>NUL 2>NUL |
||||||
|
if errorlevel 9009 goto sphinx_python |
||||||
|
goto sphinx_ok |
||||||
|
|
||||||
|
:sphinx_python |
||||||
|
|
||||||
|
set SPHINXBUILD=python -m sphinx.__init__ |
||||||
|
%SPHINXBUILD% 2> nul |
||||||
|
if errorlevel 9009 ( |
||||||
|
echo. |
||||||
|
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx |
||||||
|
echo.installed, then set the SPHINXBUILD environment variable to point |
||||||
|
echo.to the full path of the 'sphinx-build' executable. Alternatively you |
||||||
|
echo.may add the Sphinx directory to PATH. |
||||||
|
echo. |
||||||
|
echo.If you don't have Sphinx installed, grab it from |
||||||
|
echo.http://sphinx-doc.org/ |
||||||
|
exit /b 1 |
||||||
|
) |
||||||
|
|
||||||
|
:sphinx_ok |
||||||
|
|
||||||
|
|
||||||
|
if "%1" == "html" ( |
||||||
|
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The HTML pages are in %BUILDDIR%/html. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "dirhtml" ( |
||||||
|
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "singlehtml" ( |
||||||
|
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "pickle" ( |
||||||
|
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished; now you can process the pickle files. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "json" ( |
||||||
|
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished; now you can process the JSON files. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "htmlhelp" ( |
||||||
|
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished; now you can run HTML Help Workshop with the ^ |
||||||
|
.hhp project file in %BUILDDIR%/htmlhelp. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "qthelp" ( |
||||||
|
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished; now you can run "qcollectiongenerator" with the ^ |
||||||
|
.qhcp project file in %BUILDDIR%/qthelp, like this: |
||||||
|
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\BasisHR.qhcp |
||||||
|
echo.To view the help file: |
||||||
|
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\BasisHR.ghc |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "devhelp" ( |
||||||
|
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "epub" ( |
||||||
|
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The epub file is in %BUILDDIR%/epub. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "epub3" ( |
||||||
|
%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "latex" ( |
||||||
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "latexpdf" ( |
||||||
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex |
||||||
|
cd %BUILDDIR%/latex |
||||||
|
make all-pdf |
||||||
|
cd %~dp0 |
||||||
|
echo. |
||||||
|
echo.Build finished; the PDF files are in %BUILDDIR%/latex. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "latexpdfja" ( |
||||||
|
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex |
||||||
|
cd %BUILDDIR%/latex |
||||||
|
make all-pdf-ja |
||||||
|
cd %~dp0 |
||||||
|
echo. |
||||||
|
echo.Build finished; the PDF files are in %BUILDDIR%/latex. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "text" ( |
||||||
|
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The text files are in %BUILDDIR%/text. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "man" ( |
||||||
|
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The manual pages are in %BUILDDIR%/man. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "texinfo" ( |
||||||
|
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "gettext" ( |
||||||
|
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The message catalogs are in %BUILDDIR%/locale. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "changes" ( |
||||||
|
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.The overview file is in %BUILDDIR%/changes. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "linkcheck" ( |
||||||
|
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Link check complete; look for any errors in the above output ^ |
||||||
|
or in %BUILDDIR%/linkcheck/output.txt. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "doctest" ( |
||||||
|
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Testing of doctests in the sources finished, look at the ^ |
||||||
|
results in %BUILDDIR%/doctest/output.txt. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "coverage" ( |
||||||
|
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Testing of coverage in the sources finished, look at the ^ |
||||||
|
results in %BUILDDIR%/coverage/python.txt. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "xml" ( |
||||||
|
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The XML files are in %BUILDDIR%/xml. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
if "%1" == "pseudoxml" ( |
||||||
|
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml |
||||||
|
if errorlevel 1 exit /b 1 |
||||||
|
echo. |
||||||
|
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. |
||||||
|
goto end |
||||||
|
) |
||||||
|
|
||||||
|
:end |
@ -0,0 +1,3 @@ |
|||||||
|
sphinx |
||||||
|
sphinx_rtd_theme |
||||||
|
git+https://github.com/develmaycare/sphinx-helpers |
@ -0,0 +1,440 @@ |
|||||||
|
apache.disable_module |
||||||
|
..................... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[disable an apache module] |
||||||
|
apache.disable_module = module_name |
||||||
|
|
||||||
|
apache.disable_site |
||||||
|
................... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[disable a virtual host] |
||||||
|
apache.disable_site = domain_name |
||||||
|
|
||||||
|
apache.enable_module |
||||||
|
.................... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[enable an apache module] |
||||||
|
apache.enable_module = module_name |
||||||
|
|
||||||
|
apache.enable_site |
||||||
|
.................. |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[enable a virtual host] |
||||||
|
apache.enable_site = domain_name |
||||||
|
|
||||||
|
apache.test |
||||||
|
........... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[run an apache config test] |
||||||
|
apache: test |
||||||
|
|
||||||
|
append |
||||||
|
...... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[append to a file] |
||||||
|
append = path |
||||||
|
content = None |
||||||
|
|
||||||
|
archive |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create an archive file] |
||||||
|
archive = from_path |
||||||
|
absolute = False |
||||||
|
exclude = None |
||||||
|
file_name = archive.tgz |
||||||
|
strip = 0 |
||||||
|
to_path = . |
||||||
|
view = False |
||||||
|
|
||||||
|
certbot |
||||||
|
....... |
||||||
|
|
||||||
|
Alias: ssl |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[get new ssl certificate from let's encrypt] |
||||||
|
certbot = domain_name |
||||||
|
email = None |
||||||
|
webroot = None |
||||||
|
|
||||||
|
copy |
||||||
|
.... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[copy a file or directory] |
||||||
|
copy = from_path to_path |
||||||
|
overwrite = False |
||||||
|
recursive = False |
||||||
|
|
||||||
|
django |
||||||
|
...... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[run a django management command] |
||||||
|
django = name |
||||||
|
|
||||||
|
django.dumpdata |
||||||
|
............... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[export django fixtures] |
||||||
|
django.dumpdata = app_name |
||||||
|
file_name = initial |
||||||
|
indent = 4 |
||||||
|
natural_foreign = False |
||||||
|
natural_primary = False |
||||||
|
path = None |
||||||
|
|
||||||
|
django.loaddata |
||||||
|
............... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[load django fixtures] |
||||||
|
django.loaddata = app_name |
||||||
|
file_name = initial |
||||||
|
path = None |
||||||
|
|
||||||
|
extract |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[extract an archive] |
||||||
|
extract = from_path |
||||||
|
absolute = False |
||||||
|
exclude = None |
||||||
|
file_name = archive.tgz |
||||||
|
strip = 0 |
||||||
|
to_path = None |
||||||
|
view = False |
||||||
|
|
||||||
|
install |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[install a package using apt-get] |
||||||
|
apt = package |
||||||
|
remove = False |
||||||
|
|
||||||
|
makedir |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a directory] |
||||||
|
makedir = path |
||||||
|
mode = None |
||||||
|
recursive = True |
||||||
|
|
||||||
|
message |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[run a message command] |
||||||
|
message = output |
||||||
|
back_title = Message |
||||||
|
dialog = False |
||||||
|
height = 15 |
||||||
|
width = 100 |
||||||
|
|
||||||
|
mkdir |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a directory] |
||||||
|
mkdir = path |
||||||
|
mode = None |
||||||
|
recursive = True |
||||||
|
|
||||||
|
move |
||||||
|
.... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[move a file or directory] |
||||||
|
move = from_path to_path |
||||||
|
|
||||||
|
perms |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[set permissions on a file or directory] |
||||||
|
perms = path |
||||||
|
group = None |
||||||
|
mode = None |
||||||
|
owner = None |
||||||
|
recursive = False |
||||||
|
|
||||||
|
pg.createdb |
||||||
|
........... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a postgresql database] |
||||||
|
pg.createdb = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
host = localhost |
||||||
|
owner = None |
||||||
|
port = 5432 |
||||||
|
template = None |
||||||
|
|
||||||
|
pg.createuser |
||||||
|
............. |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a postgresql user] |
||||||
|
pg.createuser = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
host = localhost |
||||||
|
password = None |
||||||
|
port = 5432 |
||||||
|
|
||||||
|
pg.db |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a postgresql database] |
||||||
|
pg.db = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
host = localhost |
||||||
|
owner = None |
||||||
|
port = 5432 |
||||||
|
template = None |
||||||
|
|
||||||
|
pg.dropdb |
||||||
|
......... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[remove a postgresql database] |
||||||
|
pg.dropdb = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
host = localhost |
||||||
|
port = 5432 |
||||||
|
|
||||||
|
pg.dropuser |
||||||
|
........... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[remove a postgres user] |
||||||
|
pg.dropuser = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
host = localhost |
||||||
|
port = 5432 |
||||||
|
|
||||||
|
pg.dump |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[export a postgres database] |
||||||
|
pg.dump = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
file_name = None |
||||||
|
host = localhost |
||||||
|
port = 5432 |
||||||
|
|
||||||
|
pg.exists |
||||||
|
......... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[determine if a postgres database exists] |
||||||
|
pg.exists = name |
||||||
|
admin_pass = None |
||||||
|
admin_user = postgres |
||||||
|
host = localhost |
||||||
|
port = 5432 |
||||||
|
|
||||||
|
pip |
||||||
|
... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[install a python package using pip] |
||||||
|
pip = package |
||||||
|
remove = False |
||||||
|
upgrade = False |
||||||
|
|
||||||
|
psql |
||||||
|
.... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[execute a psql command] |
||||||
|
psql = sql |
||||||
|
database = template1 |
||||||
|
host = localhost |
||||||
|
password = None |
||||||
|
port = 5432 |
||||||
|
user = postgres |
||||||
|
|
||||||
|
reload |
||||||
|
...... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[reload a service] |
||||||
|
reload = service |
||||||
|
|
||||||
|
remove |
||||||
|
...... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[remove a file or directory] |
||||||
|
remove = path |
||||||
|
force = False |
||||||
|
recursive = False |
||||||
|
|
||||||
|
restart |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[restart a service] |
||||||
|
restart = service |
||||||
|
|
||||||
|
rsync |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[synchronize files from a local to remote directory] |
||||||
|
rsync = source target |
||||||
|
delete = False |
||||||
|
guess = False |
||||||
|
host = None |
||||||
|
key_file = None |
||||||
|
links = True |
||||||
|
port = 22 |
||||||
|
recursive = True |
||||||
|
user = None |
||||||
|
|
||||||
|
run |
||||||
|
... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[a command to be executed] |
||||||
|
run = statement |
||||||
|
comment = None |
||||||
|
condition = None |
||||||
|
cd = None |
||||||
|
environments = None |
||||||
|
function = None |
||||||
|
prefix = None |
||||||
|
register = None |
||||||
|
shell = None |
||||||
|
stop = False |
||||||
|
sudo = None |
||||||
|
tags = None |
||||||
|
|
||||||
|
scopy |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[copy a file from the local (machine) to the remote host] |
||||||
|
scp = from_path to_path |
||||||
|
host = None |
||||||
|
key_file = None |
||||||
|
port = 22 |
||||||
|
user = None |
||||||
|
|
||||||
|
sed |
||||||
|
... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[replace text in a file] |
||||||
|
sed = path |
||||||
|
backup = .b |
||||||
|
change = None |
||||||
|
delimiter = / |
||||||
|
find = None |
||||||
|
|
||||||
|
start |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[start a service] |
||||||
|
start = service |
||||||
|
|
||||||
|
stop |
||||||
|
.... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[stop a service] |
||||||
|
stop = service |
||||||
|
|
||||||
|
symlink |
||||||
|
....... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a symlink] |
||||||
|
symlink = source |
||||||
|
force = False |
||||||
|
target = None |
||||||
|
|
||||||
|
touch |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[touch a file or directory] |
||||||
|
touch = path |
||||||
|
|
||||||
|
virtualenv |
||||||
|
.......... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[create a python virtual environment] |
||||||
|
virtualenv = name |
||||||
|
|
||||||
|
write |
||||||
|
..... |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[write to a file] |
||||||
|
write = path |
||||||
|
content = None |
||||||
|
overwrite = False |
unable to load file from base commit
|
@ -0,0 +1,10 @@ |
|||||||
|
/* override table width restrictions */ |
||||||
|
.wy-table-responsive table td, .wy-table-responsive table th { |
||||||
|
white-space: normal; |
||||||
|
} |
||||||
|
|
||||||
|
.wy-table-responsive { |
||||||
|
margin-bottom: 24px; |
||||||
|
max-width: 100%; |
||||||
|
overflow: visible; |
||||||
|
} |
After Width: | Height: | Size: 301 KiB |
After Width: | Height: | Size: 393 KiB |
After Width: | Height: | Size: 33 KiB |
@ -0,0 +1,243 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
# |
||||||
|
# Script Tease documentation build configuration file, created by |
||||||
|
# sphinx-quickstart on Mon Apr 11 17:36:02 2016. |
||||||
|
# |
||||||
|
# This file is execfile()d with the current directory set to its |
||||||
|
# containing dir. |
||||||
|
# |
||||||
|
# Note that not all possible configuration values are present in this |
||||||
|
# autogenerated file. |
||||||
|
# |
||||||
|
# All configuration values have a default; values that are commented out |
||||||
|
# serve to show the default. |
||||||
|
import os |
||||||
|
from sphinx_helpers import get_release, get_version |
||||||
|
import sys |
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory, |
||||||
|
# add these directories to sys.path here. If the directory is relative to the |
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here. |
||||||
|
sys.path.insert(0, os.path.abspath("../../")) |
||||||
|
|
||||||
|
# -- General configuration ------------------------------------------------ |
||||||
|
|
||||||
|
# If your documentation needs a minimal Sphinx version, state it here. |
||||||
|
#needs_sphinx = '1.0' |
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be |
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom |
||||||
|
# ones. |
||||||
|
extensions = [ |
||||||
|
'sphinx.ext.autodoc', |
||||||
|
'sphinx.ext.intersphinx', |
||||||
|
'sphinx.ext.todo', |
||||||
|
'sphinx.ext.coverage', |
||||||
|
'sphinx.ext.ifconfig', |
||||||
|
'sphinx.ext.viewcode', |
||||||
|
] |
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory. |
||||||
|
templates_path = ['_templates'] |
||||||
|
|
||||||
|
# The suffix(es) of source filenames. |
||||||
|
# You can specify multiple suffix as a list of string: |
||||||
|
# source_suffix = ['.rst', '.md'] |
||||||
|
source_suffix = '.rst' |
||||||
|
|
||||||
|
# The encoding of source files. |
||||||
|
#source_encoding = 'utf-8-sig' |
||||||
|
|
||||||
|
# The master toctree document. |
||||||
|
master_doc = 'index' |
||||||
|
|
||||||
|
# General information about the project. |
||||||
|
project = u'Script Tease (Python)' |
||||||
|
copyright = u'Pleasant Tents, LLC' |
||||||
|
author = u'Shawn Davis' |
||||||
|
|
||||||
|
# The version info for the project you're documenting, acts as replacement for |
||||||
|
# |version| and |release|, also used in various other places throughout the |
||||||
|
# built documents. |
||||||
|
# |
||||||
|
# The short X.Y version. |
||||||
|
version = get_version("../../VERSION.txt") |
||||||
|
|
||||||
|
# The full version, including alpha/beta/rc tags. |
||||||
|
release = get_release("../../VERSION.txt") |
||||||
|
|
||||||
|
# The language for content autogenerated by Sphinx. Refer to documentation |
||||||
|
# for a list of supported languages. |
||||||
|
# |
||||||
|
# This is also used if you do content translation via gettext catalogs. |
||||||
|
# Usually you set "language" from the command line for these cases. |
||||||
|
language = None |
||||||
|
|
||||||
|
# There are two options for replacing |today|: either, you set today to some |
||||||
|
# non-false value, then it is used: |
||||||
|
#today = '' |
||||||
|
# Else, today_fmt is used as the format for a strftime call. |
||||||
|
#today_fmt = '%B %d, %Y' |
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and |
||||||
|
# directories to ignore when looking for source files. |
||||||
|
# This patterns also effect to html_static_path and html_extra_path |
||||||
|
exclude_patterns = [] |
||||||
|
|
||||||
|
# The reST default role (used for this markup: `text`) to use for all |
||||||
|
# documents. |
||||||
|
#default_role = None |
||||||
|
|
||||||
|
# If true, '()' will be appended to :func: etc. cross-reference text. |
||||||
|
#add_function_parentheses = True |
||||||
|
|
||||||
|
# If true, the current module name will be prepended to all description |
||||||
|
# unit titles (such as .. function::). |
||||||
|
#add_module_names = True |
||||||
|
|
||||||
|
# If true, sectionauthor and moduleauthor directives will be shown in the |
||||||
|
# output. They are ignored by default. |
||||||
|
#show_authors = False |
||||||
|
|
||||||
|
# The name of the Pygments (syntax highlighting) style to use. |
||||||
|
pygments_style = 'sphinx' |
||||||
|
|
||||||
|
# A list of ignored prefixes for module index sorting. |
||||||
|
#modindex_common_prefix = [] |
||||||
|
|
||||||
|
# If true, keep warnings as "system message" paragraphs in the built documents. |
||||||
|
#keep_warnings = False |
||||||
|
|
||||||
|
# If true, `todo` and `todoList` produce output, else they produce nothing. |
||||||
|
todo_include_todos = True |
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output ---------------------------------------------- |
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for |
||||||
|
# a list of builtin themes. |
||||||
|
# html_theme = 'alabaster' |
||||||
|
|
||||||
|
# Theme options are theme-specific and customize the look and feel of a theme |
||||||
|
# further. For a list of options available for each theme, see the |
||||||
|
# documentation. |
||||||
|
#html_theme_options = {} |
||||||
|
|
||||||
|
# Add any paths that contain custom themes here, relative to this directory. |
||||||
|
#html_theme_path = [] |
||||||
|
|
||||||
|
# The name for this set of Sphinx documents. |
||||||
|
# "<project> v<release> documentation" by default. |
||||||
|
#html_title = u'Ninjas v%s' % version |
||||||
|
|
||||||
|
# A shorter title for the navigation bar. Default is the same as html_title. |
||||||
|
#html_short_title = None |
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to place at the top |
||||||
|
# of the sidebar. |
||||||
|
#html_logo = None |
||||||
|
|
||||||
|
# The name of an image file (relative to this directory) to use as a favicon of |
||||||
|
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
||||||
|
# pixels large. |
||||||
|
#html_favicon = None |
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here, |
||||||
|
# relative to this directory. They are copied after the builtin static files, |
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css". |
||||||
|
html_static_path = ['_static'] |
||||||
|
|
||||||
|
|
||||||
|
def setup(app): |
||||||
|
# Some csv-table tables in the RTD theme were scrolling horizontally. |
||||||
|
# See https://github.com/snide/sphinx_rtd_theme/issues/117 |
||||||
|
# Apparently the placement of this function is significant. It wasn't |
||||||
|
# working at the end of the file. |
||||||
|
# See https://github.com/syncany/syncany-docs/blob/82166518720051e413231d621c3b23b9ac35cbf6/source/conf.py#L135 |
||||||
|
# app.add_javascript("js/custom.js") |
||||||
|
app.add_stylesheet("css/custom.css") |
||||||
|
|
||||||
|
# Add any extra paths that contain custom files (such as robots.txt or |
||||||
|
# .htaccess) here, relative to this directory. These files are copied |
||||||
|
# directly to the root of the documentation. |
||||||
|
#html_extra_path = [] |
||||||
|
|
||||||
|
# If not None, a 'Last updated on:' timestamp is inserted at every page |
||||||
|
# bottom, using the given strftime format. |
||||||
|
# The empty string is equivalent to '%b %d, %Y'. |
||||||
|
#html_last_updated_fmt = None |
||||||
|
|
||||||
|
# If true, SmartyPants will be used to convert quotes and dashes to |
||||||
|
# typographically correct entities. |
||||||
|
#html_use_smartypants = True |
||||||
|
|
||||||
|
# Custom sidebar templates, maps document names to template names. |
||||||
|
#html_sidebars = {} |
||||||
|
|
||||||
|
# Additional templates that should be rendered to pages, maps page names to |
||||||
|
# template names. |
||||||
|
#html_additional_pages = {} |
||||||
|
|
||||||
|
# If false, no module index is generated. |
||||||
|
#html_domain_indices = True |
||||||
|
|
||||||
|
# If false, no index is generated. |
||||||
|
#html_use_index = True |
||||||
|
|
||||||
|
# If true, the index is split into individual pages for each letter. |
||||||
|
#html_split_index = False |
||||||
|
|
||||||
|
# If true, links to the reST sources are added to the pages. |
||||||
|
#html_show_sourcelink = True |
||||||
|
|
||||||
|
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
||||||
|
#html_show_sphinx = True |
||||||
|
|
||||||
|
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
||||||
|
#html_show_copyright = True |
||||||
|
|
||||||
|
# If true, an OpenSearch description file will be output, and all pages will |
||||||
|
# contain a <link> tag referring to it. The value of this option must be the |
||||||
|
# base URL from which the finished HTML is served. |
||||||
|
#html_use_opensearch = '' |
||||||
|
|
||||||
|
# This is the file name suffix for HTML files (e.g. ".xhtml"). |
||||||
|
#html_file_suffix = None |
||||||
|
|
||||||
|
# Language to be used for generating the HTML full-text search index. |
||||||
|
# Sphinx supports the following languages: |
||||||
|
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' |
||||||
|
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' |
||||||
|
#html_search_language = 'en' |
||||||
|
|
||||||
|
# A dictionary with options for the search language support, empty by default. |
||||||
|
# 'ja' uses this config value. |
||||||
|
# 'zh' user can custom change `jieba` dictionary path. |
||||||
|
#html_search_options = {'type': 'default'} |
||||||
|
|
||||||
|
# The name of a javascript file (relative to the configuration directory) that |
||||||
|
# implements a search results scorer. If empty, the default will be used. |
||||||
|
#html_search_scorer = 'scorer.js' |
||||||
|
|
||||||
|
# Output file base name for HTML help builder. |
||||||
|
htmlhelp_basename = 'ScriptTeaseDoc' |
||||||
|
|
||||||
|
# -- Options for manual page output --------------------------------------- |
||||||
|
|
||||||
|
# One entry per manual page. List of tuples |
||||||
|
# (source start file, name, description, authors, manual section). |
||||||
|
man_pages = [ |
||||||
|
(master_doc, 'script_tease', u'Script Tease Documentation', |
||||||
|
[author], 1) |
||||||
|
] |
||||||
|
|
||||||
|
# If true, show URL addresses after external links. |
||||||
|
#man_show_urls = False |
||||||
|
|
||||||
|
# Example configuration for intersphinx: refer to the Python standard library. |
||||||
|
intersphinx_mapping = {'https://docs.python.org/': None} |
||||||
|
|
||||||
|
# Read the Docs Theme |
||||||
|
import sphinx_rtd_theme |
||||||
|
html_theme = "sphinx_rtd_theme" |
||||||
|
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] |
@ -0,0 +1,166 @@ |
|||||||
|
.. _configuration: |
||||||
|
|
||||||
|
************* |
||||||
|
Configuration |
||||||
|
************* |
||||||
|
|
||||||
|
Generating Commands From a File |
||||||
|
=============================== |
||||||
|
|
||||||
|
The :py:class:`scripttease.parsers.ini.Config` class may instantiate commands by loading a configuration file. |
||||||
|
|
||||||
|
.. note:: |
||||||
|
Additional formats such as JSON or YAML may be supported in the future. |
||||||
|
|
||||||
|
An example file: |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[install apache] |
||||||
|
install: apache2 |
||||||
|
|
||||||
|
[create the web site directory] |
||||||
|
mkdir: /var/www/domains/example_com/www |
||||||
|
recursive: yes |
||||||
|
|
||||||
|
[set permissions on the website directory] |
||||||
|
perms: /var/www/domains/example_com/www |
||||||
|
group: www-data |
||||||
|
mode: 775 |
||||||
|
owner: www-data |
||||||
|
|
||||||
|
Notes regarding this format: |
||||||
|
|
||||||
|
- This is the standard format for Python's ConfigParser. If you prefer, you may use ``=`` instead of ``:``. |
||||||
|
- The first line is the INI section and is used as the default comment. |
||||||
|
- The command name must be the *first* option in the section. |
||||||
|
- The arguments for the command appear as the value of the first option in the section. Arguments are separated by a |
||||||
|
space. |
||||||
|
- Arguments that should be treated as a single value should be enclosed in double quotes. |
||||||
|
- ``yes`` and ``no`` are interpreted as boolean values. |
||||||
|
- List values, where required, are separated by commas. |
||||||
|
|
||||||
|
Common Parameters |
||||||
|
----------------- |
||||||
|
|
||||||
|
All commands support the following common parameters: |
||||||
|
|
||||||
|
- ``comment``: A comment regarding the command. |
||||||
|
- ``condition``: A condition for execution. For example, ``! -f /path/to/some/file.txt`` |
||||||
|
- ``cd``: The path from which a command should be executed. |
||||||
|
- ``environments``: A string or list of strings indicating the operational environments in which the command runs. This |
||||||
|
is *not* used by default, but may be used to programmatically filter commands for a specific environment. For example, |
||||||
|
development versus live. |
||||||
|
- ``prefix``: A statement to be added prior to executing the command. |
||||||
|
- ``register``: A variable name to which the the success or failure (exit code) of the statement is captured. |
||||||
|
- ``shell``: The shell used to run the commands. For example, ``/bin/bash``. This is generally not important, but can |
||||||
|
be a problem when attempting to execute some commands (such as Django management commands). |
||||||
|
- ``stop``: ``True`` indicates no other commands should be executed if the given command fails. |
||||||
|
- ``sudo``: ``True`` indicates the command should be automatically prefixed with ``sudo``. If provided as a string, the |
||||||
|
command is also prefixed with a specific user name. |
||||||
|
- ``tags``: A list of tags used to classify the command. |
||||||
|
|
||||||
|
Defining an "Itemized" Command |
||||||
|
------------------------------ |
||||||
|
|
||||||
|
Certain command definitions may be repeated by defining a list of items. |
||||||
|
|
||||||
|
Example of an "itemized" command: |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[touch a bunch of files] |
||||||
|
touch = /var/www/domains/example_com/www/$item |
||||||
|
items = index.html, assets/index.html, content/index.html |
||||||
|
|
||||||
|
.. note:: |
||||||
|
Command itemization may vary with the command type. |
||||||
|
|
||||||
|
Available Commands |
||||||
|
------------------ |
||||||
|
|
||||||
|
The following commands instantiate command instances. Each example is shown with the defaults. |
||||||
|
|
||||||
|
.. include:: _command-examples.rst |
||||||
|
|
||||||
|
Pre-Parsing Command Files as Templates |
||||||
|
====================================== |
||||||
|
|
||||||
|
Configuration file may be pre-processed as a Jinja2 template by providing a context dictionary: |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[install apache] |
||||||
|
install: apache |
||||||
|
|
||||||
|
[create the website directory] |
||||||
|
mkdir: /var/www/domains/{{ domain_tld }}/www |
||||||
|
recursive: yes |
||||||
|
|
||||||
|
[set permissions on the website directory] |
||||||
|
perms: /var/www/domains/{{ domain_tld }}/www |
||||||
|
group: www-data |
||||||
|
mode: 775 |
||||||
|
owner: www-data |
||||||
|
|
||||||
|
Then with a config instance: |
||||||
|
|
||||||
|
.. code-block:: python |
||||||
|
|
||||||
|
context = { |
||||||
|
'domain_tld': "example_com", |
||||||
|
} |
||||||
|
|
||||||
|
config = Config("commands.ini", context=context) |
||||||
|
config.load() |
||||||
|
|
||||||
|
for command in config.get_commands(): |
||||||
|
print(command.get_statement(cd=True)) |
||||||
|
print("") |
||||||
|
|
||||||
|
Using the Tease Command |
||||||
|
======================= |
||||||
|
|
||||||
|
The ``tease`` command may be used to parse a configuration file, providing additional utilities for working with |
||||||
|
commands. |
||||||
|
|
||||||
|
.. code-block:: text |
||||||
|
|
||||||
|
positional arguments: |
||||||
|
path The path to the configuration file. |
||||||
|
|
||||||
|
optional arguments: |
||||||
|
-h, --help show this help message and exit |
||||||
|
-c, --color Enable code highlighting for terminal output. |
||||||
|
-C= VARIABLES, --context= VARIABLES |
||||||
|
Context variables for use in pre-parsing the config and templates. In the form of: name:value |
||||||
|
-d, --docs Output documentation instead of code. |
||||||
|
-D, --debug Enable debug output. |
||||||
|
-f= FILTERS, --filter= FILTERS |
||||||
|
Filter the commands in the form of: attribute:value |
||||||
|
-O= OPTIONS, --option= OPTIONS |
||||||
|
Common command options in the form of: name:value |
||||||
|
-s, --script Output commands as a script. |
||||||
|
-T= TEMPLATE_LOCATIONS, --template-path= TEMPLATE_LOCATIONS |
||||||
|
The location of template files that may be used with the template command. |
||||||
|
-w= OUTPUT_FILE, --write= OUTPUT_FILE |
||||||
|
Write the output to disk. |
||||||
|
-V= VARIABLES_FILE, --variables-file= VARIABLES_FILE |
||||||
|
Load variables from a file. |
||||||
|
-v Show version number and exit. |
||||||
|
--version Show verbose version information and exit. |
||||||
|
|
||||||
|
The ``path`` argument defaults to ``commands.ini``. |
||||||
|
|
||||||
|
Loading Variables from a File |
||||||
|
----------------------------- |
||||||
|
|
||||||
|
Context variables may be loaded from a file: |
||||||
|
|
||||||
|
.. code-block:: ini |
||||||
|
|
||||||
|
[domain] |
||||||
|
name = example.com |
||||||
|
tld = example_com |
||||||
|
|
||||||
|
The variables above are available as ``section_key``. For example, ``domain_name`` is ``example.com``. |
@ -0,0 +1,110 @@ |
|||||||
|
.. _developer-reference: |
||||||
|
|
||||||
|
******************* |
||||||
|
Developer Reference |
||||||
|
******************* |
||||||
|
|
||||||
|
Constants |
||||||
|
========= |
||||||
|
|
||||||
|
.. automodule:: scripttease.constants |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Library |
||||||
|
======= |
||||||
|
|
||||||
|
Commands |
||||||
|
-------- |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.commands.base |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Overlays |
||||||
|
-------- |
||||||
|
|
||||||
|
Common |
||||||
|
...... |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.overlays.common |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Django |
||||||
|
...... |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.overlays.django |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Postgres |
||||||
|
........ |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.overlays.pgsql |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Posix |
||||||
|
..... |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.overlays.posix |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Ubuntu |
||||||
|
...... |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.overlays.ubuntu |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Scripts |
||||||
|
------- |
||||||
|
|
||||||
|
.. automodule:: scripttease.library.scripts |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Factory |
||||||
|
======= |
||||||
|
|
||||||
|
.. automodule:: scripttease.factory |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Parsers |
||||||
|
======= |
||||||
|
|
||||||
|
Base |
||||||
|
---- |
||||||
|
|
||||||
|
.. automodule:: scripttease.parsers.base |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Config (INI) |
||||||
|
------------ |
||||||
|
|
||||||
|
.. automodule:: scripttease.parsers.ini |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
||||||
|
|
||||||
|
Utils |
||||||
|
----- |
||||||
|
|
||||||
|
.. automodule:: scripttease.parsers.utils |
||||||
|
:members: |
||||||
|
:show-inheritance: |
||||||
|
:special-members: __init__ |
@ -0,0 +1,17 @@ |
|||||||
|
Python Script Tease |
||||||
|
=================== |
||||||
|
|
||||||
|
.. toctree:: |
||||||
|
:maxdepth: 2 |
||||||
|
|
||||||
|
Introduction <introduction> |
||||||
|
Configuration <configuration> |
||||||
|
Developer Reference <developer> |
||||||
|
Tests <tests> |
||||||
|
|
||||||
|
Indices and tables |
||||||
|
================== |
||||||
|
|
||||||
|
* :ref:`genindex` |
||||||
|
* :ref:`modindex` |
||||||
|
* :ref:`search` |
@ -0,0 +1,27 @@ |
|||||||
|
.. _introduction: |
||||||
|
|
||||||
|
************ |
||||||
|
Introduction |
||||||
|
************ |
||||||
|
|
||||||
|
Script Tease is a library and command line tool for generating commands programmatically or using configuration files. |
||||||
|
|
||||||
|
Concepts |
||||||
|
======== |
||||||
|
|
||||||
|
Generating Commands |
||||||
|
------------------- |
||||||
|
|
||||||
|
Script Tease may be used in two (2) ways: |
||||||
|
|
||||||
|
1. Using the library to programmatically define commands and export them as command line statements. See |
||||||
|
:ref:`developer-reference`. |
||||||
|
2. Using the ``tease`` command to generate commands from a configuration file. See :ref:`configuration`. |
||||||
|
|
||||||
|
Overlays |
||||||
|
-------- |
||||||
|
|
||||||
|
An *overlay* is a set of command meta functions that define the capabilities of a specific operating system. |
||||||
|
|
||||||
|
.. note:: |
||||||
|
At present, the only fully defined overlay is for Ubuntu. |
@ -0,0 +1,54 @@ |
|||||||
|
***** |
||||||
|
Tests |
||||||
|
***** |
||||||
|
|
||||||
|
Coverage Requirements |
||||||
|
===================== |
||||||
|
|
||||||
|
100% coverage is required for the ``master`` branch. |
||||||
|
|
||||||
|
See `current coverage report <coverage/index.html>`_. |
||||||
|
|
||||||
|
.. csv-table:: Lines of Code |
||||||
|
:file: _data/cloc.csv |
||||||
|
|
||||||
|
Set Up for Testing |
||||||
|
================== |
||||||
|
|
||||||
|
Install requirements: |
||||||
|
|
||||||
|
.. code-block:: bash |
||||||
|
|
||||||
|
pip install tests/requirements.pip |
||||||
|
|
||||||
|
Running Tests |
||||||
|
============= |
||||||
|
|
||||||
|
.. tip:: |
||||||
|
You may use the ``tests`` target of the ``Makefile`` to run tests with coverage: |
||||||
|
|
||||||
|
``make tests;`` |
||||||
|
|
||||||
|
To run unit tests: |
||||||
|
|
||||||
|
.. code-block:: bash |
||||||
|
|
||||||
|
python -m pytest; |
||||||
|
|
||||||
|
Run a specific test: |
||||||
|
|
||||||
|
.. code-block:: bash |
||||||
|
|
||||||
|
python -m pytest tests/units/path/to/test.py |
||||||
|
|
||||||
|
To allow output from print statements within a test method, add the ``-s`` switch: |
||||||
|
|
||||||
|
.. code-block:: bash |
||||||
|
|
||||||
|
python -m pytest -s tests/units/path/to/test.py |
||||||
|
|
||||||
|
Reference |
||||||
|
========= |
||||||
|
|
||||||
|
- `coverage <https://coverage.readthedocs.io/en/v4.5.x/>`_ |
||||||
|
- `pytest <https://pytest.org>`_ |
@ -0,0 +1,12 @@ |
|||||||
|
#! /usr/bin/env python |
||||||
|
|
||||||
|
import re |
||||||
|
import sys |
||||||
|
|
||||||
|
sys.path.insert(0, "../") |
||||||
|
|
||||||
|
from scripttease.cli import main_command |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) |
||||||
|
sys.exit(main_command()) |
@ -0,0 +1,204 @@ |
|||||||
|
# Imports |
||||||
|
|
||||||
|
from argparse import ArgumentParser, RawDescriptionHelpFormatter |
||||||
|
from superpython.logging import LoggingHelper |
||||||
|
from ..constants import LOGGER_NAME |
||||||
|
from . import initialize |
||||||
|
from . import subcommands |
||||||
|
|
||||||
|
DEBUG = 10 |
||||||
|
|
||||||
|
logging = LoggingHelper(colorize=True, name=LOGGER_NAME) |
||||||
|
log = logging.setup() |
||||||
|
|
||||||
|
# Commands |
||||||
|
|
||||||
|
|
||||||
|
def main_command(): |
||||||
|
"""Process script configurations.""" |
||||||
|
|
||||||
|
__author__ = "Shawn Davis <shawn@develmaycare.com>" |
||||||
|
__date__ = "2020-07-21" |
||||||
|
__help__ = """NOTES |
||||||
|
|
||||||
|
This command is used to parse configuration files and output the commands. |
||||||
|
|
||||||
|
""" |
||||||
|
__version__ = "0.10.0-d" |
||||||
|
|
||||||
|
# Main argument parser from which sub-commands are created. |
||||||
|
parser = ArgumentParser(description=__doc__, epilog=__help__, formatter_class=RawDescriptionHelpFormatter) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"path", |
||||||
|
default="commands.ini", |
||||||
|
nargs="?", |
||||||
|
help="The path to the configuration file." |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-c", |
||||||
|
"--color", |
||||||
|
action="store_true", |
||||||
|
dest="color_enabled", |
||||||
|
help="Enable code highlighting for terminal output." |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-C=", |
||||||
|
"--context=", |
||||||
|
action="append", |
||||||
|
dest="variables", |
||||||
|
help="Context variables for use in pre-parsing the config and templates. In the form of: name:value" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-d", |
||||||
|
"--docs", |
||||||
|
action="store_true", |
||||||
|
dest="docs_enabled", |
||||||
|
help="Output documentation instead of code." |
||||||
|
) |
||||||
|
|
||||||
|
# parser.add_argument( |
||||||
|
# "-d=", |
||||||
|
# "--docs=", |
||||||
|
# choices=["html", "markdown", "plain", "rst"], |
||||||
|
# dest="docs_enabled", |
||||||
|
# help="Output documentation instead of code." |
||||||
|
# ) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-D", |
||||||
|
"--debug", |
||||||
|
action="store_true", |
||||||
|
dest="debug_enabled", |
||||||
|
help="Enable debug output." |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-f=", |
||||||
|
"--filter=", |
||||||
|
action="append", |
||||||
|
dest="filters", |
||||||
|
help="Filter the commands in the form of: attribute:value" |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-O=", |
||||||
|
"--option=", |
||||||
|
action="append", |
||||||
|
dest="options", |
||||||
|
help="Common command options in the form of: name:value" |
||||||
|
) |
||||||
|
|
||||||
|
# parser.add_argument( |
||||||
|
# "-O=", |
||||||
|
# "--output=", |
||||||
|
# # default=os.path.join("prototype", "output"), |
||||||
|
# dest="output_path", |
||||||
|
# help="Output to the given directory. Defaults to ./prototype/output/" |
||||||
|
# ) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-s", |
||||||
|
"--script", |
||||||
|
action="store_true", |
||||||
|
dest="script_enabled", |
||||||
|
help="Output commands as a script." |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-T=", |
||||||
|
"--template-path=", |
||||||
|
action="append", |
||||||
|
dest="template_locations", |
||||||
|
help="The location of template files that may be used with the template command." |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-w=", |
||||||
|
"--write=", |
||||||
|
dest="output_file", |
||||||
|
help="Write the output to disk." |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"-V=", |
||||||
|
"--variables-file=", |
||||||
|
dest="variables_file", |
||||||
|
help="Load variables from a file." |
||||||
|
) |
||||||
|
|
||||||
|
# Access to the version number requires special consideration, especially |
||||||
|
# when using sub parsers. The Python 3.3 behavior is different. See this |
||||||
|
# answer: http://stackoverflow.com/questions/8521612/argparse-optional-subparser-for-version |
||||||
|
parser.add_argument( |
||||||
|
"-v", |
||||||
|
action="version", |
||||||
|
help="Show version number and exit.", |
||||||
|
version=__version__ |
||||||
|
) |
||||||
|
|
||||||
|
parser.add_argument( |
||||||
|
"--version", |
||||||
|
action="version", |
||||||
|
help="Show verbose version information and exit.", |
||||||
|
version="%(prog)s" + " %s %s by %s" % (__version__, __date__, __author__) |
||||||
|
) |
||||||
|
|
||||||
|
# Parse arguments. |
||||||
|
args = parser.parse_args() |
||||||
|
|
||||||
|
if args.debug_enabled: |
||||||
|
log.setLevel(DEBUG) |
||||||
|
|
||||||
|
log.debug("Namespace: %s" % args) |
||||||
|
|
||||||
|
# Load context. |
||||||
|
context = dict() |
||||||
|
if args.variables: |
||||||
|
context = initialize.context_from_cli(args.variables) |
||||||
|
|
||||||
|
# Handle filters. |
||||||
|
filters = None |
||||||
|
if args.filters: |
||||||
|
filters = initialize.filters_from_cli(args.filters) |
||||||
|
|
||||||
|
# Handle options. |
||||||
|
options = None |
||||||
|
if args.options: |
||||||
|
options = initialize.options_from_cli(args.options) |
||||||
|
|
||||||
|
if args.variables_file: |
||||||
|
variables = initialize.variable_from_file(args.variables_file) |
||||||
|
if variables: |
||||||
|
context.update(variables) |
||||||
|
|
||||||
|
if args.docs_enabled: |
||||||
|
exit_code = subcommands.output_docs( |
||||||
|
args.path, |
||||||
|
context=context, |
||||||
|
filters=filters, |
||||||
|
locations=args.template_locations, |
||||||
|
options=options |
||||||
|
) |
||||||
|
elif args.script_enabled: |
||||||
|
exit_code = subcommands.output_script( |
||||||
|
args.path, |
||||||
|
color_enabled=args.color_enabled, |
||||||
|
context=context, |
||||||
|
locations=args.template_locations, |
||||||
|
options=options |
||||||
|
) |
||||||
|
else: |
||||||
|
exit_code = subcommands.output_commands( |
||||||
|
args.path, |
||||||
|
color_enabled=args.color_enabled, |
||||||
|
context=context, |
||||||
|
filters=filters, |
||||||
|
locations=args.template_locations, |
||||||
|
options=options |
||||||
|
) |
||||||
|
|
||||||
|
exit(exit_code) |
@ -0,0 +1,58 @@ |
|||||||
|
# Imports |
||||||
|
|
||||||
|
from configparser import ConfigParser |
||||||
|
import logging |
||||||
|
import os |
||||||
|
from superpython.utils import smart_cast |
||||||
|
from ..constants import LOGGER_NAME |
||||||
|
|
||||||
|
log = logging.getLogger(LOGGER_NAME) |
||||||
|
|
||||||
|
# Functions |
||||||
|
|
||||||
|
|
||||||
|
def context_from_cli(variables): |
||||||
|
context = dict() |
||||||
|
for i in variables: |
||||||
|
key, value = i.split(":") |
||||||
|
context[key] = smart_cast(value) |
||||||
|
|
||||||
|
return context |
||||||
|
|
||||||
|
|
||||||
|
def filters_from_cli(filters): |
||||||
|
_filters = dict() |
||||||
|
for i in filters: |
||||||
|
key, value = i.split(":") |
||||||
|
if key not in filters: |
||||||
|
_filters[key] = list() |
||||||
|
|
||||||
|
_filters[key].append(value) |
||||||
|
|
||||||
|
return _filters |
||||||
|
|
||||||
|
|
||||||
|
def options_from_cli(options): |
||||||
|
_options = dict() |
||||||
|
for i in options: |
||||||
|
key, value = i.split(":") |
||||||
|
_options[key] = smart_cast(value) |
||||||
|
|
||||||
|
return _options |
||||||
|
|
||||||
|
|
||||||
|
def variable_from_file(path): |
||||||
|
if not os.path.exists(path): |
||||||
|
log.warning("Variables file does not exist: %s" % path) |
||||||
|
return None |
||||||
|
|
||||||
|
ini = ConfigParser() |
||||||
|
ini.read(path) |
||||||
|
|
||||||
|
variables = dict() |
||||||
|
for section in ini.sections(): |
||||||
|
for key, value in ini.items(section): |
||||||
|
key = "%s_%s" % (section, key) |
||||||
|
variables[key] = smart_cast(vaue) |
||||||
|
|
||||||
|
return variables |
@ -0,0 +1,76 @@ |
|||||||
|
# Imports |
||||||
|
|
||||||
|
from superpython.shell import EXIT |
||||||
|
from superpython.utils import highlight_code |
||||||
|
from ..parsers import load_commands, load_config |
||||||
|
|
||||||
|
# Functions |
||||||
|
|
||||||
|
|
||||||
|
def output_commands(path, color_enabled=False, context=None, filters=None, locations=None, options=None): |
||||||
|
commands = load_commands( |
||||||
|
path, |
||||||
|
context=context, |
||||||
|
filters=filters, |
||||||
|
locations=locations, |
||||||
|
options=options |
||||||
|
) |
||||||
|
if commands is None: |
||||||
|
return EXIT.ERROR |
||||||
|
|
||||||
|
output = list() |
||||||
|
for command in commands: |
||||||
|
statement = command.get_statement(cd=True) |
||||||
|
if statement is None: |
||||||
|
continue |
||||||
|
|
||||||
|
output.append(statement) |
||||||
|
output.append("") |
||||||
|
|
||||||
|
if color_enabled: |
||||||
|
print(highlight_code("\n".join(output), language="bash")) |
||||||
|
else: |
||||||
|
print("\n".join(output)) |
||||||
|
|
||||||
|
return EXIT.OK |
||||||
|
|
||||||
|
|
||||||
|
def output_docs(path, context=None, filters=None, locations=None, options=None): |
||||||
|
commands = load_commands( |
||||||
|
path, |
||||||
|
context=context, |
||||||
|
filters=filters, |
||||||
|
locations=locations, |
||||||
|
options=options |
||||||
|
) |
||||||
|
if commands is None: |
||||||
|
return EXIT.ERROR |
||||||
|
|
||||||
|
count = 1 |
||||||
|
output = list() |
||||||
|
for command in commands: |
||||||
|
output.append("%s. %s" % (count, command.comment)) |
||||||
|
count += 1 |
||||||
|
|
||||||
|
print("\n".join(output)) |
||||||
|
|
||||||
|
return EXIT.OK |
||||||
|
|
||||||
|
|
||||||
|
def output_script(path, color_enabled=False, context=None, filters=None, locations=None, options=None): |
||||||
|
config = load_config( |
||||||
|
path, |
||||||
|
context=context, |
||||||
|
locations=locations, |
||||||
|
options=options |
||||||
|
) |
||||||
|
if config is None: |
||||||
|
return EXIT.ERROR |
||||||
|
|
||||||
|
script = config.as_script() |
||||||
|
if color_enabled: |
||||||
|
print(highlight_code(script.to_string(), language="bash")) |
||||||
|
else: |
||||||
|
print(script) |
||||||
|
|
||||||
|
return EXIT.OK |
@ -1,47 +0,0 @@ |
|||||||
[apache] |
|
||||||
disable_module = a2dismod {{ module_name }} |
|
||||||
disable_site = a2dissite {{ domain_name }}.conf |
|
||||||
enable_module = a2enmod {{ module_name }} |
|
||||||
enable_site = a2ensite {{ domain_name }}.conf |
|
||||||
reload = service apache2 reload |
|
||||||
restart = service apache2 restart |
|
||||||
start = service apache2 start |
|
||||||
stop = service apache2 stop |
|
||||||
test = apachectl configtest |
|
||||||
|
|
||||||
[package_install] |
|
||||||
system = apt-get install -y {{ package_name }} |
|
||||||
pip = pip3 install{% if upgrade %} --upgrade{% endif %} --quiet {{ package_name }} |
|
||||||
|
|
||||||
[package_remove] |
|
||||||
system = apt-get uninstall -y {{ package_name }} |
|
||||||
pip = pip3 uninstall --quiet {{ package_name }} |
|
||||||
|
|
||||||
[system] |
|
||||||
install = apt-get install -y {{ package_name }} |
|
||||||
reboot = reboot |
|
||||||
remove = apt-get uninstall -y {{ package_name }} |
|
||||||
update = apt-get update -y |
|
||||||
upgrade = apt-get upgrade -y |
|
||||||
|
|
||||||
[python] |
|
||||||
virtualenv = virtualenv {{ name }} |
|
||||||
install = pip3 install{% if upgrade %} --upgrade{% endif %} --quiet {{ package_name }} |
|
||||||
remove = pip3 uninstall --quiet {{ package_name }} |
|
||||||
|
|
||||||
[files] |
|
||||||
append = echo "{{ content }}" >> {{ path }} |
|
||||||
chgrp = chgrp{% if recursive %} -R{% endif %} {{ group }} {{ path }} |
|
||||||
chmod = chmod{% if recursive %} -R{% endif %} {{ owner }} {{ path }} |
|
||||||
chown = chown{% if recursive %} -R{% endif %} {{ mode }} {{ path }} |
|
||||||
copy = cp{% if recursive %} -R{% endif %}{% if overwrite %} -n{% endif %} {{ from_path }} {{ to_path }} |
|
||||||
mkdir = mkdir{% if mode %} -m {{ mode }}{% endif %}{% if recursive %} -p{% endif %} {{ path }} |
|
||||||
move = move {{ from_path }} {{ to_path }} |
|
||||||
rename = move {{ from_path }} {{ to_path }} |
|
||||||
remove = rm{% if force %} -f{% endif %}{% if recursive %} -r{% endif %} {{ path }} |
|
||||||
;rsync = ? |
|
||||||
;scopy = ? |
|
||||||
;sed = ? |
|
||||||
symlink = ln -s{% if force %} -f{% endif %} {{ source }} {{ target }} |
|
||||||
touch = touch {{ path }} |
|
||||||
;write = ? |
|
@ -1,224 +0,0 @@ |
|||||||
# Imports |
|
||||||
|
|
||||||
from configparser import RawConfigParser |
|
||||||
import os |
|
||||||
from superpython.utils import parse_jinja_string |
|
||||||
from ..constants import PATH_TO_SCRIPT_TEASE |
|
||||||
|
|
||||||
# Exports |
|
||||||
|
|
||||||
__all__ = ( |
|
||||||
"Overlay", |
|
||||||
) |
|
||||||
|
|
||||||
# Classes |
|
||||||
|
|
||||||
|
|
||||||
class Overlay(object): |
|
||||||
"""An overlay applies commands specific to a given operating system or platform.""" |
|
||||||
|
|
||||||
def __init__(self, name): |
|
||||||
self.is_loaded = False |
|
||||||
self._name = name |
|
||||||
self._path = os.path.join(PATH_TO_SCRIPT_TEASE, "data", "overlays", "%s.ini" % name) |
|
||||||
self._sections = dict() |
|
||||||
|
|
||||||
def __repr__(self): |
|
||||||
return "<%s %s>" % (self.__class__.__name__, self._name) |
|
||||||
|
|
||||||
@property |
|
||||||
def exists(self): |
|
||||||
"""Indicates whether the overlay file exists. |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
return os.path.exists(self._path) |
|
||||||
|
|
||||||
def get(self, section, key, **kwargs): |
|
||||||
"""Get the command statement for the given section and key. |
|
||||||
|
|
||||||
:param section: The section name. |
|
||||||
:type section: str |
|
||||||
|
|
||||||
:param key: The key within the section. |
|
||||||
:type key: str |
|
||||||
|
|
||||||
kwargs are used to parse the value of the key within the section. |
|
||||||
|
|
||||||
:rtype: str | None |
|
||||||
|
|
||||||
""" |
|
||||||
if not self.has(section, key): |
|
||||||
return None |
|
||||||
|
|
||||||
template = self._sections[section][key] |
|
||||||
|
|
||||||
return parse_jinja_string(template, kwargs) |
|
||||||
|
|
||||||
def has(self, section, key): |
|
||||||
"""Determine whether the overlay contains a given section and key. |
|
||||||
|
|
||||||
:param section: The section name. |
|
||||||
:type section: str |
|
||||||
|
|
||||||
:param key: The key within the section. |
|
||||||
:type key: str |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
if section not in self._sections: |
|
||||||
return False |
|
||||||
|
|
||||||
if key not in self._sections[section]: |
|
||||||
return False |
|
||||||
|
|
||||||
return True |
|
||||||
|
|
||||||
def load(self): |
|
||||||
"""Load the overlay. |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
if not self.exists: |
|
||||||
return False |
|
||||||
|
|
||||||
ini = RawConfigParser() |
|
||||||
ini.read(self._path) |
|
||||||
|
|
||||||
for section in ini.sections(): |
|
||||||
self._sections[section] = dict() |
|
||||||
for key, value in ini.items(section): |
|
||||||
self._sections[section][key] = value |
|
||||||
|
|
||||||
self.is_loaded = True |
|
||||||
return True |
|
||||||
|
|
||||||
def to_mapping(self): |
|
||||||
"""Export the overlay as a dictionary with command names as values. |
|
||||||
|
|
||||||
:rtype: dict |
|
||||||
|
|
||||||
""" |
|
||||||
d = dict() |
|
||||||
for section in self._sections: |
|
||||||
d[section] = list() |
|
||||||
for command_name, statement in self._sections[section].items(): |
|
||||||
d[section].append(command_name) |
|
||||||
|
|
||||||
|
|
||||||
class Overlay2(object): |
|
||||||
"""An overlay applies commands specific to a given operating system or platform.""" |
|
||||||
|
|
||||||
def __init__(self, name): |
|
||||||
self.is_loaded = False |
|
||||||
self._name = name |
|
||||||
self._path = os.path.join(PATH_TO_SCRIPT_TEASE, "data", "overlays", "%s.ini" % name) |
|
||||||
self._sections = dict() |
|
||||||
|
|
||||||
self.exists = os.path.exists(self._path) |
|
||||||
|
|
||||||
def __repr__(self): |
|
||||||
return "<%s %s>" % (self.__class__.__name__, self._name) |
|
||||||
|
|
||||||
def command_exists(self, name): |
|
||||||
"""Determine whether a given command exists. |
|
||||||
|
|
||||||
:param name: The name of the command to check. |
|
||||||
:type name: str |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
section = None |
|
||||||
if "." in name: |
|
||||||
section, name = name.split(".") |
|
||||||
|
|
||||||
if section is not None: |
|
||||||
if section in self._sections: |
|
||||||
return name in self._sections[section] |
|
||||||
|
|
||||||
for section in self._sections.keys(): |
|
||||||
if name in self._sections[section]: |
|
||||||
return True |
|
||||||
|
|
||||||
return False |
|
||||||
|
|
||||||
def get_statement(self, name, *args, **kwargs): |
|
||||||
pass |
|
||||||
|
|
||||||
def get(self, section, key, **kwargs): |
|
||||||
"""Get the command statement for the given section and key. |
|
||||||
|
|
||||||
:param section: The section name. |
|
||||||
:type section: str |
|
||||||
|
|
||||||
:param key: The key within the section. |
|
||||||
:type key: str |
|
||||||
|
|
||||||
kwargs are used to parse the value of the key within the section. |
|
||||||
|
|
||||||
:rtype: str | None |
|
||||||
|
|
||||||
""" |
|
||||||
if not self.has(section, key): |
|
||||||
return None |
|
||||||
|
|
||||||
template = self._sections[section][key] |
|
||||||
|
|
||||||
return parse_jinja_string(template, kwargs) |
|
||||||
|
|
||||||
def has(self, section, key): |
|
||||||
"""Determine whether the overlay contains a given section and key. |
|
||||||
|
|
||||||
:param section: The section name. |
|
||||||
:type section: str |
|
||||||
|
|
||||||
:param key: The key within the section. |
|
||||||
:type key: str |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
if section not in self._sections: |
|
||||||
return False |
|
||||||
|
|
||||||
if key not in self._sections[section]: |
|
||||||
return False |
|
||||||
|
|
||||||
return True |
|
||||||
|
|
||||||
def load(self): |
|
||||||
"""Load the overlay. |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
if not self.exists: |
|
||||||
return False |
|
||||||
|
|
||||||
ini = RawConfigParser() |
|
||||||
ini.read(self._path) |
|
||||||
|
|
||||||
for section in ini.sections(): |
|
||||||
self._sections[section] = dict() |
|
||||||
for command_name, statement_template in ini.items(section): |
|
||||||
self._sections[section][command_name] = statement_template |
|
||||||
|
|
||||||
self.is_loaded = True |
|
||||||
|
|
||||||
return True |
|
||||||
|
|
||||||
def to_mapping(self): |
|
||||||
"""Export the overlay as a dictionary with command names as values. |
|
||||||
|
|
||||||
:rtype: dict |
|
||||||
|
|
||||||
""" |
|
||||||
d = dict() |
|
||||||
for section in self._sections: |
|
||||||
d[section] = list() |
|
||||||
for command_name, statement in self._sections[section].items(): |
|
||||||
d[section].append(command_name) |
|
@ -1,2 +1,2 @@ |
|||||||
from .base import Command, ItemizedCommand |
from .base import Command, ItemizedCommand |
||||||
from .factory import command_factory |
# from .factory import command_factory |
||||||
|
@ -1,134 +0,0 @@ |
|||||||
# Imports |
|
||||||
|
|
||||||
import logging |
|
||||||
from ...constants import LOGGER_NAME |
|
||||||
from .base import Command |
|
||||||
|
|
||||||
log = logging.getLogger(LOGGER_NAME) |
|
||||||
|
|
||||||
# Exports |
|
||||||
|
|
||||||
__all__ = ( |
|
||||||
"MAPPING", |
|
||||||
"ConfigTest", |
|
||||||
"DisableModule", |
|
||||||
"DisableSite", |
|
||||||
"EnableModule", |
|
||||||
"EnableSite", |
|
||||||
"Reload", |
|
||||||
"Restart", |
|
||||||
"Start", |
|
||||||
"Stop", |
|
||||||
) |
|
||||||
|
|
||||||
# Classes |
|
||||||
|
|
||||||
|
|
||||||
class ConfigTest(Command): |
|
||||||
"""Run an apache config test.""" |
|
||||||
|
|
||||||
def __init__(self, overlay=None, **kwargs): |
|
||||||
"""There is no argument.""" |
|
||||||
if overlay is not None: |
|
||||||
statement = overlay.get("apache", "test") |
|
||||||
else: |
|
||||||
statement = "apachectl configtest" |
|
||||||
|
|
||||||
kwargs.setdefault('register', "apache_checks_out") |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
class DisableModule(Command): |
|
||||||
"""Disable an Apache module.""" |
|
||||||
|
|
||||||
def __init__(self, module_name, overlay=None, **kwargs): |
|
||||||
"""Initialize the command. |
|
||||||
|
|
||||||
:param module_name: The module name. |
|
||||||
:type module_name: str |
|
||||||
|
|
||||||
""" |
|
||||||
if overlay is not None: |
|
||||||
statement = overlay.get("apache", "disable_module", module_name=module_name) |
|
||||||
|
|
||||||
statement = "a2dismod %s" % module_name |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
class DisableSite(Command): |
|
||||||
"""Disable a virtual host.""" |
|
||||||
|
|
||||||
def __init__(self, domain_name, **kwargs): |
|
||||||
"""Initialize the command. |
|
||||||
|
|
||||||
:param domain_name: The domain name. |
|
||||||
:type domain_name: str |
|
||||||
|
|
||||||
""" |
|
||||||
statement = "a2dissite %s.conf" % domain_name |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
class Enable(Command): |
|
||||||
|
|
||||||
def __init__(self, what, name, **kwargs): |
|
||||||
if what in ("mod", "module"): |
|
||||||
statement = EnableModule(name, **kwargs).statement |
|
||||||
elif what == "site": |
|
||||||
statement = EnableSite(name, **kwargs).statement |
|
||||||
else: |
|
||||||
raise ValueError("Invalid Apache item to be enabled: %s" % what) |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
class EnableModule(Command): |
|
||||||
"""Enable an Apache module.""" |
|
||||||
|
|
||||||
def __init__(self, module_name, **kwargs): |
|
||||||
"""Initialize the command. |
|
||||||
|
|
||||||
:param module_name: The module name. |
|
||||||
:type module_name: str |
|
||||||
|
|
||||||
""" |
|
||||||
statement = "a2enmod %s" % module_name |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
class EnableSite(Command): |
|
||||||
"""Enable a virtual host.""" |
|
||||||
|
|
||||||
def __init__(self, domain_name, **kwargs): |
|
||||||
"""Initialize the command. |
|
||||||
|
|
||||||
:param domain_name: The domain name. |
|
||||||
:type domain_name: str |
|
||||||
|
|
||||||
""" |
|
||||||
statement = "a2ensite %s.conf" % domain_name |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
MAPPING = { |
|
||||||
# 'apache': Apache, |
|
||||||
'apache.check': ConfigTest, |
|
||||||
'apache.config': ConfigTest, |
|
||||||
'apache.configtest': ConfigTest, |
|
||||||
'apache.disable': Disable, |
|
||||||
'apache.disable_mod': DisableModule, |
|
||||||
'apache.disable_module': DisableModule, |
|
||||||
'apache.disable_site': DisableSite, |
|
||||||
'apache.enable': Enable, |
|
||||||
'apache.enable_mod': EnableModule, |
|
||||||
'apache.enable_module': EnableModule, |
|
||||||
'apache.enable_site': EnableSite, |
|
||||||
'apache.mod': EnableModule, |
|
||||||
'apache.module': EnableModule, |
|
||||||
'apache.test': ConfigTest, |
|
||||||
} |
|
@ -1,119 +0,0 @@ |
|||||||
# Imports |
|
||||||
|
|
||||||
from importlib import import_module |
|
||||||
import logging |
|
||||||
# from ..scripts import Function |
|
||||||
from ...constants import LOGGER_NAME |
|
||||||
# from .base import ItemizedCommand |
|
||||||
# from .mappings import MAPPING |
|
||||||
|
|
||||||
log = logging.getLogger(LOGGER_NAME) |
|
||||||
|
|
||||||
# Functions |
|
||||||
|
|
||||||
|
|
||||||
def command_factory(name, comment, overlay, *args, **kwargs): |
|
||||||
# try: |
|
||||||
# _overlay = import_module("scripttease.library.overlays.%s" % overlay) |
|
||||||
# except ImportError as e: |
|
||||||
# log.error("The %s overlay could not be imported: %s" % (overlay, str(e))) |
|
||||||
# return None |
|
||||||
|
|
||||||
if not overlay.command_exists(name): |
|
||||||
log.warning("Command does not exist in %s overlay: %s" % (overlay.name, name)) |
|
||||||
return None |
|
||||||
|
|
||||||
kwargs['comment'] = comment |
|
||||||
|
|
||||||
callback = overlay.MAPPINGS[name] |
|
||||||
return callback(*args, **kwargs) |
|
||||||
|
|
||||||
''' |
|
||||||
def command_exists(name): |
|
||||||
"""Indicates whether the named command exists. |
|
||||||
|
|
||||||
:param name: The name of the command to be checked. |
|
||||||
:type name: str |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
return name in MAPPING |
|
||||||
|
|
||||||
|
|
||||||
def command_factory(name, comment, overlay, *args, **kwargs): |
|
||||||
# if name in ("func", "function"): |
|
||||||
# kwargs['comment'] = comment |
|
||||||
# return Function(*args, **kwargs) |
|
||||||
|
|
||||||
if not command_exists(name): |
|
||||||
log.warning("No mapping for command: %s" % name) |
|
||||||
return None |
|
||||||
|
|
||||||
_args = list(args) |
|
||||||
kwargs['comment'] = comment |
|
||||||
kwargs['overlay'] = overlay |
|
||||||
|
|
||||||
log.debug("%s: %s" % (comment, kwargs)) |
|
||||||
|
|
||||||
command_class = MAPPING[name] |
|
||||||
try: |
|
||||||
items = kwargs.pop("items", None) |
|
||||||
if items is not None: |
|
||||||
return ItemizedCommand(command_class, items, *_args, **kwargs) |
|
||||||
|
|
||||||
return command_class(*_args, **kwargs) |
|
||||||
except (KeyError, TypeError, ValueError) as e: |
|
||||||
log.critical("Failed to load %s command: %s" % (name, e)) |
|
||||||
return None |
|
||||||
''' |
|
||||||
|
|
||||||
# |
|
||||||
# |
|
||||||
# |
|
||||||
# MAPPINGS = { |
|
||||||
# 'apache.disable_module': apache_disable_module, |
|
||||||
# 'apache.disable_site': apache_disable_site, |
|
||||||
# 'apache.enable_module': apache_enable_module, |
|
||||||
# 'apache.enable_site': apache_enable_site, |
|
||||||
# 'apache.reload': apache_reload, |
|
||||||
# 'apache.restart': apache_restart, |
|
||||||
# 'apache.start': apache_start, |
|
||||||
# 'apache.stop': apache_stop, |
|
||||||
# 'apache.test': apache_test, |
|
||||||
# 'copy': file_copy, |
|
||||||
# 'pip': python_pip, |
|
||||||
# 'virtualenv': python_virtualenv, |
|
||||||
# # 'python': ("pip", "virtualenv"), |
|
||||||
# # 'apache': ("disable_module", "disable_site", "enable_module", "enable_site", "test"), |
|
||||||
# } |
|
||||||
|
|
||||||
|
|
||||||
def nother_command_exists(name): |
|
||||||
return name in MAPPINGS |
|
||||||
|
|
||||||
|
|
||||||
def other_command_exists(name, section=None): |
|
||||||
if section is not None: |
|
||||||
if section not in MAPPINGS: |
|
||||||
return False |
|
||||||
|
|
||||||
return name in MAPPINGS[section] |
|
||||||
|
|
||||||
for _section, commands in MAPPINGS.items(): |
|
||||||
if name in commands: |
|
||||||
return True |
|
||||||
|
|
||||||
return False |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def other_command_factory(name, comment, overlay, *args, **kwargs): |
|
||||||
if not overlay.command_exists(name): |
|
||||||
log.warning("The %s overlay does not have a mapping for command: %s" % (overlay, name)) |
|
||||||
return None |
|
||||||
|
|
||||||
items = kwargs.pop("items", None) |
|
||||||
if items is not None: |
|
||||||
return ItemizedCommand |
|
||||||
|
|
@ -1,4 +0,0 @@ |
|||||||
from .python import MAPPING as PYTHON_MAPPING |
|
||||||
|
|
||||||
MAPPING = dict() |
|
||||||
MAPPING.update(PYTHON_MAPPING) |
|
@ -1,23 +0,0 @@ |
|||||||
# Classes |
|
||||||
|
|
||||||
|
|
||||||
class Install(object): |
|
||||||
|
|
||||||
def __init__(self, name, manager="pip", overlay=None, upgrade=False, **kwargs): |
|
||||||
if overlay is not None: |
|
||||||
statement = overlay.get("package_install", manager, package_name=name, upgrade=upgrade) |
|
||||||
else: |
|
||||||
statement = "%s install %s" % (manager, name) |
|
||||||
|
|
||||||
self.statement = statement |
|
||||||
|
|
||||||
|
|
||||||
class Remove(object): |
|
||||||
|
|
||||||
def __init__(self, name, manager="pip", overlay=None): |
|
||||||
if overlay is not None: |
|
||||||
statement = overlay.get("package_remove", manager, package_name=name) |
|
||||||
else: |
|
||||||
statement = "%s uninstall %s" % (manager, name) |
|
||||||
|
|
||||||
|
|
@ -1,43 +0,0 @@ |
|||||||
# Imports |
|
||||||
|
|
||||||
from .base import Command |
|
||||||
|
|
||||||
# Exports |
|
||||||
|
|
||||||
__all__ = ( |
|
||||||
"Pip", |
|
||||||
"VirtualEnv", |
|
||||||
) |
|
||||||
|
|
||||||
# Classes |
|
||||||
|
|
||||||
|
|
||||||
class Pip(Command): |
|
||||||
|
|
||||||
def __init__(self, name, op="install", overlay=None, upgrade=False, venv=None, **kwargs): |
|
||||||
if overlay is not None: |
|
||||||
statement = overlay.get("python", op, package_name=name, upgrade=upgrade) |
|
||||||
else: |
|
||||||
statement = "pip %s -y %s" % (op, name) |
|
||||||
|
|
||||||
if venv is not None: |
|
||||||
kwargs['prefix'] = "source %s/bin/activate" % venv |
|
||||||
|
|
||||||
kwargs.setdefault("comment", "%s %s" % (op, name)) |
|
||||||
|
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
class VirtualEnv(Command): |
|
||||||
|
|
||||||
def __init__(self, name="python", overlay=None, **kwargs): |
|
||||||
kwargs.setdefault("comment", "create %s virtual environment" % name) |
|
||||||
|
|
||||||
statement = "virtualenv %s" % name |
|
||||||
super().__init__(statement, **kwargs) |
|
||||||
|
|
||||||
|
|
||||||
MAPPING = { |
|
||||||
'pip': Pip, |
|
||||||
'virtualenv': VirtualEnv, |
|
||||||
} |
|
@ -0,0 +1,164 @@ |
|||||||
|
# Imports |
||||||
|
|
||||||
|
import os |
||||||
|
from ..commands import Command |
||||||
|
|
||||||
|
# Exports |
||||||
|
|
||||||
|
__all__ = ( |
||||||
|
"DJANGO_MAPPINGS", |
||||||
|
"django", |
||||||
|
"django_check", |
||||||
|
"django_collect_static", |
||||||
|
"django_dumpdata", |
||||||
|
"django_loaddata", |
||||||
|
"django_migrate", |
||||||
|
) |
||||||
|
|
||||||
|
# Functions |
||||||
|
|
||||||
|
|
||||||
|
def _django(name, *args, venv=None, **kwargs): |
||||||
|
if venv is not None: |
||||||
|
kwargs['prefix'] = "source %s/bin/activate" % venv |
||||||
|
|
||||||
|
kwargs.setdefault("comment", "run %s django management command" % name) |
||||||
|
|
||||||
|
# Base parameters need to be captured, because all others are assumed to be switches for the management command. |
||||||
|
_kwargs = { |
||||||
|
'comment': kwargs.pop("comment", None), |
||||||
|
'condition': kwargs.pop("condition", None), |
||||||
|
'cd': kwargs.pop("cd", None), |
||||||
|
'environments': kwargs.pop("environments", None), |
||||||
|
'function': kwargs.pop("function", None), |
||||||
|
# 'local': kwargs.pop("local", False), |
||||||
|
'prefix': kwargs.pop("prefix", None), |
||||||
|
'register': kwargs.pop("register", None), |
||||||
|
'shell': kwargs.pop("shell", "/bin/bash"), |
||||||
|
'stop': kwargs.pop("stop", False), |
||||||
|
'sudo': kwargs.pop('sudo', False), |
||||||
|
'tags': kwargs.pop("tags", None), |
||||||
|
} |
||||||
|
|
||||||
|
statement = list() |
||||||
|
statement.append("./manage.py %s" % name) |
||||||
|
|
||||||
|
# Remaining kwargs are assumed to be switches. |
||||||
|
for key, value in kwargs.items(): |
||||||
|
key = key.replace("_", "-") |
||||||
|
if type(value) is bool: |
||||||
|
if value is True: |
||||||
|
statement.append("--%s" % key) |
||||||
|
else: |
||||||
|
statement.append("--%s=%s" % (key, value)) |
||||||
|
|
||||||
|
if len(args) > 0: |
||||||
|
statement.append(" ".join(args)) |
||||||
|
|
||||||
|
return Command(" ".join(statement), **_kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def django(name, *args, venv=None, **kwargs): |
||||||
|
if name == "check": |
||||||
|
return django_check(venv=venv, **kwargs) |
||||||
|
elif name in ("collectstatic", "static"): |
||||||
|
return django_collect_static(venv=venv, **kwargs) |
||||||
|
elif name == "migrate": |
||||||
|
return django_migrate(venv=venv, **kwargs) |
||||||
|
else: |
||||||
|
return _django(name, *args, venv=venv, **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def django_check(venv=None, **kwargs): |
||||||
|
kwargs.setdefault("comment", "run django checks") |
||||||
|
kwargs.setdefault("register", "django_checks_out") |
||||||
|
|
||||||
|
return _django("check", venv=venv, **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def django_collect_static(venv=None, **kwargs): |
||||||
|
kwargs.setdefault("comment", "collect static files") |
||||||
|
|
||||||
|
return _django("collectstatic", venv=venv, **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def django_dumpdata(app_name, base_path="local", file_name="initial", indent=4, natural_foreign=False, |
||||||
|
natural_primary=False, path=None, venv=None, **kwargs): |
||||||
|
"""Initialize the command. |
||||||
|
|
||||||
|
:param app_name: The name (app label) of the app. ``app_label.ModelName`` may also be given. |
||||||
|
:type app_name: str |
||||||
|
|
||||||
|
:param file_name: The file name to which the data will be dumped. |
||||||
|
:type file_name: str |
||||||
|
|
||||||
|
:param indent: Indentation of the exported fixtures. |
||||||
|
:type indent: int |
||||||
|
|
||||||
|
:param natural_foreign: Use the natural foreign parameter. |
||||||
|
:type natural_foreign: bool |
||||||
|
|
||||||
|
:param natural_primary: Use the natural primary parameter. |
||||||
|
:type natural_primary: bool |
||||||
|
|
||||||
|
:param path: The path to the data file. |
||||||
|
:type path: str |
||||||
|
|
||||||
|
""" |
||||||
|
kwargs.setdefault("comment", "export fixtures for %s" % app_name) |
||||||
|
|
||||||
|
output_format = kwargs.pop("format", "json") |
||||||
|
|
||||||
|
_path = path or os.path.join(base_path, app_name, "fixtures", "%s.%s" % (file_name, output_format)) |
||||||
|
|
||||||
|
return _django( |
||||||
|
"dumpdata", |
||||||
|
app_name, |
||||||
|
"> %s" % _path, |
||||||
|
format=output_format, |
||||||
|
indent=indent, |
||||||
|
natural_foreign=natural_foreign, |
||||||
|
natural_primary=natural_primary, |
||||||
|
venv=venv, |
||||||
|
**kwargs |
||||||
|
) |
||||||
|
|
||||||
|
|
||||||
|
def django_loaddata(app_name, base_path="local", file_name="initial", path=None, venv=None, **kwargs): |
||||||
|
"""Initialize the command. |
||||||
|
|
||||||
|
:param app_name: The name (app label) of the app. |
||||||
|
:type app_name: str |
||||||
|
|
||||||
|
:param file_name: The file name to which the data will be dumped. |
||||||
|
:type file_name: str |
||||||
|
|
||||||
|
:param path: The path to the data file. |
||||||
|
:type path: str |
||||||
|
|
||||||
|
""" |
||||||
|
kwargs.setdefault("comment", "load fixtures for %s" % app_name) |
||||||
|
|
||||||
|
output_format = kwargs.pop("format", "json") |
||||||
|
|
||||||
|
_path = path or os.path.join(base_path, app_name, "fixtures", "%s.%s" % (file_name, output_format)) |
||||||
|
|
||||||
|
return _django("loaddata", _path, venv=venv, **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def django_migrate(venv=None, **kwargs): |
||||||
|
kwargs.setdefault("comment", "run django database migrations") |
||||||
|
|
||||||
|
return _django("migrate", venv=venv, **kwargs) |
||||||
|
|
||||||
|
# Mapping |
||||||
|
|
||||||
|
|
||||||
|
DJANGO_MAPPINGS = { |
||||||
|
'django': django, |
||||||
|
'django.check': django_check, |
||||||
|
'django.collect_static': django_collect_static, |
||||||
|
'django.dumpdata': django_dumpdata, |
||||||
|
'django.loaddata': django_loaddata, |
||||||
|
'django.migrate': django_migrate, |
||||||
|
} |
@ -0,0 +1,292 @@ |
|||||||
|
# Imports |
||||||
|
|
||||||
|
from ..commands import Command |
||||||
|
|
||||||
|
# Exports |
||||||
|
|
||||||
|
__all__ = ( |
||||||
|
"PGSQL_MAPPINGS", |
||||||
|
"pg_create_database", |
||||||
|
"pg_create_user", |
||||||
|
"pg_database_exists", |
||||||
|
"pg_drop_database", |
||||||
|
"pg_drop_user", |
||||||
|
"pg_dump_database", |
||||||
|
"psql", |
||||||
|
) |
||||||
|
|
||||||
|
# Functions |
||||||
|
|
||||||
|
|
||||||
|
def _get_pgsql_command(name, host="localhost", password=None, port=5432, user="postgres"): |
||||||
|
a = list() |
||||||
|
|
||||||
|
if password: |
||||||
|
a.append('export PGPASSWORD="%s" &&' % password) |
||||||
|
|
||||||
|
a.append(name) |
||||||
|
|
||||||
|
a.append("--host=%s" % host) |
||||||
|
a.append("--port=%s" % port) |
||||||
|
a.append("--username=%s" % user) |
||||||
|
|
||||||
|
return a |
||||||
|
|
||||||
|
|
||||||
|
def pg_create_database(name, admin_pass=None, admin_user="postgres", host="localhost", owner=None, port=5432, |
||||||
|
template=None, **kwargs): |
||||||
|
"""Create a PostgreSQL database. |
||||||
|
|
||||||
|
:param name: The database name. |
||||||
|
:type name: str |
||||||
|
|
||||||
|
:param admin_pass: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_pass: str |
||||||
|
|
||||||
|
:param admin_user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_user: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param owner: The owner (user/role name) of the new database. |
||||||
|
:type owner: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
:param template: The database template name to use, if any. |
||||||
|
:type template: str |
||||||
|
|
||||||
|
""" |
||||||
|
_owner = owner or admin_user |
||||||
|
|
||||||
|
# Postgres commands always run without sudo because the -U may be provided. |
||||||
|
kwargs['sudo'] = False |
||||||
|
|
||||||
|
# Assemble the command. |
||||||
|
base = _get_pgsql_command("createdb", host=host, password=admin_pass, port=port) |
||||||
|
base.append("--owner=%s" % _owner) |
||||||
|
|
||||||
|
if template is not None: |
||||||
|
base.append("--template=%s" % template) |
||||||
|
|
||||||
|
base.append(name) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def pg_create_user(name, admin_pass=None, admin_user="postgres", host="localhost", password=None, port=5432, **kwargs): |
||||||
|
"""Create a PostgreSQL user. |
||||||
|
|
||||||
|
:param name: The user name. |
||||||
|
:type name: str |
||||||
|
|
||||||
|
:param admin_pass: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_pass: str |
||||||
|
|
||||||
|
:param admin_user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_user: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param password: The password for the new user. |
||||||
|
:type password: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
""" |
||||||
|
# Postgres commands always run without sudo because the -U may be provided. |
||||||
|
kwargs['sudo'] = False |
||||||
|
|
||||||
|
# Assemble the command. |
||||||
|
base = _get_pgsql_command("createuser", host=host, password=admin_pass, port=port) |
||||||
|
base.append("-DRS") |
||||||
|
base.append(name) |
||||||
|
|
||||||
|
if password is not None: |
||||||
|
base.append("&& psql -h %s -U %s" % (host, admin_user)) |
||||||
|
base.append("-c \"ALTER USER %s WITH ENCRYPTED PASSWORD '%s';\"" % (name, password)) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def pg_database_exists(name, admin_pass=None, admin_user="postgres", host="localhost", port=5432, **kwargs): |
||||||
|
"""Determine if a Postgres database exists. |
||||||
|
|
||||||
|
:param name: The database name. |
||||||
|
:type name: str |
||||||
|
|
||||||
|
:param admin_pass: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_pass: str |
||||||
|
|
||||||
|
:param admin_user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_user: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
""" |
||||||
|
# Postgres commands always run without sudo because the -U may be provided. However, sudo may be required for |
||||||
|
# file writing. |
||||||
|
# kwargs['sudo'] = False |
||||||
|
|
||||||
|
kwargs.setdefault("register", "%s_db_exists" % name) |
||||||
|
|
||||||
|
base = _get_pgsql_command("psql", host=host, password=admin_pass, port=port, user=admin_user) |
||||||
|
base.append(r"-lqt | cut -d \| -f 1 | grep -qw %s" % name) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def pg_drop_database(name, admin_pass=None, admin_user="postgres", host="localhost", port=5432, **kwargs): |
||||||
|
"""Remove a PostgreSQL database. |
||||||
|
|
||||||
|
:param name: The database name. |
||||||
|
:type name: str |
||||||
|
|
||||||
|
:param admin_pass: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_pass: str |
||||||
|
|
||||||
|
:param admin_user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_user: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
""" |
||||||
|
# Postgres commands always run without sudo because the -U may be provided. |
||||||
|
kwargs['sudo'] = False |
||||||
|
|
||||||
|
# Assemble the command. |
||||||
|
base = _get_pgsql_command("dropdb", host=host, password=admin_pass, port=port, user=admin_user) |
||||||
|
base.append(name) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def pg_drop_user(name, admin_pass=None, admin_user="postgres", host="localhost", port=5432, **kwargs): |
||||||
|
"""Remove a Postgres user. |
||||||
|
|
||||||
|
:param name: The user name. |
||||||
|
:type name: str |
||||||
|
|
||||||
|
:param admin_pass: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_pass: str |
||||||
|
|
||||||
|
:param admin_user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_user: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
""" |
||||||
|
# Postgres commands always run without sudo because the -U may be provided. |
||||||
|
kwargs['sudo'] = False |
||||||
|
|
||||||
|
# Assemble the command. |
||||||
|
base = _get_pgsql_command("dropuser", host=host, password=admin_pass, port=port, user=admin_user) |
||||||
|
base.append(name) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def pg_dump_database(name, admin_pass=None, admin_user="postgres", file_name=None, host="localhost", port=5432, |
||||||
|
**kwargs): |
||||||
|
"""Export a Postgres database. |
||||||
|
|
||||||
|
:param name: The database name. |
||||||
|
:type name: str |
||||||
|
|
||||||
|
:param admin_pass: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_pass: str |
||||||
|
|
||||||
|
:param admin_user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type admin_user: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param file_name: The name (including the path, if desired) of the export file. Defaults to the |
||||||
|
``database_name`` plus ".sql" |
||||||
|
:type file_name: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
""" |
||||||
|
_file_name = file_name or "%s.sql" % name |
||||||
|
|
||||||
|
# Postgres commands always run without sudo because the -U may be provided. |
||||||
|
kwargs['sudo'] = False |
||||||
|
|
||||||
|
# Assemble the command. |
||||||
|
base = _get_pgsql_command("pg_dump", host=host, password=admin_pass, port=port, user=admin_user) |
||||||
|
base.append("--column-inserts") |
||||||
|
base.append("--file=%s" % _file_name) |
||||||
|
base.append(name) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
def psql(sql, database="template1", host="localhost", password=None, port=5432, user="postgres", **kwargs): |
||||||
|
"""Execute a psql command. |
||||||
|
|
||||||
|
:param sql: The SQL to be executed. |
||||||
|
:type sql: str |
||||||
|
|
||||||
|
:param database: The database name. |
||||||
|
:type database: str |
||||||
|
|
||||||
|
:param password: The password for the user with sufficient access privileges to execute the command. |
||||||
|
:type password: str |
||||||
|
|
||||||
|
:param host: The database host name or IP address. |
||||||
|
:type host: str |
||||||
|
|
||||||
|
:param port: The port number of the Postgres service running on the host. |
||||||
|
:type port: int |
||||||
|
|
||||||
|
:param user: The name of the user with sufficient access privileges to execute the command. |
||||||
|
:type user: str |
||||||
|
|
||||||
|
""" |
||||||
|
# Postgres commands always run without sudo because the -U may be provided. |
||||||
|
kwargs['sudo'] = False |
||||||
|
|
||||||
|
# Assemble the command. |
||||||
|
base = _get_pgsql_command("psql", host=host, password=password, port=port, user=user) |
||||||
|
base.append("--dbname=%s" % database) |
||||||
|
base.append('-c "%s"' % sql) |
||||||
|
|
||||||
|
return Command(" ".join(base), **kwargs) |
||||||
|
|
||||||
|
|
||||||
|
PGSQL_MAPPINGS = { |
||||||
|
'pg.client': psql, |
||||||
|
'pg.createdatabase': pg_create_database, |
||||||
|
'pg.createdb': pg_create_database, |
||||||
|
'pg.createuser': pg_create_user, |
||||||
|
'pg.database': pg_create_database, |
||||||
|
'pg.database_exists': pg_database_exists, |
||||||
|
'pg.db': pg_create_database, |
||||||
|
'pg.dropdatabase': pg_drop_database, |
||||||
|
'pg.dropdb': pg_drop_database, |
||||||
|
'pg.dropuser': pg_drop_user, |
||||||
|
'pg.dump': pg_dump_database, |
||||||
|
'pg.dumpdb': pg_dump_database, |
||||||
|
'pg.exists': pg_database_exists, |
||||||
|
'pg.user': pg_create_user, |
||||||
|
'psql': psql, |
||||||
|
} |
@ -1,85 +1,4 @@ |
|||||||
# Imports |
# Imports |
||||||
|
|
||||||
import logging |
|
||||||
from superpython.utils import any_list_item |
|
||||||
from ..constants import LOGGER_NAME |
|
||||||
from .ini import Config |
from .ini import Config |
||||||
|
from .utils import filter_commands, load_commands, load_config |
||||||
log = logging.getLogger(LOGGER_NAME) |
|
||||||
|
|
||||||
# Exports |
|
||||||
|
|
||||||
__all__ = ( |
|
||||||
"filter_commands", |
|
||||||
"load_commands", |
|
||||||
) |
|
||||||
|
|
||||||
# Functions |
|
||||||
|
|
||||||
|
|
||||||
def filter_commands(commands, environments=None, tags=None): |
|
||||||
"""Filter commands based on the given criteria. |
|
||||||
|
|
||||||
:param commands: The commands to be filtered. |
|
||||||
:type commands: list |
|
||||||
|
|
||||||
:param environments: Environment names to be matched. |
|
||||||
:type environments: list[str] |
|
||||||
|
|
||||||
:param tags: Tag names to be matched. |
|
||||||
:type tags |
|
||||||
:return: |
|
||||||
""" |
|
||||||
filtered = list() |
|
||||||
for command in commands: |
|
||||||
if environments is not None: |
|
||||||
if not any_list_item(environments, command.environments): |
|
||||||
continue |
|
||||||
|
|
||||||
if tags is not None: |
|
||||||
if not any_list_item(tags, command.tags): |
|
||||||
continue |
|
||||||
|
|
||||||
filtered.append(command) |
|
||||||
|
|
||||||
return filtered |
|
||||||
|
|
||||||
|
|
||||||
def load_commands(path, filters=None, overlay=None, **kwargs): |
|
||||||
"""Load commands from a configuration file. |
|
||||||
|
|
||||||
:param path: The path to the configuration file. |
|
||||||
:type path: str |
|
||||||
|
|
||||||
:param filters: Used to filter commands. |
|
||||||
:type filters: dict |
|
||||||
|
|
||||||
:rtype: list[BaseType[Command] | ItemizedCommand] | None |
|
||||||
|
|
||||||
:returns: A list of command instances or ``None`` if the configuration could not be loaded. |
|
||||||
|
|
||||||
kwargs are passed to the configuration class for instantiation. |
|
||||||
|
|
||||||
""" |
|
||||||
if path.endswith(".ini"): |
|
||||||
_config = Config(path, overlay=overlay, **kwargs) |
|
||||||
# elif path.endswith(".yml"): |
|
||||||
# _config = YAML(path, **kwargs) |
|
||||||
else: |
|
||||||
log.warning("Input file format is not currently supported: %s" % path) |
|
||||||
return None |
|
||||||
|
|
||||||
if _config.load(): |
|
||||||
commands = _config.get_commands() |
|
||||||
|
|
||||||
if filters is not None: |
|
||||||
criteria = dict() |
|
||||||
for attribute, values in filters.items(): |
|
||||||
criteria[attribute] = values |
|
||||||
|
|
||||||
commands = filter_commands(commands, **criteria) |
|
||||||
|
|
||||||
return commands |
|
||||||
|
|
||||||
log.error("Failed to load config file: %s" % path) |
|
||||||
return None |
|
||||||
|
@ -0,0 +1,110 @@ |
|||||||
|
# Imports |
||||||
|
|
||||||
|
import logging |
||||||
|
from superpython.utils import any_list_item |
||||||
|
from ..constants import LOGGER_NAME |
||||||
|
from .ini import Config |
||||||
|
|
||||||
|
log = logging.getLogger(LOGGER_NAME) |
||||||
|
|
||||||
|
# Exports |
||||||
|
|
||||||
|
__all__ = ( |
||||||
|
"filter_commands", |
||||||
|
"load_commands", |
||||||
|
) |
||||||
|
|
||||||
|
# Functions |
||||||
|
|
||||||
|
|
||||||
|
def filter_commands(commands, environments=None, tags=None): |
||||||
|
"""Filter commands based on the given criteria. |
||||||
|
|
||||||
|
:param commands: The commands to be filtered. |
||||||
|
:type commands: list |
||||||
|
|
||||||
|
:param environments: Environment names to be matched. |
||||||
|
:type environments: list[str] |
||||||
|
|
||||||
|
:param tags: Tag names to be matched. |
||||||
|
:type tags |
||||||
|
:return: |
||||||
|
""" |
||||||
|
filtered = list() |
||||||
|
for command in commands: |
||||||
|
if environments is not None: |
||||||
|
if not any_list_item(environments, command.environments): |
||||||
|
continue |
||||||
|
|
||||||
|
if tags is not None: |
||||||
|
if not any_list_item(tags, command.tags): |
||||||
|
continue |
||||||
|
|
||||||
|
filtered.append(command) |
||||||
|
|
||||||
|
return filtered |
||||||
|
|
||||||
|
|
||||||
|
def load_commands(path, filters=None, overlay="ubuntu", **kwargs): |
||||||
|
"""Load commands from a configuration file. |
||||||
|
|
||||||
|
:param path: The path to the configuration file. |
||||||
|
:type path: str |
||||||
|
|
||||||
|
:param filters: Used to filter commands. |
||||||
|
:type filters: dict |
||||||
|
|
||||||
|
:param overlay: The name of the command overlay to apply to generated commands. |
||||||
|
:type overlay: str |
||||||
|
|
||||||
|
:rtype: list[scriptetease.library.commands.base.Command] | scriptetease.library.commands.base.ItemizedCommand] | |
||||||
|
None |
||||||
|
|
||||||
|
:returns: A list of command instances or ``None`` if the configuration could not be loaded. |
||||||
|
|
||||||
|
kwargs are passed to the configuration class for instantiation. |
||||||
|
|
||||||
|
""" |
||||||
|
_config = load_config(path, overlay, **kwargs) |
||||||
|
if _config is None: |
||||||
|
return None |
||||||
|
|
||||||
|
commands = _config.get_commands() |
||||||
|
|
||||||
|
if filters is not None: |
||||||
|
criteria = dict() |
||||||
|
for attribute, values in filters.items(): |
||||||
|
criteria[attribute] = values |
||||||
|
|
||||||
|
commands = filter_commands(commands, **criteria) |
||||||
|
|
||||||
|
return commands |
||||||
|
|
||||||
|
|
||||||
|
def load_config(path, overlay="ubuntu", **kwargs): |
||||||
|
"""Load a command configuration. |
||||||
|
|
||||||
|
:param path: The path to the configuration file. |
||||||
|
:type path: str |
||||||
|
|
||||||
|
:param overlay: The name of the command overlay to apply to generated commands. |
||||||
|
:type overlay: str |
||||||
|
|
||||||
|
:rtype: Config | None |
||||||
|
|
||||||
|
kwargs are passed to the configuration class for instantiation. |
||||||
|
|
||||||
|
""" |
||||||
|
if path.endswith(".ini"): |
||||||
|
_config = Config(path, overlay=overlay, **kwargs) |
||||||
|
# elif path.endswith(".yml"): |
||||||
|
# _config = YAML(path, **kwargs) |
||||||
|
else: |
||||||
|
log.warning("Input file format is not currently supported: %s" % path) |
||||||
|
return None |
||||||
|
|
||||||
|
if not _config.load(): |
||||||
|
log.error("Failed to load config file: %s" % path) |
||||||
|
return None |
||||||
|
|
||||||
|
return _config |
@ -1,159 +0,0 @@ |
|||||||
# Imports |
|
||||||
|
|
||||||
from pygments import highlight |
|
||||||
from pygments.lexers import get_lexer_by_name |
|
||||||
from pygments.formatters import get_formatter_by_name |
|
||||||
|
|
||||||
BashLexer = get_lexer_by_name("bash") |
|
||||||
JSONLexer = get_lexer_by_name("json") |
|
||||||
PythonLexer = get_lexer_by_name("python") |
|
||||||
TerminalFormatter = get_formatter_by_name("terminal", linenos=True) |
|
||||||
|
|
||||||
# Exports |
|
||||||
|
|
||||||
__all__ = ( |
|
||||||
"any_list_item", |
|
||||||
"filter_commands", |
|
||||||
"filter_objects", |
|
||||||
"highlight_code", |
|
||||||
"split_csv", |
|
||||||
) |
|
||||||
|
|
||||||
# Functions |
|
||||||
|
|
||||||
|
|
||||||
def any_list_item(a, b): |
|
||||||
"""Determine whether any item in ``a`` also exists in ``b``. |
|
||||||
|
|
||||||
:param a: The first list to be compared. |
|
||||||
:type a: list |
|
||||||
|
|
||||||
:param b: The second list to be compared. |
|
||||||
:type b: list |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
""" |
|
||||||
for i in a: |
|
||||||
for j in b: |
|
||||||
if i == j: |
|
||||||
return True |
|
||||||
|
|
||||||
return False |
|
||||||
|
|
||||||
|
|
||||||
def filter_commands(commands, values, attribute="tags"): |
|
||||||
"""Filter commands for a given set of values. |
|
||||||
|
|
||||||
:param commands: The commands to be filtered. |
|
||||||
:type commands: list[BaseType[Command]] |
|
||||||
|
|
||||||
:param values: The values to be compared. |
|
||||||
:type values: list |
|
||||||
|
|
||||||
:param attribute: The name of the command attribute to check. This attribute must be a list or tuple of values of |
|
||||||
the same type given in ``values``. |
|
||||||
:type attribute: str |
|
||||||
|
|
||||||
:rtype: bool |
|
||||||
|
|
||||||
.. code-block:: python |
|
||||||
|
|
||||||
commands = [ |
|
||||||
AddUser("bob"), |
|
||||||
Apt("apache2", tags=["apache", "www"]), |
|
||||||
Reload("postgresql", tags=["database", "pgsql"]), |
|
||||||
Touch("/var/www/index.html", tags=["www"]), |
|
||||||
] |
|
||||||
|
|
||||||
values = ["apache", "www"] |
|
||||||
|
|
||||||
# Outputs the Apt and Touch commands above. |
|
||||||
filtered_commands = filter_commands(command, values) |
|
||||||
print(filtered_commands) |
|
||||||
|
|
||||||
""" |
|
||||||
filtered = list() |
|
||||||
for command in commands: |
|
||||||
try: |
|
||||||
list_b = getattr(command, attribute) |
|
||||||
except AttributeError: |
|
||||||
continue |
|
||||||
|
|
||||||
if not any_list_item(values, list_b): |
|
||||||
continue |
|
||||||
|
|
||||||
filtered.append(command) |
|
||||||
|
|
||||||
return filtered |
|
||||||
|
|
||||||
|
|
||||||
def filter_objects(objects, environments=None, scope=None, tags=None): |
|
||||||
"""Filter the given objects by the given keys. |
|
||||||
|
|
||||||
:param objects: The objects to be filtered. |
|
||||||
:type objects: list |
|
||||||
|
|
||||||
:param environments: The environments to be included. |
|
||||||
:type environments: list[str] |
|
||||||
|
|
||||||
:param scope: The scope by which to filter; deploy, provision, tenant. |
|
||||||
:type scope: str |
|
||||||
|
|
||||||
:param tags: The tags to be included. |
|
||||||
:type tags: list[str] |
|
||||||
|
|
||||||
:rtype: list |
|
||||||
:returns: Returns the objects that match the given keys. |
|
||||||
|
|
||||||
""" |
|
||||||
filtered = list() |
|
||||||
|
|
||||||
# print("object, object environments, environments, any_list_item") |
|
||||||
|
|
||||||
for o in objects: |
|
||||||
|
|
||||||
# print(o, o.environments, environments, any_list_item(environments, o.environments)) |
|
||||||
|
|
||||||
# Apply environment filter. |
|
||||||
if environments is not None: |
|
||||||
if hasattr(o, "environment"): |
|
||||||
if o.environment is not None and o.environment not in environments: |
|
||||||
continue |
|
||||||
elif hasattr(o, "environments"): |
|
||||||
if type(o.environments) in (list, tuple) and not any_list_item(environments, o.environments): |
|
||||||
continue |
|
||||||
else: |
|
||||||
pass |
|
||||||
|
|
||||||
# # Apply scope filter. |
|
||||||
# if scope is not None: |
|
||||||
# if o.scope not in [None, SCOPE_ALL, scope]: |
|
||||||
# continue |
|
||||||
|
|
||||||
# Apply tag filter. |
|
||||||
if tags is not None: |
|
||||||
if not any_list_item(tags, o.tags): |
|
||||||
continue |
|
||||||
|
|
||||||
# The object has passed the tests above. |
|
||||||
filtered.append(o) |
|
||||||
|
|
||||||
return filtered |
|
||||||
|
|
||||||
|
|
||||||
def highlight_code(string, lexer=None): |
|
||||||
"""Highlight (colorize) the given string as Python code. |
|
||||||
|
|
||||||
:param string: The string to be highlighted. |
|
||||||
:type string: str |
|
||||||
|
|
||||||
:rtype: str |
|
||||||
|
|
||||||
""" |
|
||||||
if lexer is None: |
|
||||||
lexer = BashLexer |
|
||||||
|
|
||||||
return highlight(string, lexer, TerminalFormatter) |
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@ |
|||||||
|
[this command will fail to load] |
||||||
|
nonexistent = testing |
@ -0,0 +1,2 @@ |
|||||||
|
[this command will fail to load] |
||||||
|
run - testing |
@ -0,0 +1,6 @@ |
|||||||
|
[create the site directory] |
||||||
|
mkdir: /var/www/domains/{{ domain_tld }} |
||||||
|
|
||||||
|
[this will cause template parsing to fail] |
||||||
|
touch: /path/to/{% if this.will.break %}testing |
||||||
|
|
@ -0,0 +1,25 @@ |
|||||||
|
[function for setting up apache] |
||||||
|
func = apache_setup |
||||||
|
|
||||||
|
[install apache] |
||||||
|
install: apache2 |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[install wsgi] |
||||||
|
install: mod_wsgi |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[enable wsgi] |
||||||
|
apache.enable_module: mod_wsgi |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[disable the default site] |
||||||
|
apache.disable_site = default |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[restart apache] |
||||||
|
apache: restart |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[call apache setup] |
||||||
|
run: apache_setup |
@ -0,0 +1,192 @@ |
|||||||
|
[update system repos] |
||||||
|
system: update |
||||||
|
|
||||||
|
[upgrade the system] |
||||||
|
system: upgrade |
||||||
|
|
||||||
|
[reboot the system] |
||||||
|
system: reboot |
||||||
|
|
||||||
|
[function for setting up apache] |
||||||
|
func = apache_setup |
||||||
|
|
||||||
|
[install apache] |
||||||
|
install: apache2 |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[install wsgi] |
||||||
|
install: mod_wsgi |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[enable wsgi] |
||||||
|
apache.enable_module: mod_wsgi |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[disable the default site in function] |
||||||
|
apache.disable_site = default |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[restart apache] |
||||||
|
apache: restart |
||||||
|
func: apache_setup |
||||||
|
|
||||||
|
[call apache setup] |
||||||
|
run: apache_setup |
||||||
|
|
||||||
|
[disable the default site] |
||||||
|
apache.disable_site = default |
||||||
|
|
||||||
|
[enable mod SSL] |
||||||
|
apache.enable_module = mod_ssl |
||||||
|
|
||||||
|
[enable more than one apache module at once] |
||||||
|
apache.enable_module = $item |
||||||
|
items = mod_wsgi, mod_rewrite |
||||||
|
|
||||||
|
[make sure apache can be reloaded] |
||||||
|
apache: test |
||||||
|
|
||||||
|
[restart apache outside of function] |
||||||
|
apache: restart |
||||||
|
condition: $apache_checks_out -eq 0 |
||||||
|
|
||||||
|
[install the virtualenv package] |
||||||
|
pip = virtualenv |
||||||
|
|
||||||
|
[install django debug toolbar] |
||||||
|
pip: django-debug-toolbar |
||||||
|
env: development |
||||||
|
tags: python, project |
||||||
|
|
||||||
|
[create a virtual environment] |
||||||
|
virtualenv = python |
||||||
|
cd = /path/to/project |
||||||
|
tags = python, project |
||||||
|
|
||||||
|
[install pillow] |
||||||
|
pip = Pillow |
||||||
|
cd = /path/to/project |
||||||
|
upgrade = yes |
||||||
|
venv = python |
||||||
|
tags = python, project |
||||||
|
|
||||||
|
[apply database migrations] |
||||||
|
django: migrate |
||||||
|
cd: /path/to/project |
||||||
|
venv: python |
||||||
|
|
||||||
|
[run a custom django command] |
||||||
|
django = custom_command arg1 arg2 |
||||||
|
cd = /path/to/project |
||||||
|
venv = python |
||||||
|
settings = tenants.example_app.settings |
||||||
|
quiet = yes |
||||||
|
|
||||||
|
[collect the project's static files] |
||||||
|
django: collectstatic |
||||||
|
cd: /path/to/project |
||||||
|
venv: python |
||||||
|
|
||||||
|
[load data fixtures] |
||||||
|
django.loaddata: categories |
||||||
|
cd: /path/to/project |
||||||
|
venv: python |
||||||
|
|
||||||
|
[dump data fixtures] |
||||||
|
django.dumpdata: projects |
||||||
|
cd: /path/to/project |
||||||
|
venv: python |
||||||
|
|
||||||
|
[reload a service] |
||||||
|
reload: postfix |
||||||
|
|
||||||
|
[restart a service] |
||||||
|
restart: postfix |
||||||
|
|
||||||
|
[stop a service] |
||||||
|
stop: postfix |
||||||
|
|
||||||
|
[start a service] |
||||||
|
start: postfix |
||||||
|
|
||||||
|
[install a package] |
||||||
|
install: python3 |
||||||
|
|
||||||
|
[remove a package] |
||||||
|
uninstall: apache-top |
||||||
|
|
||||||
|
[add to a file] |
||||||
|
append: /path/to/file.txt |
||||||
|
content: this is a test |
||||||
|
|
||||||
|
[copy a file] |
||||||
|
copy: /path/to/file.txt /new/path/to/file.txt |
||||||
|
|
||||||
|
[write (overwrite) a file] |
||||||
|
write: /path/to/file.txt |
||||||
|
content: this replaces all text in the file |
||||||
|
|
||||||
|
[create a directory] |
||||||
|
mkdir: /path/to/dir |
||||||
|
mode: 755 |
||||||
|
|
||||||
|
[move a file] |
||||||
|
move: /path/to/file.txt /path/to/file.txt.b |
||||||
|
|
||||||
|
[set permissions on a file] |
||||||
|
perms: /path/to/file.txt |
||||||
|
group: www-data |
||||||
|
mode: 755 |
||||||
|
owner: deploy |
||||||
|
recursive: yes |
||||||
|
|
||||||
|
[remove a file] |
||||||
|
remove: /path/to/file.txt |
||||||
|
|
||||||
|
[sync a directory] |
||||||
|
rsync: /path/to/source /path/to/target |
||||||
|
|
||||||
|
[copy a file to remote server] |
||||||
|
scopy: /path/to/file.txt /path/to/server/file.txt |
||||||
|
host: example.com |
||||||
|
|
||||||
|
[replace text in a file] |
||||||
|
sed: /path/to/file.txt |
||||||
|
find: logging = no |
||||||
|
replace: logging = yes |
||||||
|
|
||||||
|
[create a symlink] |
||||||
|
symlink: /var/www/domains |
||||||
|
|
||||||
|
[touch a file] |
||||||
|
touch: /path/to/file.txt |
||||||
|
|
||||||
|
[create a postgres user/role] |
||||||
|
pg.user: example_app |
||||||
|
|
||||||
|
[create a postgres database] |
||||||
|
pg.db: example_app |
||||||
|
owner: example_app |
||||||
|
|
||||||
|
[determine whether a postgres database exists] |
||||||
|
pg.database_exists: example_app |
||||||
|
|
||||||
|
[export a postgres database] |
||||||
|
pg.dump: testing |
||||||
|
|
||||||
|
[drop a postgres user/role] |
||||||
|
pg.dropuser: testing |
||||||
|
|
||||||
|
[drop a postgres database] |
||||||
|
pg.dropdb: testing |
||||||
|
|
||||||
|
[run an SQL command on a postgres database] |
||||||
|
psql: "SELECT * FROM projects WHERE category = 'testing'" |
||||||
|
database: example_app |
||||||
|
owner: example_app |
||||||
|
|
||||||
|
[create a file archive] |
||||||
|
archive: /var/www/domains/example_com |
||||||
|
|
||||||
|
[extract a file archive] |
||||||
|
extract: /var/www/domains/example_com.tgz |
@ -1,12 +1,15 @@ |
|||||||
[install the virtualenv package] |
[install the virtualenv package] |
||||||
pip = virtualenv |
pip = virtualenv |
||||||
|
tags = python-support |
||||||
|
|
||||||
[create a virtual environment] |
[create a virtual environment] |
||||||
virtualenv = python |
virtualenv = python |
||||||
cd = /path/to/project |
cd = /path/to/project |
||||||
|
tags = python-support |
||||||
|
|
||||||
[install pillow] |
[install pillow] |
||||||
pip = Pillow |
pip = Pillow |
||||||
cd = /path/to/project |
cd = /path/to/project |
||||||
upgrade = yes |
upgrade = yes |
||||||
venv = python |
venv = python |
||||||
|
tags = depends |
@ -0,0 +1,2 @@ |
|||||||
|
[create the site directory] |
||||||
|
mkdir: /var/www/domains/{{ domain_tld }} |
@ -0,0 +1,40 @@ |
|||||||
|
from scripttease.library.commands import Command, ItemizedCommand |
||||||
|
from scripttease.factory import Factory |
||||||
|
|
||||||
|
|
||||||
|
class TestFactory(object): |
||||||
|
|
||||||
|
def test_get_command(self): |
||||||
|
f = Factory("ubuntu") |
||||||
|
f.load() |
||||||
|
|
||||||
|
# Non-existent command. |
||||||
|
c = f.get_command("nonexistent") |
||||||
|
assert c is None |
||||||
|
|
||||||
|
# A good command with itemized parameters. |
||||||
|
c = f.get_command( |
||||||
|
"pip", |
||||||
|
"$item", |
||||||
|
items=["Pillow", "psycopg2-binary", "django"] |
||||||
|
) |
||||||
|
assert isinstance(c, ItemizedCommand) |
||||||
|
|
||||||
|
# A good, normal command. |
||||||
|
c = f.get_command("pip", "django") |
||||||
|
assert isinstance(c, Command) |
||||||
|
|
||||||
|
# Command exists, but given bad arguments. |
||||||
|
c = f.get_command("pip") |
||||||
|
assert c is None |
||||||
|
|
||||||
|
def test_load(self): |
||||||
|
f = Factory("nonexistent") |
||||||
|
assert f.load() is False |
||||||
|
|
||||||
|
f = Factory("ubuntu") |
||||||
|
assert f.load() is True |
||||||
|
|
||||||
|
def test_repr(self): |
||||||
|
f = Factory("centos") |
||||||
|
assert repr(f) == "<Factory centos>" |
@ -1,20 +0,0 @@ |
|||||||
from scripttease.library.commands import command_factory, ItemizedCommand |
|
||||||
from scripttease.library.commands.python import Pip |
|
||||||
from scripttease.library.overlays import Overlay |
|
||||||
|
|
||||||
|
|
||||||
def test_command_factory(): |
|
||||||
overlay = Overlay("ubuntu") |
|
||||||
overlay.load() |
|
||||||
|
|
||||||
command = command_factory("nonexistent", "non existent command", overlay) |
|
||||||
assert command is None |
|
||||||
|
|
||||||
command = command_factory("pip", "install pillow", overlay) |
|
||||||
assert command is None |
|
||||||
|
|
||||||
command = command_factory("pip", "install pillow", overlay, "Pillow") |
|
||||||
assert isinstance(command, Pip) |
|
||||||
|
|
||||||
command = command_factory("pip", "install various", overlay, "$item", items=["Pillow", "pyscopg2-binary", "django"]) |
|
||||||
assert isinstance(command, ItemizedCommand) |
|
@ -1,18 +0,0 @@ |
|||||||
from scripttease.library.commands.python import * |
|
||||||
from scripttease.library.overlays import Overlay |
|
||||||
|
|
||||||
|
|
||||||
def test_pip(): |
|
||||||
pip = Pip("Pillow") |
|
||||||
assert "pip install -y Pillow" in pip.get_statement() |
|
||||||
|
|
||||||
overlay = Overlay("ubuntu") |
|
||||||
overlay.load() |
|
||||||
|
|
||||||
pip = Pip("Pillow", op="remove", overlay=overlay, venv="python") |
|
||||||
assert "source python/bin/activate && pip3 uninstall --quiet Pillow" in pip.get_statement() |
|
||||||
|
|
||||||
|
|
||||||
def test_virtualenv(): |
|
||||||
virt = VirtualEnv() |
|
||||||
assert "virtualenv python" in virt.get_statement() |
|
@ -0,0 +1,17 @@ |
|||||||
|
from scripttease.library.overlays.common import * |
||||||
|
|
||||||
|
|
||||||
|
def test_python_pip(): |
||||||
|
c = python_pip("Pillow") |
||||||
|
assert "pip install -y Pillow" in c.get_statement() |
||||||
|
|
||||||
|
c = python_pip("Pillow", upgrade=True) |
||||||
|
assert "--upgrade" in c.get_statement() |
||||||
|
|
||||||
|
c = python_pip("Pillow", venv="python") |
||||||
|
assert "source python/bin/activate" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_python_virtual_env(): |
||||||
|
c = python_virtualenv() |
||||||
|
assert "virtualenv python" in c.get_statement() |
@ -0,0 +1,61 @@ |
|||||||
|
from scripttease.library.overlays.django import * |
||||||
|
|
||||||
|
|
||||||
|
def test_django(): |
||||||
|
c = django("check") |
||||||
|
assert "./manage.py check" in c.get_statement() |
||||||
|
|
||||||
|
c = django("collectstatic") |
||||||
|
assert "./manage.py collectstatic" in c.get_statement() |
||||||
|
|
||||||
|
c = django("migrate") |
||||||
|
assert "./manage.py migrate" in c.get_statement() |
||||||
|
|
||||||
|
c = django("custom", "arg1", "arg2", venv="python", settings="tenants.example.settings", quiet=True) |
||||||
|
s = c.get_statement() |
||||||
|
assert "./manage.py custom" in s |
||||||
|
assert "arg1" in s |
||||||
|
assert "arg2" in s |
||||||
|
assert "--settings=" in s |
||||||
|
assert "source python/bin/activate" in s |
||||||
|
assert "--quiet" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_django_check(): |
||||||
|
c = django_check(venv="python") |
||||||
|
s = c.get_statement() |
||||||
|
assert "./manage.py check" in s |
||||||
|
assert "source python/bin/activate" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_django_collect_static(): |
||||||
|
c = django_collect_static(venv="python") |
||||||
|
s = c.get_statement() |
||||||
|
assert "./manage.py collectstatic" in s |
||||||
|
assert "source python/bin/activate" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_django_dumpdata(): |
||||||
|
c = django_dumpdata("projects") |
||||||
|
s = c.get_statement() |
||||||
|
assert "./manage.py dumpdata" in s |
||||||
|
assert "projects >" in s |
||||||
|
assert "--format=json" in s |
||||||
|
assert "--indent=4" in s |
||||||
|
assert "local/projects/fixtures/initial.json" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_django_loaddata(): |
||||||
|
c = django_loaddata("projects") |
||||||
|
s = c.get_statement() |
||||||
|
print(s) |
||||||
|
assert "./manage.py loaddata" in s |
||||||
|
assert "local/projects/fixtures/initial.json" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_django_migrate(): |
||||||
|
c = django_migrate(cd="/path/to/project/", venv="python") |
||||||
|
s = c.get_statement(cd=True) |
||||||
|
assert "./manage.py migrate" in s |
||||||
|
assert "source python/bin/activate" in s |
||||||
|
assert "cd /path/to/project/" in s |
@ -0,0 +1,60 @@ |
|||||||
|
from scripttease.library.overlays.pgsql import * |
||||||
|
|
||||||
|
|
||||||
|
def test_pg_create_database(): |
||||||
|
c = pg_create_database("testing", admin_pass="secret", template="mytemplate") |
||||||
|
s = c.get_statement() |
||||||
|
assert "createdb" in s |
||||||
|
assert "export PGPASSWORD=" in s |
||||||
|
assert "--host=" in s |
||||||
|
assert "--port=" in s |
||||||
|
assert "--username=" in s |
||||||
|
assert "--owner=" in s |
||||||
|
assert "--template=mytemplate" in s |
||||||
|
assert "testing" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_pg_create_user(): |
||||||
|
c = pg_create_user("testing", password="secret") |
||||||
|
s = c.get_statement() |
||||||
|
assert "createuser" in s |
||||||
|
assert "-DRS" in s |
||||||
|
assert "testing" in s |
||||||
|
assert "ALTER USER testing" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_pg_database_exists(): |
||||||
|
c = pg_database_exists("testing") |
||||||
|
s = c.get_statement() |
||||||
|
assert "psql" in s |
||||||
|
assert "testing_db_exists" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_pg_drop_database(): |
||||||
|
c = pg_drop_database("testing") |
||||||
|
s = c.get_statement() |
||||||
|
assert "dropdb" in s |
||||||
|
assert "testing" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_pg_drop_user(): |
||||||
|
c = pg_drop_user("testing") |
||||||
|
s = c.get_statement() |
||||||
|
assert "dropuser" in s |
||||||
|
assert "testing" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_pg_dump_database(): |
||||||
|
c = pg_dump_database("testing") |
||||||
|
s = c.get_statement() |
||||||
|
assert "pg_dump" in s |
||||||
|
assert "--column-inserts" in s |
||||||
|
assert "--file=testing.sql" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_psql(): |
||||||
|
c = psql("SELECT * FROM projects", database="testing") |
||||||
|
s = c.get_statement() |
||||||
|
assert "psql" in s |
||||||
|
assert "--dbname=testing" in s |
||||||
|
assert '-c "SELECT * FROM projects"' in s |
@ -0,0 +1,209 @@ |
|||||||
|
import pytest |
||||||
|
from scripttease.library.overlays.posix import * |
||||||
|
|
||||||
|
|
||||||
|
def test_archive(): |
||||||
|
c = archive( |
||||||
|
"/path/to/target", |
||||||
|
absolute=True, |
||||||
|
exclude="*.log", |
||||||
|
strip=1, |
||||||
|
view=True |
||||||
|
) |
||||||
|
s = c.get_statement() |
||||||
|
print(s) |
||||||
|
# tar -czPv --exclude *.log --strip-components 1 -f ./archive.tgz /path/to/target |
||||||
|
assert "tar -czPv --exclude *.log --strip-components 1" in s |
||||||
|
assert "-f ./archive.tgz /path/to/target" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_certbot(): |
||||||
|
with pytest.raises(ValueError): |
||||||
|
c = certbot("example.com") |
||||||
|
|
||||||
|
c = certbot("example.com", email="webmaster@example.com") |
||||||
|
s = c.get_statement() |
||||||
|
assert "certbot certonly --agree-tos --email webmaster@example.com -n" in s |
||||||
|
assert "--webroot -w /var/www/domains/example_com/www -d example.com" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_extract(): |
||||||
|
c = extract( |
||||||
|
"/path/to/archive.tgz", |
||||||
|
absolute=True, |
||||||
|
exclude="*.log", |
||||||
|
strip=1, |
||||||
|
view=True |
||||||
|
) |
||||||
|
s = c.get_statement() |
||||||
|
assert "tar -xzPv --exclude *.log --strip-components 1" in s |
||||||
|
assert "-f /path/to/archive.tgz ./" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_file_append(): |
||||||
|
c = file_append("/path/to/file.txt", content="testing = yes") |
||||||
|
assert 'echo "testing = yes" >> /path/to/file.txt' in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_file_copy(): |
||||||
|
c = file_copy("/path/to/file.txt", "/path/to/new-file.txt") |
||||||
|
s = c.get_statement() |
||||||
|
assert "cp" in s |
||||||
|
assert "-n" in s |
||||||
|
assert "/path/to/file.txt /path/to/new-file.txt" in s |
||||||
|
|
||||||
|
c = file_copy("/path/to/dir", "/path/to/newdir", recursive=True) |
||||||
|
s = c.get_statement() |
||||||
|
assert "cp" in s |
||||||
|
assert "-R" in s |
||||||
|
assert "/path/to/dir /path/to/newdir" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_file_write(): |
||||||
|
c = file_write("/path/to/file.txt", content="testing 123") |
||||||
|
assert 'echo "testing 123" > /path/to/file.txt' in c.get_statement() |
||||||
|
|
||||||
|
content = [ |
||||||
|
"I am testing", |
||||||
|
"I am testing", |
||||||
|
"I am testing", |
||||||
|
"testing 123", |
||||||
|
] |
||||||
|
c = file_write("/path/to/file.txt", content="\n".join(content)) |
||||||
|
s = c.get_statement() |
||||||
|
assert "cat > /path/to/file.txt << EOF" in s |
||||||
|
assert "I am testing" in s |
||||||
|
assert "testing 123" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_mkdir(): |
||||||
|
c = mkdir("/path/to/dir", mode=755, recursive=True) |
||||||
|
s = c.get_statement() |
||||||
|
assert "mkdir" in s |
||||||
|
assert "-m 755" in s |
||||||
|
assert "-p" in s |
||||||
|
assert "/path/to/dir" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_move(): |
||||||
|
c = move("/path/to/file.txt", "/path/to/file.txt.b") |
||||||
|
assert "mv /path/to/file.txt /path/to/file.txt.b" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_perms(): |
||||||
|
c = perms("/path/to/dir", group="www-data", mode=755, owner="deploy", recursive=True) |
||||||
|
s = c.get_statement() |
||||||
|
assert "chgrp -R www-data /path/to/dir" in s |
||||||
|
assert "chown -R deploy /path/to/dir" in s |
||||||
|
assert "chmod -R 755 /path/to/dir" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_remove(): |
||||||
|
c = remove("/path/to/dir", force=True, recursive=True) |
||||||
|
s = c.get_statement() |
||||||
|
assert "rm" in s |
||||||
|
assert "-f" in s |
||||||
|
assert "-r" in s |
||||||
|
assert "/path/to/dir" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_rsync(): |
||||||
|
c = rsync( |
||||||
|
"/path/to/local/", |
||||||
|
"/path/to/remote", |
||||||
|
links=True, |
||||||
|
delete=True, |
||||||
|
exclude="deploy/exclude.txt", |
||||||
|
recursive=True, |
||||||
|
host="example.com", |
||||||
|
key_file="~/.ssh/deploy", |
||||||
|
user="deploy" |
||||||
|
) |
||||||
|
s = c.get_statement() |
||||||
|
assert "rsync --cvs-exclude --checksum --compress --copy-links --delete" in s |
||||||
|
assert "--exclude-from=deploy/exclude.txt" in s |
||||||
|
assert "-P" in s |
||||||
|
assert "--recursive /path/to/local/" in s |
||||||
|
assert '-e "ssh -i ~/.ssh/deploy -p 22"' in s |
||||||
|
assert "deploy@example.com:/path/to/remote" in s |
||||||
|
|
||||||
|
c = rsync( |
||||||
|
"/path/to/local/", |
||||||
|
"/path/to/remote", |
||||||
|
links=True, |
||||||
|
delete=True, |
||||||
|
exclude="deploy/exclude.txt", |
||||||
|
recursive=True, |
||||||
|
) |
||||||
|
s = c.get_statement() |
||||||
|
assert "rsync --cvs-exclude --checksum --compress --copy-links --delete" in s |
||||||
|
assert "--exclude-from=deploy/exclude.txt" in s |
||||||
|
assert "-P" in s |
||||||
|
assert "--recursive" in s |
||||||
|
assert "/path/to/local/" in s |
||||||
|
assert "/path/to/remote" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_run(): |
||||||
|
c = run("ls -ls") |
||||||
|
assert "ls -ls" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_scopy(): |
||||||
|
with pytest.raises(ValueError): |
||||||
|
c = scopy("/path/to/local/file.txt", "/path/to/remote/file.txt") |
||||||
|
|
||||||
|
c = scopy( |
||||||
|
"/path/to/local/file.txt", |
||||||
|
"/path/to/remote/file.txt", |
||||||
|
key_file="~/.ssh/deploy", |
||||||
|
host="example.com", |
||||||
|
user="deploy" |
||||||
|
) |
||||||
|
s = c.get_statement() |
||||||
|
assert "scp -i ~/.ssh/deploy" in s |
||||||
|
assert "-P 22" in s |
||||||
|
assert "/path/to/local/file.txt" in s |
||||||
|
assert "deploy@example.com:/path/to/remote/file.txt" in s |
||||||
|
|
||||||
|
c = scopy( |
||||||
|
"/path/to/local/file.txt", |
||||||
|
"/path/to/remote/file.txt", |
||||||
|
host="example.com", |
||||||
|
) |
||||||
|
s = c.get_statement() |
||||||
|
assert "scp -P 22" in s |
||||||
|
assert "/path/to/local/file.txt" in s |
||||||
|
assert "example.com:/path/to/remote/file.txt" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_sed(): |
||||||
|
c = sed("/path/to/file.txt", find="testing", replace="123") |
||||||
|
s = c.get_statement() |
||||||
|
assert "sed -i .b" in s |
||||||
|
assert "s/testing/123/g" in s |
||||||
|
assert "/path/to/file.txt" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_symlink(): |
||||||
|
c = symlink("/var/www/domains", force=True) |
||||||
|
s = c.get_statement() |
||||||
|
assert "ln -s" in s |
||||||
|
assert "-f" in s |
||||||
|
assert "/var/www/domains" in s |
||||||
|
|
||||||
|
|
||||||
|
def test_touch(): |
||||||
|
c = touch("/path/to/file.txt") |
||||||
|
assert "touch /path/to/file.txt" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
class TestFunction(object): |
||||||
|
|
||||||
|
def test_to_string(self): |
||||||
|
f = Function("testing", comment="A test function.") |
||||||
|
f.commands.append(touch("/path/to/file.txt")) |
||||||
|
s = f.to_string() |
||||||
|
assert "# A test function." in s |
||||||
|
assert "function testing()" in s |
||||||
|
assert "touch /path/to/file.txt" in s |
@ -0,0 +1,86 @@ |
|||||||
|
import pytest |
||||||
|
from scripttease.library.overlays.ubuntu import * |
||||||
|
|
||||||
|
|
||||||
|
def test_apache(): |
||||||
|
c = apache("reload") |
||||||
|
assert "service apache2 reload" in c.get_statement() |
||||||
|
|
||||||
|
c = apache("restart") |
||||||
|
assert "service apache2 restart" in c.get_statement() |
||||||
|
|
||||||
|
c = apache("start") |
||||||
|
assert "service apache2 start" in c.get_statement() |
||||||
|
|
||||||
|
c = apache("stop") |
||||||
|
assert "service apache2 stop" in c.get_statement() |
||||||
|
|
||||||
|
c = apache("test") |
||||||
|
assert "apachectl configtest" in c.get_statement() |
||||||
|
|
||||||
|
with pytest.raises(NameError): |
||||||
|
apache("nonexistent") |
||||||
|
|
||||||
|
|
||||||
|
def test_apache_disable_module(): |
||||||
|
c = apache_disable_module("mod_ssl") |
||||||
|
assert "a2dismod mod_ssl" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_apache_disable_site(): |
||||||
|
c = apache_disable_site("default") |
||||||
|
assert "a2dissite default" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_apache_enable_module(): |
||||||
|
c = apache_enable_module("mod_wsgi") |
||||||
|
assert "a2enmod mod_wsgi" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_apache_enable_site(): |
||||||
|
c = apache_enable_site("example.com") |
||||||
|
assert "a2ensite example.com" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_service_reload(): |
||||||
|
c = service_reload("postfix") |
||||||
|
assert "service postfix reload" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_service_restart(): |
||||||
|
c = service_restart("postfix") |
||||||
|
assert "service postfix restart" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_service_start(): |
||||||
|
c = service_start("postfix") |
||||||
|
assert "service postfix start" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_service_stop(): |
||||||
|
c = service_stop("postfix") |
||||||
|
assert "service postfix stop" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_system(): |
||||||
|
c = system("reboot") |
||||||
|
assert "reboot" in c.get_statement() |
||||||
|
|
||||||
|
c = system("update") |
||||||
|
assert "apt-get update -y" in c.get_statement() |
||||||
|
|
||||||
|
c = system("upgrade") |
||||||
|
assert "apt-get upgrade -y" in c.get_statement() |
||||||
|
|
||||||
|
with pytest.raises(NameError): |
||||||
|
system("nonexistent") |
||||||
|
|
||||||
|
|
||||||
|
def test_system_install(): |
||||||
|
c = system_install("vim") |
||||||
|
assert "apt-get install -y vim" in c.get_statement() |
||||||
|
|
||||||
|
|
||||||
|
def test_system_uninstall(): |
||||||
|
c = system_uninstall("lftp") |
||||||
|
assert "apt-get uninstall -y lftp" in c.get_statement() |
@ -0,0 +1,31 @@ |
|||||||
|
from scripttease.library.commands import Command, ItemizedCommand |
||||||
|
from scripttease.library.overlays.posix import Function |
||||||
|
from scripttease.library.scripts import Script |
||||||
|
|
||||||
|
|
||||||
|
class TestScript(object): |
||||||
|
|
||||||
|
def test_append(self): |
||||||
|
s = Script("testing") |
||||||
|
s.append(Command("ls -ls", comment="list some stuff")) |
||||||
|
s.append(Command("touch /path/to/file.txt", comment="touch a file")) |
||||||
|
s.append(Command("ln -s /path/to/file.txt", comment="link to a file")) |
||||||
|
|
||||||
|
assert len(s.commands) == 3 |
||||||
|
|
||||||
|
def test_to_string(self): |
||||||
|
s = Script("testing") |
||||||
|
s.append(Command("ls -ls", comment="list some stuff")) |
||||||
|
s.append(Command("touch /path/to/file.txt", comment="touch a file")) |
||||||
|
s.append(Command("ln -s /path/to/file.txt", comment="link to a file")) |
||||||
|
|
||||||
|
s.functions = list() |
||||||
|
s.functions.append(Function("testing")) |
||||||
|
|
||||||
|
output = s.to_string() |
||||||
|
assert output == str(s) |
||||||
|
|
||||||
|
assert "ls -ls" in output |
||||||
|
assert "touch /path/to/file.txt" in output |
||||||
|
assert "ln -s /path/to/file.txt" in output |
||||||
|
assert "function testing()" in output |
@ -1,19 +0,0 @@ |
|||||||
from scripttease.library.overlays import Overlay |
|
||||||
|
|
||||||
|
|
||||||
class TestOverlay(object): |
|
||||||
|
|
||||||
def test_get(self): |
|
||||||
overlay = Overlay("ubuntu") |
|
||||||
overlay.load() |
|
||||||
assert overlay.get("nonexistent", "nonexistent") is None |
|
||||||
|
|
||||||
def test_has(self): |
|
||||||
overlay = Overlay("ubuntu") |
|
||||||
overlay.load() |
|
||||||
assert overlay.has("nonexistent", "nonexistent") is False |
|
||||||
assert overlay.has("python", "nonexistent") is False |
|
||||||
|
|
||||||
def test_load(self): |
|
||||||
overlay = Overlay("nonexistent") |
|
||||||
assert overlay.load() is False |
|
@ -0,0 +1,22 @@ |
|||||||
|
import pytest |
||||||
|
from scripttease.library.scripts import Script |
||||||
|
# from scripttease.parsers import filter_commands, load_commands |
||||||
|
from scripttease.parsers.base import Parser |
||||||
|
|
||||||
|
|
||||||
|
class TestParser(object): |
||||||
|
|
||||||
|
def test_as_script(self): |
||||||
|
p = Parser("/path/to/nonexistent.txt") |
||||||
|
assert isinstance(p.as_script(), Script) |
||||||
|
|
||||||
|
# def test_get_commands(self): |
||||||
|
# pass |
||||||
|
# |
||||||
|
# def test_get_functions(self): |
||||||
|
# pass |
||||||
|
|
||||||
|
def test_load(self): |
||||||
|
p = Parser("/path/to/nonexistent.txt") |
||||||
|
with pytest.raises(NotImplementedError): |
||||||
|
p.load() |
@ -0,0 +1,45 @@ |
|||||||
|
import pytest |
||||||
|
from scripttease.parsers.ini import Config |
||||||
|
|
||||||
|
|
||||||
|
class TestConfig(object): |
||||||
|
|
||||||
|
def test_get_commands(self): |
||||||
|
c = Config("tests/examples/kitchen_sink.ini") |
||||||
|
assert c.load() is True |
||||||
|
|
||||||
|
assert len(c.get_commands()) > 0 |
||||||
|
|
||||||
|
def test_get_functions(self): |
||||||
|
c = Config("tests/examples/kitchen_sink.ini") |
||||||
|
assert c.load() is True |
||||||
|
|
||||||
|
assert len(c.get_functions()) > 0 |
||||||
|
|
||||||
|
def test_load(self): |
||||||
|
c = Config("nonexistent.ini") |
||||||
|
assert c.load() is False |
||||||
|
|
||||||
|
c = Config("tests/examples/python_examples.ini", overlay="nonexistent") |
||||||
|
assert c.load() is False |
||||||
|
|
||||||
|
c = Config("tests/examples/bad_examples.ini") |
||||||
|
assert c.load() is False |
||||||
|
|
||||||
|
c = Config("tests/examples/kitchen_sink.ini") |
||||||
|
assert c.load() is True |
||||||
|
|
||||||
|
c = Config("tests/examples/bad_command.ini") |
||||||
|
assert c.load() is False |
||||||
|
|
||||||
|
context = { |
||||||
|
'domain_tld': "example_com", |
||||||
|
} |
||||||
|
c = Config("tests/examples/template_example.ini", context=context) |
||||||
|
assert c.load() is True |
||||||
|
|
||||||
|
context = { |
||||||
|
'domain_tld': "example_com", |
||||||
|
} |
||||||
|
c = Config("tests/examples/bad_template_example.ini", context=context) |
||||||
|
assert c.load() is False |
@ -0,0 +1,42 @@ |
|||||||
|
import pytest |
||||||
|
from scripttease.library.commands import Command, ItemizedCommand |
||||||
|
from scripttease.parsers import filter_commands, load_commands |
||||||
|
|
||||||
|
|
||||||
|
def test_filter_commands(): |
||||||
|
commands = [ |
||||||
|
Command("apt-get install apache2 -y", environments=["base"], tags=["web"]), |
||||||
|
Command("apt-get install apache-top -y", environments=["live"], tags=["web"]), |
||||||
|
Command("pip install django-debug-toolbar", environments=["development"], tags=["django"]), |
||||||
|
Command("pip install django", environments=["base"], tags=["django"]), |
||||||
|
] |
||||||
|
f1 = filter_commands(commands, environments=["base", "live"]) |
||||||
|
assert len(f1) == 3 |
||||||
|
|
||||||
|
f2 = filter_commands(commands, tags=["django"]) |
||||||
|
assert len(f2) == 2 |
||||||
|
|
||||||
|
f3 = filter_commands(commands, environments=["base", "development"]) |
||||||
|
assert len(f3) == 3 |
||||||
|
|
||||||
|
f4 = filter_commands(commands, environments=["base"], tags=["web"]) |
||||||
|
assert len(f4) == 1 |
||||||
|
|
||||||
|
|
||||||
|
def test_load_commands(): |
||||||
|
commands = load_commands("nonexistent.xml") |
||||||
|
assert commands is None |
||||||
|
|
||||||
|
commands = load_commands("nonexistent.ini") |
||||||
|
assert commands is None |
||||||
|
|
||||||
|
commands = load_commands("tests/examples/bad_examples.ini") |
||||||
|
assert commands is None |
||||||
|
|
||||||
|
commands = load_commands( |
||||||
|
"tests/examples/python_examples.ini", |
||||||
|
filters={ |
||||||
|
'tags': ["python-support"], |
||||||
|
} |
||||||
|
) |
||||||
|
assert len(commands) == 2 |
Loading…
Reference in new issue