feat: Update template
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"template": "https://github.com/lkubb/salt-template-formula",
|
"template": "https://github.com/lkubb/salt-template-formula",
|
||||||
"commit": "09d23d7be4069023a5dd2201c3db5b82049391a1",
|
"commit": "ec0d8da5021bc9320ca1270e582ab9ac604f2ad7",
|
||||||
"checkout": null,
|
"checkout": null,
|
||||||
"context": {
|
"context": {
|
||||||
"cookiecutter": {
|
"cookiecutter": {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
# See https://pre-commit.com for more information
|
# See https://pre-commit.com for more information
|
||||||
@@ -67,6 +66,15 @@ repos:
|
|||||||
require_serial: true
|
require_serial: true
|
||||||
always_run: true
|
always_run: true
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: render_readme
|
||||||
|
name: Render available states in README.rst.tpl
|
||||||
|
entry: ./bin/render_readme
|
||||||
|
language: system
|
||||||
|
require_serial: true
|
||||||
|
always_run: true
|
||||||
|
pass_filenames: false
|
||||||
- repo: https://github.com/myint/rstcheck
|
- repo: https://github.com/myint/rstcheck
|
||||||
rev: 3f929574
|
rev: 3f929574
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
# General overrides used across formulas in the org
|
# General overrides used across formulas in the org
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
exclude_paths: []
|
exclude_paths: []
|
||||||
@@ -6,9 +5,5 @@ rules: {}
|
|||||||
skip_list:
|
skip_list:
|
||||||
# Using `salt-lint` for linting other files as well, such as Jinja macros/templates
|
# Using `salt-lint` for linting other files as well, such as Jinja macros/templates
|
||||||
- 205 # Use ".sls" as a Salt State file extension
|
- 205 # Use ".sls" as a Salt State file extension
|
||||||
# Skipping `207` and `208` because `210` is sufficient, at least for the time-being
|
|
||||||
# I.e. Allows 3-digit unquoted codes to still be used, such as `644` and `755`
|
|
||||||
- 207 # File modes should always be encapsulated in quotation marks
|
|
||||||
- 208 # File modes should always contain a leading zero
|
|
||||||
tags: []
|
tags: []
|
||||||
verbosity: 1
|
verbosity: 1
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
# Extend the `default` configuration provided by `yamllint`
|
# Extend the `default` configuration provided by `yamllint`
|
||||||
|
|||||||
8
bin/render_readme
Executable file
8
bin/render_readme
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# This inserts the rendered state docs into the readme.
|
||||||
|
# Avoids issues with rendering the final readme on Gitea etc.
|
||||||
|
sed '/<INSERT_STATES>/{
|
||||||
|
s/<INSERT_STATES>//g
|
||||||
|
r docs/states.rst
|
||||||
|
}' docs/README.rst.tpl > docs/README.rst
|
||||||
471
bin/slsdoc
471
bin/slsdoc
@@ -1,23 +1,86 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
"""
|
'''
|
||||||
This script renders Jinja comments found at the beginning
|
This script renders Jinja comments found at the beginning
|
||||||
of `.sls` files.
|
of `.sls` files as state documentation.
|
||||||
|
|
||||||
Since this was written for the salt tool suite,
|
The code is horrible, but I'm too lazy to rewrite it properly
|
||||||
it should be placed in a sibling directory
|
because it works for my use cases. There will likely be a lot of bugs.
|
||||||
of a directory named tool_<something> containing
|
|
||||||
the actual states to be able autodiscover them.
|
|
||||||
|
|
||||||
Of course, it can be used by other formulae by manually
|
Full configuration in ``pyproject.toml`` with defaults:
|
||||||
providing the root path and I might publish this at some
|
|
||||||
point as a python module or at least in a separate repo
|
[tool.slsdoc]
|
||||||
to be used by pre-commit. It would need to be configurable
|
# Choose which renderer to use. `single` or `depth`
|
||||||
without editing the source code for that. @TODO
|
renderer = "single"
|
||||||
|
# Also list states without documentation
|
||||||
|
include_empty = false
|
||||||
|
# Path prefixes to ignore, relative to formula root
|
||||||
|
ignore = ["_mapdata"]
|
||||||
|
# Given a directory with `package.init`, `package.install`
|
||||||
|
# and `package.clean`, only dump init and clean.
|
||||||
|
avoid_init_dup = True
|
||||||
|
# By default, states are ordered alphabetically, but init
|
||||||
|
# always comes first and all clean states are separated.
|
||||||
|
# This overrides the purely alphabetical order for the roots.
|
||||||
|
sort_list = ["init", "clean", "package", "config", "service"]
|
||||||
|
|
||||||
|
[tool.slsdoc.single_renderer]
|
||||||
|
# Include init.sls files in state list
|
||||||
|
init = true
|
||||||
|
# Include .init suffix in when init is true
|
||||||
|
init_suffix = false
|
||||||
|
# Include clean.sls files in state list
|
||||||
|
clean = true
|
||||||
|
# When rendering with prefix `settings.something`,
|
||||||
|
# write `else` instead of `settings.something.else`
|
||||||
|
cut_prefix = false
|
||||||
|
# Write `salt.package` instead of `package` when formula root == `salt`
|
||||||
|
include_formula_root = true
|
||||||
|
# Default .rst main header, when not defined in root init.sls
|
||||||
|
default_header = "Available States"
|
||||||
|
# Header, overrides everything
|
||||||
|
header = ""
|
||||||
|
# Description, overrides everything
|
||||||
|
description = ""
|
||||||
|
# Default description, when init.sls is empty
|
||||||
|
default_description = """
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
"""
|
"""
|
||||||
|
# Always append default description, regardless of
|
||||||
|
# presence in init.sls
|
||||||
|
always_include_default_description = false
|
||||||
|
# Character to use to underline main headings
|
||||||
|
main_heading_char = "="
|
||||||
|
# Character to use to underline sub headings
|
||||||
|
sub_heading_char = "^"
|
||||||
|
"""
|
||||||
|
# File to write to
|
||||||
|
target = "docs/states.rst"
|
||||||
|
|
||||||
|
[tool.slsdoc.depth_renderer]
|
||||||
|
# maxdepth for generated index.rst files (toctree)
|
||||||
|
index_maxdepth = 4
|
||||||
|
# Directory to write to
|
||||||
|
target = "docs/states"
|
||||||
|
|
||||||
|
[tool.slsdoc.depth_renderer.single_opts]
|
||||||
|
# Include init.sls files in state list
|
||||||
|
init = false
|
||||||
|
# Include .init suffix in when init is true
|
||||||
|
init_suffix = false
|
||||||
|
# Include clean.sls files in state list
|
||||||
|
clean = false
|
||||||
|
# When rendering with prefix `settings.something`,
|
||||||
|
# write `else` instead of `settings.something.else`
|
||||||
|
cut_prefix = true
|
||||||
|
# Write `salt.package` instead of `package` when formula root == `salt`
|
||||||
|
include_formula_root = false
|
||||||
|
'''
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import toml
|
||||||
from jinja2 import Environment
|
from jinja2 import Environment
|
||||||
from jinja2.exceptions import TemplateSyntaxError
|
from jinja2.exceptions import TemplateSyntaxError
|
||||||
|
|
||||||
@@ -31,27 +94,38 @@ class State:
|
|||||||
Object representing a documented state.
|
Object representing a documented state.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, path, comment):
|
def __init__(self, path, comment, formula_root):
|
||||||
|
if not isinstance(path, Path):
|
||||||
|
path = Path(path)
|
||||||
self.path = path
|
self.path = path
|
||||||
self.comment = comment
|
self.comment = str(comment)
|
||||||
|
self.formula_root = formula_root
|
||||||
|
|
||||||
def tostateid(self, include_init=True, relative_to=""):
|
def to_state_id(self, include_init=True, relative_to="", split=False, formula_root=False):
|
||||||
ret = self.path.with_suffix("")
|
ret = self.path.with_suffix("")
|
||||||
|
|
||||||
if not include_init and "init" == ret.parts[-1]:
|
if not include_init and ret.parts[-1] == "init":
|
||||||
ret = ret.parent
|
ret = ret.parent
|
||||||
|
|
||||||
if relative_to:
|
if relative_to:
|
||||||
relative_to = Path(relative_to.replace(".", "/"))
|
relative_to = Path(relative_to.replace(".", "/"))
|
||||||
ret = ret.relative_to(relative_to)
|
ret = ret.relative_to(relative_to)
|
||||||
|
elif formula_root:
|
||||||
|
ret = Path(self.formula_root) / ret
|
||||||
|
|
||||||
return str(ret).replace("/", ".")
|
ret = str(ret).replace("/", ".")
|
||||||
|
if not split:
|
||||||
|
return ret
|
||||||
|
return tuple(ret.split("."))
|
||||||
|
|
||||||
def isinit(self):
|
def is_init(self):
|
||||||
return "init.sls" == self.path.parts[-1]
|
return self.path.parts[-1] == "init.sls"
|
||||||
|
|
||||||
def isclean(self):
|
def is_clean(self):
|
||||||
return "clean.sls" == self.path.parts[-1]
|
return self.path.parts[-1] == "clean.sls"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.to_state_id()
|
||||||
|
|
||||||
|
|
||||||
class StateRegistry:
|
class StateRegistry:
|
||||||
@@ -66,16 +140,36 @@ class StateRegistry:
|
|||||||
by some of the downstream classes.
|
by some of the downstream classes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, reg=None, states=None, prefixes=None):
|
def __init__(self, reg=None, states=None, prefixes=None, default_sort_fn=None, avoid_init_dup=True, sort_list=None):
|
||||||
if reg is None:
|
# nested dict
|
||||||
reg = {}
|
self.reg = reg or {}
|
||||||
if states is None:
|
# flat dict with ptr to reg
|
||||||
states = []
|
self.states = states or {}
|
||||||
if prefixes is None:
|
# flat dict with ptr to reg
|
||||||
prefixes = []
|
self.prefixes = prefixes or {}
|
||||||
self.reg = reg
|
self.default_sort_fn = default_sort_fn or self._default_sort
|
||||||
self.states = states
|
# ensure no prefix lists the root
|
||||||
self.prefixes = prefixes
|
self.prefixes[()] = self.reg
|
||||||
|
self.avoid_init_dup = avoid_init_dup
|
||||||
|
self.sort_list = tuple(sort_list or ("init", "clean", "package", "config", "service"))
|
||||||
|
|
||||||
|
def _default_sort(self, a):
|
||||||
|
"""
|
||||||
|
Sort prefixes package > config > service, rest alphabetically.
|
||||||
|
Init always comes first. Clean states are separated.
|
||||||
|
"""
|
||||||
|
sort_key = ()
|
||||||
|
if a[0] in self.sort_list:
|
||||||
|
sort_key += (str(self.sort_list.index(a[0])),)
|
||||||
|
else:
|
||||||
|
sort_key += (str(len(self.sort_list)),)
|
||||||
|
if a[-1] == "init":
|
||||||
|
sort_key += a[:-1]
|
||||||
|
elif a[-1] == "clean":
|
||||||
|
sort_key = ("zzzzzzzzz",) + sort_key + a[:-1]
|
||||||
|
else:
|
||||||
|
sort_key += a
|
||||||
|
return sort_key
|
||||||
|
|
||||||
def lookup(self, state, tree=False):
|
def lookup(self, state, tree=False):
|
||||||
"""
|
"""
|
||||||
@@ -85,6 +179,7 @@ class StateRegistry:
|
|||||||
ptr = self.reg
|
ptr = self.reg
|
||||||
if isinstance(state, str):
|
if isinstance(state, str):
|
||||||
state = state.split(".")
|
state = state.split(".")
|
||||||
|
state = list(state)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while state:
|
while state:
|
||||||
@@ -99,43 +194,53 @@ class StateRegistry:
|
|||||||
elif "init" in ptr:
|
elif "init" in ptr:
|
||||||
return ptr["init"]
|
return ptr["init"]
|
||||||
|
|
||||||
raise ValueError("State could not be found.")
|
raise ValueError("State could not be found. Most likely, this is a prefix.")
|
||||||
|
|
||||||
def register(self, state):
|
def register(self, state):
|
||||||
state_id = state.tostateid()
|
try:
|
||||||
self.states.append(state_id)
|
state_id = state.to_state_id(split=True)
|
||||||
|
except AttributeError as err:
|
||||||
parts = state_id.split(".")
|
raise ValueError("`state` argument must be an instance of `State`") from err
|
||||||
|
|
||||||
ptr = self.reg
|
ptr = self.reg
|
||||||
prefix = ""
|
prefix = []
|
||||||
|
parts = list(state_id)
|
||||||
|
|
||||||
while len(parts) > 1:
|
while len(parts):
|
||||||
cur = parts.pop(0)
|
cur = parts.pop(0)
|
||||||
prefix = (prefix + "." + cur) if prefix else cur
|
prefix = prefix + [cur]
|
||||||
|
if not parts:
|
||||||
|
ptr[cur] = state
|
||||||
|
break
|
||||||
# make sure subdicts are initialized
|
# make sure subdicts are initialized
|
||||||
if cur not in ptr:
|
elif cur not in ptr:
|
||||||
ptr[cur] = {}
|
ptr[cur] = {}
|
||||||
self.prefixes.append(prefix)
|
self.prefixes[tuple(prefix)] = ptr[cur]
|
||||||
ptr = ptr[cur]
|
ptr = ptr[cur]
|
||||||
|
self.states[state_id] = ptr[cur]
|
||||||
ptr[parts.pop(0)] = state
|
|
||||||
|
|
||||||
self.prefixes.sort()
|
|
||||||
self.states.sort()
|
|
||||||
|
|
||||||
def unregister(self, state):
|
def unregister(self, state):
|
||||||
state_id = state.tostateid()
|
try:
|
||||||
self.states.remove(state_id)
|
state_id = state.to_state_id(split=True)
|
||||||
|
except AttributeError as err:
|
||||||
|
raise ValueError("`state` argument must be an instance of `State`") from err
|
||||||
|
try:
|
||||||
|
self.states.pop(state_id)
|
||||||
|
except KeyError as err:
|
||||||
|
raise RuntimeError(f"Specified state {state} was not registered") from err
|
||||||
|
|
||||||
if state_id.find("."):
|
parts = list(state_id)
|
||||||
path, key = state_id.rsplit(".", maxsplit=1)
|
first_run = True
|
||||||
parent = self.lookup(path, tree=True)
|
|
||||||
else:
|
|
||||||
parent = self.reg
|
|
||||||
key = state_id
|
|
||||||
|
|
||||||
del parent[key]
|
while parts:
|
||||||
|
key = parts.pop()
|
||||||
|
parent = self.lookup(parts, tree=True)
|
||||||
|
if first_run:
|
||||||
|
del parent[key]
|
||||||
|
elif not len(parent[key]):
|
||||||
|
self.prefixes.pop(tuple(parts + [key]))
|
||||||
|
del parent[key]
|
||||||
|
first_run = False
|
||||||
|
|
||||||
def depth(self, prefix=""):
|
def depth(self, prefix=""):
|
||||||
"""
|
"""
|
||||||
@@ -155,14 +260,22 @@ class StateRegistry:
|
|||||||
def count(self):
|
def count(self):
|
||||||
return len(self.states)
|
return len(self.states)
|
||||||
|
|
||||||
def dump(self, prefix=""):
|
def dump(self, prefix=None, sort_fn=None):
|
||||||
"""
|
"""
|
||||||
Returns all states sorted alphabetically, optionally
|
Returns all states sorted, optionally beginning from a prefix only.
|
||||||
from a prefix onwards.
|
|
||||||
"""
|
"""
|
||||||
for s in self.states:
|
prefix = prefix or ()
|
||||||
if not prefix or s.startswith(prefix):
|
if isinstance(prefix, str):
|
||||||
yield self.lookup(s)
|
prefix = tuple(prefix.split("."))
|
||||||
|
for state_id in sorted(self.states, key=sort_fn or self.default_sort_fn):
|
||||||
|
if state_id[:len(prefix)] == prefix:
|
||||||
|
if self.avoid_init_dup and state_id[-1] not in ["init", "clean"]:
|
||||||
|
# given package.init, package.install and package.clean,
|
||||||
|
# only dump init and clean
|
||||||
|
parent = self.lookup(state_id[:-1], tree=True)
|
||||||
|
if len(parent) == 3 and "init" in parent and "clean" in parent:
|
||||||
|
continue
|
||||||
|
yield self.states[state_id]
|
||||||
|
|
||||||
|
|
||||||
class Renderer:
|
class Renderer:
|
||||||
@@ -170,16 +283,26 @@ class Renderer:
|
|||||||
Base class for Renderer objects.
|
Base class for Renderer objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
opts = {}
|
_default_opts = {
|
||||||
|
"default_description": """\
|
||||||
|
The following states are found in {where}:
|
||||||
|
|
||||||
def __init__(self, target="docs", opts=None):
|
.. contents::
|
||||||
if opts is not None:
|
:local:
|
||||||
self.opts = self.opts | opts
|
""",
|
||||||
|
"always_include_default_description": False,
|
||||||
if isinstance(target, str):
|
"default_header": "Available States",
|
||||||
target = Path(target)
|
"main_heading_char": "=",
|
||||||
self.target = base_dir / target
|
"sub_heading_char": "-",
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, target="docs", prefix=None, basedir=base_dir, opts=None):
|
||||||
|
self.opts = self._default_opts | (opts or {})
|
||||||
|
self.target = basedir / target
|
||||||
|
if isinstance(prefix, str):
|
||||||
|
prefix = tuple(prefix.split("."))
|
||||||
|
self.prefix = prefix or ()
|
||||||
|
self.basedir = basedir
|
||||||
self._ensurepath(self.target)
|
self._ensurepath(self.target)
|
||||||
|
|
||||||
def render(self, states):
|
def render(self, states):
|
||||||
@@ -197,25 +320,25 @@ class Renderer:
|
|||||||
)
|
)
|
||||||
self.f.write(text + "\n" * ncount)
|
self.f.write(text + "\n" * ncount)
|
||||||
|
|
||||||
def _write_heading(self, text, uline="-"):
|
def _write_heading(self, text, uline=None):
|
||||||
"""
|
"""
|
||||||
Convenience method to write a subheading
|
Convenience method to write a subheading
|
||||||
"""
|
"""
|
||||||
self._write(text)
|
self._write(text)
|
||||||
self._write(uline * len(text))
|
self._write((uline or self.opts["sub_heading_char"]) * len(text))
|
||||||
|
|
||||||
def _write_main_heading(self, text, uline="="):
|
def _write_main_heading(self, text, uline=None):
|
||||||
"""
|
"""
|
||||||
Convenience method to write the main heading
|
Convenience method to write the main heading
|
||||||
"""
|
"""
|
||||||
self.f.write(text + "\n")
|
self.f.write(text + "\n")
|
||||||
self.f.write(uline * len(text) + "\n\n")
|
self.f.write((uline or self.opts["main_heading_char"]) * len(text) + "\n\n")
|
||||||
|
|
||||||
def _write_main_description(self, text):
|
def _write_main_description(self, text):
|
||||||
"""
|
"""
|
||||||
Convenience method to write the main description
|
Convenience method to write the main description
|
||||||
"""
|
"""
|
||||||
self.f.write(text + "\n\n")
|
self.f.write(text + "\n")
|
||||||
|
|
||||||
def _get_main_heading(self, states):
|
def _get_main_heading(self, states):
|
||||||
"""
|
"""
|
||||||
@@ -227,17 +350,19 @@ class Renderer:
|
|||||||
capitalized last part of it.
|
capitalized last part of it.
|
||||||
4. "Available States"
|
4. "Available States"
|
||||||
"""
|
"""
|
||||||
if main := states.lookup(self.prefix + ".init"):
|
if header := self.opts.get("header"):
|
||||||
|
return header
|
||||||
|
if (main := states.lookup(self.prefix + ("init",))) and main.comment:
|
||||||
lines = main.comment.splitlines()
|
lines = main.comment.splitlines()
|
||||||
header = lines.pop(0)
|
header = lines.pop(0)
|
||||||
# make sure the header does not get printed twice
|
# make sure the header does not get printed twice
|
||||||
main.comment = "\n".join(lines).strip("\n")
|
main.comment = "\n".join(lines).strip("\n")
|
||||||
return header
|
return header
|
||||||
if main := self.opts.get("header"):
|
|
||||||
return main
|
|
||||||
if self.prefix:
|
if self.prefix:
|
||||||
return self.prefix.split(".")[-1].title()
|
return self.prefix[-1].title()
|
||||||
return "Available States"
|
if header := self.opts.get("default_header"):
|
||||||
|
return header
|
||||||
|
return self.opts["default_header"]
|
||||||
|
|
||||||
def _get_main_description(self, states):
|
def _get_main_description(self, states):
|
||||||
"""
|
"""
|
||||||
@@ -248,16 +373,19 @@ class Renderer:
|
|||||||
2. If a description was specified in opts, return that.
|
2. If a description was specified in opts, return that.
|
||||||
3. general description
|
3. general description
|
||||||
"""
|
"""
|
||||||
if main := states.lookup(self.prefix + ".init"):
|
def get_default_desc():
|
||||||
comment = main.comment
|
return self.opts["default_description"].format(
|
||||||
# make sure the comment does not get printed twice
|
where=".".join(self.prefix) if self.prefix else "this formula"
|
||||||
states.unregister(main)
|
)
|
||||||
return comment
|
|
||||||
if main := self.opts.get("description"):
|
if desc := self.opts.get("description"):
|
||||||
return main
|
return desc
|
||||||
return "The following states are found in {}:".format(
|
if main := states.lookup(self.prefix + ("init",)):
|
||||||
self.prefix if self.prefix else "this formula"
|
desc = main.comment
|
||||||
)
|
if self.opts.get("always_include_default_description"):
|
||||||
|
desc += "\n" + get_default_desc()
|
||||||
|
return desc
|
||||||
|
return get_default_desc()
|
||||||
|
|
||||||
def _write_header(self, states):
|
def _write_header(self, states):
|
||||||
"""
|
"""
|
||||||
@@ -282,32 +410,33 @@ class SingleRenderer(Renderer):
|
|||||||
|
|
||||||
If there is a documented top-layer init.sls, the first line of
|
If there is a documented top-layer init.sls, the first line of
|
||||||
its comment will become the main heading of the file, the stripped
|
its comment will become the main heading of the file, the stripped
|
||||||
rest will be rendered directly below before any nested states.
|
rest will be rendered directly below before any nested states as
|
||||||
|
the main description.
|
||||||
|
|
||||||
|
Should have been a Jinja template @TODO
|
||||||
"""
|
"""
|
||||||
|
|
||||||
opts = {
|
default_opts = {
|
||||||
# include init.sls files
|
# include init.sls files
|
||||||
"init": True,
|
"init": True,
|
||||||
# include .init suffix
|
# include .init suffix
|
||||||
"init_suffix": False,
|
"init_suffix": False,
|
||||||
# include clean.sls files
|
# include clean.sls files
|
||||||
"clean": False,
|
"clean": True,
|
||||||
# when rendering with prefix `settings.something`,
|
# when rendering with prefix `settings.something`,
|
||||||
# write `else` instead of `settings.something.else`
|
# write `else` instead of `settings.something.else`
|
||||||
"cut_prefix": False,
|
"cut_prefix": False,
|
||||||
|
"include_formula_root": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, target="docs/states.rst", prefix="", opts=None):
|
def __init__(self, target="docs/states.rst", prefix=None, basedir=base_dir, **kwargs):
|
||||||
self.prefix = prefix
|
|
||||||
|
|
||||||
if isinstance(target, str):
|
if isinstance(target, str):
|
||||||
target = Path(target)
|
target = Path(target)
|
||||||
|
|
||||||
target = target.with_suffix(".rst")
|
target = target.with_suffix(".rst")
|
||||||
super().__init__(target, self.opts | opts or {})
|
super().__init__(target=target, prefix=prefix, basedir=basedir, opts=self.default_opts | kwargs)
|
||||||
|
|
||||||
def render(self, states):
|
def render(self, states):
|
||||||
relative_to = self.prefix if self.opts["cut_prefix"] else ""
|
relative_to = "/".join(self.prefix) if self.opts["cut_prefix"] else ""
|
||||||
|
|
||||||
with open(self.target, "w") as f:
|
with open(self.target, "w") as f:
|
||||||
self.f = f
|
self.f = f
|
||||||
@@ -315,12 +444,15 @@ class SingleRenderer(Renderer):
|
|||||||
self._write_header(states)
|
self._write_header(states)
|
||||||
|
|
||||||
for state in states.dump(self.prefix):
|
for state in states.dump(self.prefix):
|
||||||
if not self.opts["clean"] and state.isclean():
|
if not self.opts["init"] and state.is_init():
|
||||||
continue
|
continue
|
||||||
if not self.opts["init"] and state.isinit():
|
if not self.opts["clean"] and state.is_clean():
|
||||||
|
continue
|
||||||
|
state_id = state.to_state_id(self.opts["init_suffix"], relative_to, formula_root=self.opts["include_formula_root"])
|
||||||
|
if state_id == ".":
|
||||||
continue
|
continue
|
||||||
self._write_heading(
|
self._write_heading(
|
||||||
state.tostateid(self.opts["init_suffix"], relative_to)
|
state.to_state_id(self.opts["init_suffix"], relative_to, formula_root=self.opts["include_formula_root"])
|
||||||
)
|
)
|
||||||
self._write(state.comment, 3)
|
self._write(state.comment, 3)
|
||||||
|
|
||||||
@@ -354,36 +486,39 @@ class DepthRenderer(Renderer):
|
|||||||
- read_receipts doc
|
- read_receipts doc
|
||||||
"""
|
"""
|
||||||
|
|
||||||
opts = {
|
default_opts = {
|
||||||
# maxdepth for generated index.rst files
|
# maxdepth for generated index.rst files
|
||||||
"index_maxdepth": 4,
|
"index_maxdepth": 4,
|
||||||
# also any options are passed through to the
|
"single_opts": {
|
||||||
# delegate renderer, by default SingleRenderer
|
"init": True,
|
||||||
|
"init_suffix": False,
|
||||||
|
"clean": False,
|
||||||
|
"cut_prefix": True,
|
||||||
|
"include_formula_root": False,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, max_depth=1, target="docs/states", delegate_cls=None, opts=None):
|
def __init__(self, max_depth=1, target="docs/states", delegate_cls=None, basedir=base_dir, **kwargs):
|
||||||
if delegate_cls is None:
|
|
||||||
delegate_cls = SingleRenderer
|
|
||||||
|
|
||||||
self.max_depth = max_depth
|
self.max_depth = max_depth
|
||||||
self.delegate = delegate_cls
|
self.delegate = delegate_cls or SingleRenderer
|
||||||
|
super().__init__(target=target, basedir=basedir, opts=self.default_opts | (kwargs or {}))
|
||||||
super().__init__(target, self.opts | opts or {})
|
|
||||||
|
|
||||||
def render(self, states):
|
def render(self, states):
|
||||||
found = []
|
found = []
|
||||||
indices = {}
|
indices = {}
|
||||||
cur_top = ""
|
cur_top = ()
|
||||||
|
|
||||||
# find at which prefix length the maxdepth is fulfilled
|
# Find at which prefix length the maxdepth is fulfilled
|
||||||
for prefix in states.prefixes:
|
for prefix in states.prefixes:
|
||||||
# filtering out more specific = shallower dicts
|
# Filtering out more specific = shallower dicts
|
||||||
# this requires the list to be sorted!
|
# This requires the list to be sorted!
|
||||||
|
# This also goes not too well with rendering clean states
|
||||||
|
# by default since they will be separate.
|
||||||
if cur_top:
|
if cur_top:
|
||||||
if prefix.startswith(cur_top):
|
if prefix[:len(cur_top)] == cur_top:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
cur_top = ""
|
cur_top = ()
|
||||||
if states.depth(prefix) <= self.max_depth:
|
if states.depth(prefix) <= self.max_depth:
|
||||||
found.append(prefix)
|
found.append(prefix)
|
||||||
cur_top = prefix
|
cur_top = prefix
|
||||||
@@ -398,7 +533,7 @@ class DepthRenderer(Renderer):
|
|||||||
|
|
||||||
for prefix in found:
|
for prefix in found:
|
||||||
ptr = indices
|
ptr = indices
|
||||||
prefix = prefix.split(".")
|
prefix = list(prefix)
|
||||||
|
|
||||||
while prefix:
|
while prefix:
|
||||||
cur = prefix.pop(0)
|
cur = prefix.pop(0)
|
||||||
@@ -421,38 +556,34 @@ class DepthRenderer(Renderer):
|
|||||||
|
|
||||||
def _render_single(self, states, prefix):
|
def _render_single(self, states, prefix):
|
||||||
target = self._get_target(prefix)
|
target = self._get_target(prefix)
|
||||||
renderer = self.delegate(target=target, prefix=prefix, opts=self.opts)
|
renderer = self.delegate(target=target, prefix=prefix, **self.opts["single_opts"])
|
||||||
renderer.render(states)
|
renderer.render(states)
|
||||||
|
|
||||||
def _render_index(self, states, indices, prefix=""):
|
def _render_index(self, states, indices, prefix=None):
|
||||||
|
prefix = prefix or ()
|
||||||
target = self._get_target(prefix) / Path("index.rst")
|
target = self._get_target(prefix) / Path("index.rst")
|
||||||
self._ensurepath(target)
|
|
||||||
with open(target, "w") as f:
|
with open(target, "w") as f:
|
||||||
self.f = f
|
self.f = f
|
||||||
self.prefix = prefix
|
self.prefix = prefix
|
||||||
self._write_header(states)
|
self._write_header(states)
|
||||||
self.prefix = ""
|
self.prefix = ()
|
||||||
f.write(
|
f.write(f"""
|
||||||
"""
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: {}
|
:maxdepth: {self.opts['index_maxdepth']}
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
""".format(
|
""")
|
||||||
self.opts.get("index_maxdepth", 4)
|
for s in sorted(indices["_index"]):
|
||||||
)
|
|
||||||
)
|
|
||||||
for s in indices["_index"]:
|
|
||||||
f.write(" " + s + "\n")
|
f.write(" " + s + "\n")
|
||||||
for sub in indices:
|
for sub in sorted(indices):
|
||||||
if "_index" == sub:
|
if sub == "_index":
|
||||||
continue
|
continue
|
||||||
if "_index" in indices[sub]:
|
if "_index" in indices[sub]:
|
||||||
new_prefix = prefix + "." + sub if prefix else sub
|
new_prefix = prefix + (sub,)
|
||||||
self._render_index(states, indices[sub], new_prefix)
|
self._render_index(states, indices[sub], new_prefix)
|
||||||
|
|
||||||
def _get_target(self, prefix):
|
def _get_target(self, prefix):
|
||||||
target_prefix = Path(prefix.replace(".", "/"))
|
target_prefix = Path("/".join(prefix))
|
||||||
target = self.target / target_prefix
|
target = self.target / target_prefix
|
||||||
self._ensurepath(target)
|
self._ensurepath(target)
|
||||||
return target
|
return target
|
||||||
@@ -470,23 +601,19 @@ class SaltAutodoc:
|
|||||||
|
|
||||||
SKIP_FILE = "@internal"
|
SKIP_FILE = "@internal"
|
||||||
|
|
||||||
def __init__(self, base=None, renderer=None, registry=None, env=None):
|
def __init__(self, base=None, renderer=None, registry=None, env=None, include_empty=False, ignore=None):
|
||||||
"""
|
"""
|
||||||
base: base path containing Salt states to autodocument
|
base: base path containing Salt states to autodocument
|
||||||
renderer: renderer to use for rendering
|
renderer: renderer to use for rendering
|
||||||
"""
|
"""
|
||||||
if base is None:
|
if base is None:
|
||||||
base = list(base_dir.glob("tool_*"))[0]
|
base = list(base_dir.glob("*/init.sls"))[0].parent
|
||||||
self.base = base
|
self.base = base
|
||||||
if renderer is None:
|
self.renderer = renderer or SingleRenderer()
|
||||||
renderer = SingleRenderer()
|
self.env = env or Environment()
|
||||||
self.renderer = renderer
|
self.registry = registry or StateRegistry()
|
||||||
if env is None:
|
self.include_empty = include_empty
|
||||||
env = Environment()
|
self.ignore = ignore or []
|
||||||
self.env = env
|
|
||||||
if registry is None:
|
|
||||||
registry = StateRegistry()
|
|
||||||
self.registry = registry
|
|
||||||
|
|
||||||
def run(self, src=""):
|
def run(self, src=""):
|
||||||
"""
|
"""
|
||||||
@@ -495,32 +622,24 @@ class SaltAutodoc:
|
|||||||
3. in that case, save it to the registry
|
3. in that case, save it to the registry
|
||||||
4. pass the registry to the renderer
|
4. pass the registry to the renderer
|
||||||
"""
|
"""
|
||||||
states = {}
|
|
||||||
|
|
||||||
for file in self.glob(src):
|
for file in self.glob(src):
|
||||||
|
if str(file.relative_to(self.base)).startswith(tuple(self.ignore)):
|
||||||
|
continue
|
||||||
with open(file, "r") as f:
|
with open(file, "r") as f:
|
||||||
text = "".join(f.readlines())
|
text = "".join(f.readlines())
|
||||||
try:
|
try:
|
||||||
comment = self.find_comment(text)
|
comment = self.find_comment(text)
|
||||||
except TemplateSyntaxError as e:
|
except TemplateSyntaxError as e:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"There was an error parsing the Jinja syntax in file '{}':\n\n{}".format(
|
f"There was an error parsing the Jinja syntax in file '{file}':\n\n{e}"
|
||||||
file, str(e)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if comment and not comment.startswith(self.SKIP_FILE):
|
if (comment or self.include_empty) and not comment.startswith(self.SKIP_FILE):
|
||||||
path = self.path2saltpath(file)
|
path = file.relative_to(self.base)
|
||||||
self.registry.register(State(path, comment))
|
self.registry.register(State(path, comment, self.base.name))
|
||||||
|
|
||||||
self.renderer.render(self.registry)
|
self.renderer.render(self.registry)
|
||||||
|
|
||||||
def path2saltpath(self, path):
|
|
||||||
"""
|
|
||||||
Returns a Path object relative to the base directory.
|
|
||||||
"""
|
|
||||||
return path.relative_to(self.base)
|
|
||||||
|
|
||||||
def glob(self, src):
|
def glob(self, src):
|
||||||
"""
|
"""
|
||||||
Returns Path objects pointing to Salt states provided by this formula.
|
Returns Path objects pointing to Salt states provided by this formula.
|
||||||
@@ -534,11 +653,15 @@ class SaltAutodoc:
|
|||||||
"""
|
"""
|
||||||
lexed = list(self.env.lex(text))
|
lexed = list(self.env.lex(text))
|
||||||
try:
|
try:
|
||||||
i, t, content = lexed[1]
|
i = 0
|
||||||
|
t = ""
|
||||||
|
while i < 5 and t != "comment":
|
||||||
|
_, t, content = lexed[i]
|
||||||
|
i += 1
|
||||||
except IndexError:
|
except IndexError:
|
||||||
i = t = content = ""
|
t = content = ""
|
||||||
|
|
||||||
if "comment" == t:
|
if t == "comment":
|
||||||
return self.parse(content)
|
return self.parse(content)
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
@@ -554,18 +677,16 @@ class SaltAutodoc:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
options = {
|
options = toml.loads((base_dir / "pyproject.toml").read_text()).get("tool", {}).get("slsdoc", {})
|
||||||
"init": True,
|
renderer = options.get("renderer", "single")
|
||||||
"init_suffix": False,
|
|
||||||
"clean": False,
|
|
||||||
"cut_prefix": False,
|
|
||||||
"index_maxdepth": 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
# by default,
|
if renderer == "single":
|
||||||
# - render all documented states to a single file
|
rend = SingleRenderer(**options.get("single_renderer", {}))
|
||||||
# - skip clean.sls descriptions
|
elif renderer == "depth":
|
||||||
# - do not include .init suffix on state ID
|
rend = DepthRenderer(**options.get("depth_renderer", {}))
|
||||||
r = SingleRenderer(target="docs/states.rst", opts=options)
|
else:
|
||||||
a = SaltAutodoc(base=base_dir / "gitea", renderer=r)
|
raise ValueError(f"Invalid value for renderer: {renderer}")
|
||||||
a.run()
|
|
||||||
|
registry = StateRegistry(avoid_init_dup=options.get("avoid_init_dup", True), sort_list=options.get("sort_list"))
|
||||||
|
doc = SaltAutodoc(renderer=rend, registry=registry, include_empty=options.get("include_empty", False), ignore=options.get("ignore", ["_mapdata"]))
|
||||||
|
doc.run()
|
||||||
|
|||||||
@@ -73,64 +73,92 @@ Configuration
|
|||||||
-------------
|
-------------
|
||||||
An example pillar is provided, please see `pillar.example`. Note that you do not need to specify everything by pillar. Often, it's much easier and less resource-heavy to use the ``parameters/<grain>/<value>.yaml`` files for non-sensitive settings. The underlying logic is explained in `map.jinja`.
|
An example pillar is provided, please see `pillar.example`. Note that you do not need to specify everything by pillar. Often, it's much easier and less resource-heavy to use the ``parameters/<grain>/<value>.yaml`` files for non-sensitive settings. The underlying logic is explained in `map.jinja`.
|
||||||
|
|
||||||
|
|
||||||
Available states
|
Available states
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
The following states are found in this formula:
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
:local:
|
:local:
|
||||||
|
|
||||||
``gitea``
|
|
||||||
^^^^^^^^^
|
|
||||||
|
|
||||||
*Meta-state (This is a state that includes other states)*.
|
gitea
|
||||||
|
^^^^^
|
||||||
|
*Meta-state*.
|
||||||
|
|
||||||
This installs the gitea package,
|
This installs the gitea package,
|
||||||
manages the gitea configuration file and then
|
manages the gitea configuration file
|
||||||
starts the associated gitea service.
|
and then starts the associated gitea service.
|
||||||
|
|
||||||
``gitea.package``
|
|
||||||
^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
gitea.package
|
||||||
|
^^^^^^^^^^^^^
|
||||||
This state will install the gitea package only.
|
This state will install the gitea package only.
|
||||||
|
|
||||||
``gitea.config``
|
|
||||||
^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This state will configure the gitea service and has a dependency on ``gitea.install``
|
gitea.config
|
||||||
via include list.
|
^^^^^^^^^^^^
|
||||||
|
This state will configure the gitea service
|
||||||
|
and has a dependency on ``gitea.install`` via include list.
|
||||||
|
|
||||||
``gitea.service``
|
|
||||||
^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This state will start the gitea service and has a dependency on ``gitea.config``
|
gitea.service
|
||||||
via include list.
|
^^^^^^^^^^^^^
|
||||||
|
This state will start the gitea service
|
||||||
|
and has a dependency on ``gitea.config`` via include list.
|
||||||
|
|
||||||
``gitea.clean``
|
|
||||||
^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
*Meta-state (This is a state that includes other states)*.
|
gitea.go
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
This state will undo everything performed in the ``gitea`` meta-state in reverse order, i.e.
|
|
||||||
|
|
||||||
|
gitea.mods.rst
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gitea.clean
|
||||||
|
^^^^^^^^^^^
|
||||||
|
*Meta-state*.
|
||||||
|
|
||||||
|
This state will undo everything performed in the ``gitea`` meta-state
|
||||||
|
in reverse order, i.e.
|
||||||
stops the service,
|
stops the service,
|
||||||
removes the configuration file and
|
removes the configuration file and then
|
||||||
then uninstalls the package. Some paths are left to avoid accidental data loss (namely ``GITEA_WORKDIR``, ``APP_DATA_PATH`` and the gitea user home).
|
uninstalls the package.
|
||||||
|
Some paths are left to avoid accidental data loss
|
||||||
|
(namely ``GITEA_WORKDIR``, ``APP_DATA_PATH`` and the gitea user home).
|
||||||
|
|
||||||
``gitea.service.clean``
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This state will stop the gitea service and disable it at boot time.
|
gitea.package.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
This state will remove the gitea package and has a depency on
|
||||||
|
``gitea.config.clean`` via include list.
|
||||||
|
|
||||||
``gitea.config.clean``
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
gitea.config.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
This state will remove the configuration of the gitea service and has a
|
This state will remove the configuration of the gitea service and has a
|
||||||
dependency on ``gitea.service.clean`` via include list.
|
dependency on ``gitea.service.clean`` via include list.
|
||||||
|
|
||||||
``gitea.package.clean``
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This state will remove the gitea package and has a depency on
|
gitea.service.clean
|
||||||
``gitea.config.clean`` via include list.
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
This state will stop the gitea service and disable it at boot time.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.go.clean
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gitea.mods.rst.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Contributing to this repo
|
Contributing to this repo
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|||||||
150
docs/README.rst.tpl
Normal file
150
docs/README.rst.tpl
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
.. _readme:
|
||||||
|
|
||||||
|
Gitea Formula
|
||||||
|
=============
|
||||||
|
|
||||||
|
|img_sr| |img_pc|
|
||||||
|
|
||||||
|
.. |img_sr| image:: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
|
||||||
|
:alt: Semantic Release
|
||||||
|
:scale: 100%
|
||||||
|
:target: https://github.com/semantic-release/semantic-release
|
||||||
|
.. |img_pc| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white
|
||||||
|
:alt: pre-commit
|
||||||
|
:scale: 100%
|
||||||
|
:target: https://github.com/pre-commit/pre-commit
|
||||||
|
|
||||||
|
Manage Gitea with Salt.
|
||||||
|
|
||||||
|
.. contents:: **Table of Contents**
|
||||||
|
:depth: 1
|
||||||
|
|
||||||
|
General notes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
See the full `SaltStack Formulas installation and usage instructions
|
||||||
|
<https://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html>`_.
|
||||||
|
|
||||||
|
If you are interested in writing or contributing to formulas, please pay attention to the `Writing Formula Section
|
||||||
|
<https://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html#writing-formulas>`_.
|
||||||
|
|
||||||
|
If you want to use this formula, please pay attention to the ``FORMULA`` file and/or ``git tag``,
|
||||||
|
which contains the currently released version. This formula is versioned according to `Semantic Versioning <http://semver.org/>`_.
|
||||||
|
|
||||||
|
See `Formula Versioning Section <https://docs.saltstack.com/en/latest/topics/development/conventions/formulas.html#versioning>`_ for more details.
|
||||||
|
|
||||||
|
If you need (non-default) configuration, please refer to:
|
||||||
|
|
||||||
|
- `how to configure the formula with map.jinja <map.jinja.rst>`_
|
||||||
|
- the ``pillar.example`` file
|
||||||
|
- the `Special notes`_ section
|
||||||
|
|
||||||
|
Special notes
|
||||||
|
-------------
|
||||||
|
* This installs from the `official binary source <https://dl.gitea.io/gitea/>`_.
|
||||||
|
* The formula is currently Linux/systemd-centric. It should be relatively easy to provide the correct parameters and service file for other platforms though.
|
||||||
|
* Since the formula skips the web installer, you will need to provide at least the database configuration.
|
||||||
|
* You can optionally specify the secrets, but they can be autogenerated by Salt as well. In that case, they will be saved in a separate file inside your config dir.
|
||||||
|
* All the paths are modifiable, find them in ``lookup:paths``. You should not need to set the corresponding values in your config, they are added automatically.
|
||||||
|
* If Gitea requires mounts for some of the paths, you can specify them in ``service:requires_mount`` as a list.
|
||||||
|
* If Gitea requires a local service unit (e.g. Redis server), specify it/them in ``service:wants`` as a list. This formula will do its best to automatically add a locally running database service to this list.
|
||||||
|
|
||||||
|
RST mod
|
||||||
|
^^^^^^^
|
||||||
|
This formula provides basic support for installing an external ``rst`` renderer. This especially makes Gitea display ``README.rst`` files similar to as it does for ``README.md``.
|
||||||
|
|
||||||
|
The installation is not included by default, you will have to specifically target ``gitea.mods.rst`` to the minion. Furthermore, you will have to setup the external renderer in your ``app.ini`` similar to:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
markup.restructuredtext:
|
||||||
|
enabled: true
|
||||||
|
file_extensions: '.rst'
|
||||||
|
render_command: timeout 30s /usr/local/bin/grst
|
||||||
|
is_input_file: true
|
||||||
|
markup.sanitizer.restructuredtext:
|
||||||
|
element: pre
|
||||||
|
allow_attr: class
|
||||||
|
regexp: ''
|
||||||
|
|
||||||
|
The mod compiles ``chroma`` (the syntax highlighting library that is used by Gitea) from source and installs a Python script that renders RST files, which currently relies on ``chroma`` and the ``docutils`` python package. The parameters can be modified in ``gitea:lookup:mod_rst``. I currently use this to patch ``*.sls``, ``*.jinja`` and ``*.j2`` highlighting into ``chroma``.
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
An example pillar is provided, please see `pillar.example`. Note that you do not need to specify everything by pillar. Often, it's much easier and less resource-heavy to use the ``parameters/<grain>/<value>.yaml`` files for non-sensitive settings. The underlying logic is explained in `map.jinja`.
|
||||||
|
|
||||||
|
<INSERT_STATES>
|
||||||
|
|
||||||
|
Contributing to this repo
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Commit messages
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
**Commit message formatting is significant!**
|
||||||
|
|
||||||
|
Please see `How to contribute <https://github.com/saltstack-formulas/.github/blob/master/CONTRIBUTING.rst>`_ for more details.
|
||||||
|
|
||||||
|
pre-commit
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
`pre-commit <https://pre-commit.com/>`_ is configured for this formula, which you may optionally use to ease the steps involved in submitting your changes.
|
||||||
|
First install the ``pre-commit`` package manager using the appropriate `method <https://pre-commit.com/#installation>`_, then run ``bin/install-hooks`` and
|
||||||
|
now ``pre-commit`` will run automatically on each ``git commit``. ::
|
||||||
|
|
||||||
|
$ bin/install-hooks
|
||||||
|
pre-commit installed at .git/hooks/pre-commit
|
||||||
|
pre-commit installed at .git/hooks/commit-msg
|
||||||
|
|
||||||
|
State documentation
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
There is a script that semi-autodocuments available states: ``bin/slsdoc``.
|
||||||
|
|
||||||
|
If a ``.sls`` file begins with a Jinja comment, it will dump that into the docs. It can be configured differently depending on the formula. See the script source code for details currently.
|
||||||
|
|
||||||
|
This means if you feel a state should be documented, make sure to write a comment explaining it.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
Linux testing is done with ``kitchen-salt``.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* Ruby
|
||||||
|
* Docker
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ gem install bundler
|
||||||
|
$ bundle install
|
||||||
|
$ bin/kitchen test [platform]
|
||||||
|
|
||||||
|
Where ``[platform]`` is the platform name defined in ``kitchen.yml``,
|
||||||
|
e.g. ``debian-9-2019-2-py3``.
|
||||||
|
|
||||||
|
``bin/kitchen converge``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Creates the docker instance and runs the ``gitea`` main state, ready for testing.
|
||||||
|
|
||||||
|
``bin/kitchen verify``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Runs the ``inspec`` tests on the actual instance.
|
||||||
|
|
||||||
|
``bin/kitchen destroy``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Removes the docker instance.
|
||||||
|
|
||||||
|
``bin/kitchen test``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Runs all of the stages above in one go: i.e. ``destroy`` + ``converge`` + ``verify`` + ``destroy``.
|
||||||
|
|
||||||
|
``bin/kitchen login``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Gives you SSH access to the instance for manual testing.
|
||||||
@@ -1,6 +1,85 @@
|
|||||||
Available States
|
Available states
|
||||||
================
|
----------------
|
||||||
|
|
||||||
The following states are found in this formula:
|
The following states are found in this formula:
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
|
|
||||||
|
gitea
|
||||||
|
^^^^^
|
||||||
|
*Meta-state*.
|
||||||
|
|
||||||
|
This installs the gitea package,
|
||||||
|
manages the gitea configuration file
|
||||||
|
and then starts the associated gitea service.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.package
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
This state will install the gitea package only.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.config
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
This state will configure the gitea service
|
||||||
|
and has a dependency on ``gitea.install`` via include list.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.service
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
This state will start the gitea service
|
||||||
|
and has a dependency on ``gitea.config`` via include list.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.go
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gitea.mods.rst
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gitea.clean
|
||||||
|
^^^^^^^^^^^
|
||||||
|
*Meta-state*.
|
||||||
|
|
||||||
|
This state will undo everything performed in the ``gitea`` meta-state
|
||||||
|
in reverse order, i.e.
|
||||||
|
stops the service,
|
||||||
|
removes the configuration file and then
|
||||||
|
uninstalls the package.
|
||||||
|
Some paths are left to avoid accidental data loss
|
||||||
|
(namely ``GITEA_WORKDIR``, ``APP_DATA_PATH`` and the gitea user home).
|
||||||
|
|
||||||
|
|
||||||
|
gitea.package.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
This state will remove the gitea package and has a depency on
|
||||||
|
``gitea.config.clean`` via include list.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.config.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
This state will remove the configuration of the gitea service and has a
|
||||||
|
dependency on ``gitea.service.clean`` via include list.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.service.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
This state will stop the gitea service and disable it at boot time.
|
||||||
|
|
||||||
|
|
||||||
|
gitea.go.clean
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gitea.mods.rst.clean
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
---
|
---
|
||||||
{%- set tplroot = tpldir.split("/")[0] %}
|
{%- set tplroot = tpldir.split("/")[0] %}
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
*Meta-state*.
|
||||||
|
|
||||||
|
This state will undo everything performed in the ``gitea`` meta-state
|
||||||
|
in reverse order, i.e.
|
||||||
|
stops the service,
|
||||||
|
removes the configuration file and then
|
||||||
|
uninstalls the package.
|
||||||
|
Some paths are left to avoid accidental data loss
|
||||||
|
(namely ``GITEA_WORKDIR``, ``APP_DATA_PATH`` and the gitea user home).
|
||||||
|
#}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- .service.clean
|
- .service.clean
|
||||||
- .config.clean
|
- .config.clean
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
This state will remove the configuration of the gitea service and has a
|
||||||
|
dependency on ``gitea.service.clean`` via include list.
|
||||||
|
#}
|
||||||
|
|
||||||
{%- set tplroot = tpldir.split('/')[0] %}
|
{%- set tplroot = tpldir.split('/')[0] %}
|
||||||
{%- set sls_service_clean = tplroot ~ '.service.clean' %}
|
{%- set sls_service_clean = tplroot ~ '.service.clean' %}
|
||||||
{%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %}
|
{%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %}
|
||||||
@@ -8,7 +12,7 @@
|
|||||||
include:
|
include:
|
||||||
- {{ sls_service_clean }}
|
- {{ sls_service_clean }}
|
||||||
|
|
||||||
gitea-config-clean-file-absent:
|
Gitea configuration is absent:
|
||||||
file.absent:
|
file.absent:
|
||||||
- names:
|
- names:
|
||||||
- {{ gitea.lookup.paths.conf | path_join("app.ini") }}
|
- {{ gitea.lookup.paths.conf | path_join("app.ini") }}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
{%- set tplroot = tpldir.split('/')[0] %}
|
{%- set tplroot = tpldir.split('/')[0] %}
|
||||||
@@ -23,11 +22,11 @@ Gitea internal token file is generated:
|
|||||||
- sls: {{ sls_package_install }}
|
- sls: {{ sls_package_install }}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
Gitea config is setup:
|
Gitea configuration is managed:
|
||||||
file.managed:
|
file.managed:
|
||||||
- name: {{ gitea.lookup.paths.conf | path_join('app.ini') }}
|
- name: {{ gitea.lookup.paths.conf | path_join("app.ini") }}
|
||||||
- source: {{ files_switch(['app.ini.j2'],
|
- source: {{ files_switch(["app.ini", "app.ini.j2"],
|
||||||
lookup='Gitea config is setup'
|
lookup="Gitea configuration is managed"
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
- template: jinja
|
- template: jinja
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
This state will configure the gitea service
|
||||||
|
and has a dependency on ``gitea.install`` via include list.
|
||||||
|
#}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- .file
|
- .file
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
*Meta-state*.
|
||||||
|
|
||||||
|
This installs the gitea package,
|
||||||
|
manages the gitea configuration file
|
||||||
|
and then starts the associated gitea service.
|
||||||
|
#}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- .package
|
- .package
|
||||||
- .config
|
- .config
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{#- -*- coding: utf-8 -*- #}
|
|
||||||
{#- vim: ft=jinja #}
|
{#- vim: ft=jinja #}
|
||||||
|
|
||||||
{#- Get the `tplroot` from `tpldir` #}
|
{#- Get the `tplroot` from `tpldir` #}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{#- -*- coding: utf-8 -*- #}
|
|
||||||
{#- vim: ft=jinja #}
|
{#- vim: ft=jinja #}
|
||||||
|
|
||||||
{#- Get the `tplroot` from `tpldir` #}
|
{#- Get the `tplroot` from `tpldir` #}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{#- -*- coding: utf-8 -*- #}
|
|
||||||
{#- vim: ft=jinja #}
|
{#- vim: ft=jinja #}
|
||||||
|
|
||||||
{#- Get the relevant values from the `opts` dict #}
|
{#- Get the relevant values from the `opts` dict #}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
{#- -*- coding: utf-8 -*- #}
|
|
||||||
{#- vim: ft=jinja #}
|
{#- vim: ft=jinja #}
|
||||||
|
|
||||||
{#- Get the `tplroot` from `tpldir` #}
|
{#- Get the `tplroot` from `tpldir` #}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
This state will remove the gitea package and has a depency on
|
||||||
|
``gitea.config.clean`` via include list.
|
||||||
|
#}
|
||||||
|
|
||||||
{%- set tplroot = tpldir.split('/')[0] %}
|
{%- set tplroot = tpldir.split('/')[0] %}
|
||||||
{%- set sls_config_clean = tplroot ~ '.config.clean' %}
|
{%- set sls_config_clean = tplroot ~ '.config.clean' %}
|
||||||
{%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %}
|
{%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
This state will install the gitea package only.
|
||||||
|
#}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- .install
|
- .install
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set default values.
|
# Set default values.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
#
|
#
|
||||||
# Set values specific to:
|
# Set values specific to:
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
This state will stop the gitea service and disable it at boot time.
|
||||||
|
#}
|
||||||
|
|
||||||
{%- set tplroot = tpldir.split('/')[0] %}
|
{%- set tplroot = tpldir.split('/')[0] %}
|
||||||
{%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %}
|
{%- from tplroot ~ "/map.jinja" import mapdata as gitea with context %}
|
||||||
|
|
||||||
gitea-service-clean-service-dead:
|
Gitea is dead:
|
||||||
service.dead:
|
service.dead:
|
||||||
- name: {{ gitea.lookup.service.name }}
|
- name: {{ gitea.lookup.service.name }}
|
||||||
- enable: False
|
- enable: False
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
|
{#-
|
||||||
|
This state will start the gitea service
|
||||||
|
and has a dependency on ``gitea.config`` via include list.
|
||||||
|
#}
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- .running
|
- .running
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=sls
|
# vim: ft=sls
|
||||||
|
|
||||||
{%- set tplroot = tpldir.split('/')[0] %}
|
{%- set tplroot = tpldir.split('/')[0] %}
|
||||||
@@ -8,7 +7,7 @@
|
|||||||
include:
|
include:
|
||||||
- {{ sls_config_file }}
|
- {{ sls_config_file }}
|
||||||
|
|
||||||
gitea-service-running-service-running:
|
Gitea is running:
|
||||||
service.running:
|
service.running:
|
||||||
- name: {{ gitea.lookup.service.name }}
|
- name: {{ gitea.lookup.service.name }}
|
||||||
- enable: True
|
- enable: True
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
# For help on this file's format, see https://kitchen.ci/
|
# For help on this file's format, see https://kitchen.ci/
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
# yamllint disable rule:comments-indentation
|
# yamllint disable rule:comments-indentation
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -15,6 +15,20 @@ sphinx-rtd-theme = "^1.0.0"
|
|||||||
# fulltoc has an issue with recent Sphinx versions ('easily' fixable in the source code though)
|
# fulltoc has an issue with recent Sphinx versions ('easily' fixable in the source code though)
|
||||||
# sphinxcontrib-fulltoc = "^1.2.0"
|
# sphinxcontrib-fulltoc = "^1.2.0"
|
||||||
|
|
||||||
|
[tool.slsdoc]
|
||||||
|
include_empty = true
|
||||||
|
|
||||||
|
[tool.slsdoc.single_renderer]
|
||||||
|
header = "Available states"
|
||||||
|
description = """\
|
||||||
|
The following states are found in this formula:
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
"""
|
||||||
|
main_heading_char = "-"
|
||||||
|
sub_heading_char = "^"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
name: share
|
name: share
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
gitea:
|
gitea:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
# libtofs.jinja must work with tofs.files_switch looked up list
|
# libtofs.jinja must work with tofs.files_switch looked up list
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
portage:
|
portage:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
base:
|
base:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: ft=yaml
|
# vim: ft=yaml
|
||||||
---
|
---
|
||||||
gitea:
|
gitea:
|
||||||
|
|||||||
Reference in New Issue
Block a user