diff --git a/.github/workflows/automatic-doc-checks.yml b/.github/workflows/automatic-doc-checks.yml new file mode 100644 index 0000000..479ebcb --- /dev/null +++ b/.github/workflows/automatic-doc-checks.yml @@ -0,0 +1,24 @@ +# +name: Automatic doc checks + +on: + push: + branches: [ main ] + pull_request: + paths: + - 'docs/**' # Only run on changes to the docs directory + + workflow_dispatch: + # Manual trigger + + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + documentation-checks: + uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main + with: + working-directory: "docs" + fetch-depth: 0 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml deleted file mode 100644 index 665c2e5..0000000 --- a/.github/workflows/tests.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: Tests - - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - - -jobs: - docs-check: - name: "Check docs" - uses: canonical/documentation-workflows/.github/workflows/documentation-checks.yaml@main - with: - working-directory: "docs" - fetch-depth: 0 - - markdown-lint: - name: "Lint Markdown" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: DavidAnson/markdownlint-cli2-action@v19 - with: - config: "docs/.sphinx/.markdownlint.json" - globs: | - **/*.{md,markdown} - ! docs/.sphinx/** diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..ec26cd6 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,39 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + jobs: + post_checkout: + - git fetch --unshallow || true + # Cancel building pull requests when there aren't changed in the docs directory. + # If there are no changes (git diff exits with 0) we force the command to return with 183. + # This is a special exit code on Read the Docs that will cancel the build immediately. + # https://docs.readthedocs.io/en/stable/build-customization.html#cancel-build-based-on-a-condition + - | + if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/main -- 'docs/' '.readthedocs.yaml'; + then + exit 183; + fi + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: dirhtml + configuration: docs/conf.py + fail_on_warning: true + +# If using Sphinx, optionally build your docs in additional formats such as PDF +formats: +- pdf + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: docs/requirements.txt diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..aad78f1 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,26 @@ +# Environment +*env*/ +.sphinx/venv/ + +# Sphinx +.sphinx/warnings.txt +.sphinx/.wordlist.dic +.sphinx/.doctrees/ +.sphinx/update/ +.sphinx/node_modules/ + +# Vale +.sphinx/styles/* +.sphinx/vale.ini + +# Build outputs +_build + +# Node.js +package*.json + +# Unrelated cache and config files +.DS_Store +__pycache__ +.idea/ +.vscode/ diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml deleted file mode 100644 index f170b00..0000000 --- a/docs/.readthedocs.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# .readthedocs.yaml -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -# Required -version: 2 - -# Set the version of Python and other tools you might need -build: - os: ubuntu-22.04 - tools: - python: "3.11" - jobs: - pre_install: - - git fetch --unshallow || true - -# Build documentation in the docs/ directory with Sphinx -sphinx: - builder: dirhtml - configuration: docs/conf.py - fail_on_warning: true - -# If using Sphinx, optionally build your docs in additional formats such as PDF -formats: - - pdf - -# Optionally declare the Python requirements required to build your docs -python: - install: - - requirements: docs/.sphinx/requirements.txt diff --git a/docs/.sphinx/.markdownlint.json b/docs/.sphinx/.markdownlint.json deleted file mode 100644 index 8aafaf6..0000000 --- a/docs/.sphinx/.markdownlint.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "default": false, - "MD003": { "style": "atx" }, - "MD013": { "code_blocks": false, "tables": false, "stern": true, "line_length": 150}, - "MD014": true, - "MD018": true, - "MD022": true, - "MD023": true, - "MD026": { "punctuation": ".,;。,;"}, - "MD031": { "list_items": false}, - "MD032": true, - "MD035": true, - "MD042": true, - "MD045": true, - "MD052": true -} \ No newline at end of file diff --git a/docs/.sphinx/.pre-commit-config.yaml b/docs/.sphinx/.pre-commit-config.yaml new file mode 100644 index 0000000..07e0b48 --- /dev/null +++ b/docs/.sphinx/.pre-commit-config.yaml @@ -0,0 +1,23 @@ +repos: + - repo: local + hooks: + - id: make-spelling + name: Run make spelling + entry: make -C docs spelling + language: system + pass_filenames: false + files: ^docs/.*\.(rst|md|txt)$ + + - id: make-linkcheck + name: Run make linkcheck + entry: make -C docs linkcheck + language: system + pass_filenames: false + files: ^docs/.*\.(rst|md|txt)$ + + - id: make-woke + name: Run make woke + entry: make -C docs woke + language: system + pass_filenames: false + files: ^docs/.*\.(rst|md|txt)$ diff --git a/docs/.sphinx/.pymarkdown.json b/docs/.sphinx/.pymarkdown.json new file mode 100644 index 0000000..2c4c669 --- /dev/null +++ b/docs/.sphinx/.pymarkdown.json @@ -0,0 +1,46 @@ +{ + "plugins": { + "selectively_enable_rules": true, + "heading-style": { + "enabled": true, + "style": "atx" + }, + "commands-show-output": { + "enabled": true + }, + "no-missing-space-atx": { + "enabled": true + }, + "blanks-around-headings": { + "enabled": true + }, + "heading-start-left": { + "enabled": true + }, + "no-trailing-punctuation": { + "enabled": true, + "punctuation": ".,;。,;" + }, + "blanks-around-fences": { + "enabled": true, + "list_items": false + }, + "blanks-around-lists": { + "enabled": true + }, + "hr-style": { + "enabled": true + }, + "no-empty-links": { + "enabled": true + }, + "no-alt-text": { + "enabled": true + } + }, + "extensions": { + "front-matter" : { + "enabled" : true + } + } +} diff --git a/docs/.sphinx/.wordlist.txt b/docs/.sphinx/.wordlist.txt deleted file mode 100644 index b0cfc2c..0000000 --- a/docs/.sphinx/.wordlist.txt +++ /dev/null @@ -1,77 +0,0 @@ -ACME -ACME's -addons -AGPLv -API -APIs -balancer -Charmhub -CLI -crypto -cryptographic -DCO -Diátaxis -Dqlite -dropdown -EBS -EKS -Etag -enablement -favicon -Furo -Git -GitHub -github -golang -GPG -Grafana -gz -IAM -InRelease -installable -JSON -Juju -Kubeflow -Kubernetes -Launchpad -linter -LTS -LXD -Makefile -Makefiles -Matrix -Mattermost -MicroCeph -MicroCloud -MicroOVN -MyST -namespace -namespaces -NodePort -Numbat -observability -OEM -OLM -openpgp -Permalink -PR -pre -PRs -Quickstart -ReadMe -RSA -reST -reStructuredText -roadmap -RTD -subdirectories -subfolders -subtree -TODO -Ubuntu -UI -UUID -VM -webhook -YAML -YAMLs diff --git a/docs/.sphinx/_static/css/pdf.css b/docs/.sphinx/_static/css/pdf.css deleted file mode 100644 index f9e28dd..0000000 --- a/docs/.sphinx/_static/css/pdf.css +++ /dev/null @@ -1,15 +0,0 @@ -/* Only relevant for specific PDF generation issues */ - -.rubric>.hclass2 { - display: block; - font-size: 2em; - border-radius: .5rem; - font-weight: 300; - line-height: 1.25; - margin-top: 1.75rem; - margin-right: -0.5rem; - margin-bottom: 0.5rem; - margin-left: -0.5rem; - padding-left: .5rem; - padding-right: .5rem; -} \ No newline at end of file diff --git a/docs/.sphinx/_static/favicon.png b/docs/.sphinx/_static/favicon.png deleted file mode 100644 index 7f175e4..0000000 Binary files a/docs/.sphinx/_static/favicon.png and /dev/null differ diff --git a/docs/.sphinx/_static/js/checkbox.js b/docs/.sphinx/_static/js/checkbox.js deleted file mode 100644 index f0925b7..0000000 --- a/docs/.sphinx/_static/js/checkbox.js +++ /dev/null @@ -1,5 +0,0 @@ -document.addEventListener("DOMContentLoaded", () => { - document.querySelectorAll("input[type='checkbox'][disabled]").forEach(cb => { - cb.removeAttribute("disabled"); - }); -}); diff --git a/docs/.sphinx/_static/tag.png b/docs/.sphinx/_static/tag.png deleted file mode 100644 index f6f6e5a..0000000 Binary files a/docs/.sphinx/_static/tag.png and /dev/null differ diff --git a/docs/.sphinx/_templates/header.html b/docs/.sphinx/_templates/header.html deleted file mode 100644 index 30c52c5..0000000 --- a/docs/.sphinx/_templates/header.html +++ /dev/null @@ -1,52 +0,0 @@ - diff --git a/docs/.sphinx/fonts/LICENCE.txt b/docs/.sphinx/fonts/LICENCE.txt deleted file mode 100644 index ae78a8f..0000000 --- a/docs/.sphinx/fonts/LICENCE.txt +++ /dev/null @@ -1,96 +0,0 @@ -------------------------------- -UBUNTU FONT LICENCE Version 1.0 -------------------------------- - -PREAMBLE -This licence allows the licensed fonts to be used, studied, modified and -redistributed freely. The fonts, including any derivative works, can be -bundled, embedded, and redistributed provided the terms of this licence -are met. The fonts and derivatives, however, cannot be released under -any other licence. The requirement for fonts to remain under this -licence does not require any document created using the fonts or their -derivatives to be published under this licence, as long as the primary -purpose of the document is not to be a vehicle for the distribution of -the fonts. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this licence and clearly marked as such. This may -include source files, build scripts and documentation. - -"Original Version" refers to the collection of Font Software components -as received under this licence. - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to -a new environment. - -"Copyright Holder(s)" refers to all individuals and companies who have a -copyright ownership of the Font Software. - -"Substantially Changed" refers to Modified Versions which can be easily -identified as dissimilar to the Font Software by users of the Font -Software comparing the Original Version with the Modified Version. - -To "Propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification and with or without charging -a redistribution fee), making available to the public, and in some -countries other activities as well. - -PERMISSION & CONDITIONS -This licence does not grant any rights under trademark law and all such -rights are reserved. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of the Font Software, to propagate the Font Software, subject to -the below conditions: - -1) Each copy of the Font Software must contain the above copyright -notice and this licence. These can be included either as stand-alone -text files, human-readable headers or in the appropriate machine- -readable metadata fields within text or binary files as long as those -fields can be easily viewed by the user. - -2) The font name complies with the following: -(a) The Original Version must retain its name, unmodified. -(b) Modified Versions which are Substantially Changed must be renamed to -avoid use of the name of the Original Version or similar names entirely. -(c) Modified Versions which are not Substantially Changed must be -renamed to both (i) retain the name of the Original Version and (ii) add -additional naming elements to distinguish the Modified Version from the -Original Version. The name of such Modified Versions must be the name of -the Original Version, with "derivative X" where X represents the name of -the new work, appended to that name. - -3) The name(s) of the Copyright Holder(s) and any contributor to the -Font Software shall not be used to promote, endorse or advertise any -Modified Version, except (i) as required by this licence, (ii) to -acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with -their explicit written permission. - -4) The Font Software, modified or unmodified, in part or in whole, must -be distributed entirely under this licence, and must not be distributed -under any other licence. The requirement for fonts to remain under this -licence does not affect any document created using the Font Software, -except any version of the Font Software extracted from a document -created using the Font Software may only be distributed under this -licence. - -TERMINATION -This licence becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF -COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER -DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/.sphinx/fonts/Ubuntu-B.ttf b/docs/.sphinx/fonts/Ubuntu-B.ttf deleted file mode 100644 index b173da2..0000000 Binary files a/docs/.sphinx/fonts/Ubuntu-B.ttf and /dev/null differ diff --git a/docs/.sphinx/fonts/Ubuntu-R.ttf b/docs/.sphinx/fonts/Ubuntu-R.ttf deleted file mode 100644 index d748728..0000000 Binary files a/docs/.sphinx/fonts/Ubuntu-R.ttf and /dev/null differ diff --git a/docs/.sphinx/fonts/Ubuntu-RI.ttf b/docs/.sphinx/fonts/Ubuntu-RI.ttf deleted file mode 100644 index 4f2d2bc..0000000 Binary files a/docs/.sphinx/fonts/Ubuntu-RI.ttf and /dev/null differ diff --git a/docs/.sphinx/fonts/UbuntuMono-B.ttf b/docs/.sphinx/fonts/UbuntuMono-B.ttf deleted file mode 100644 index 7bd6665..0000000 Binary files a/docs/.sphinx/fonts/UbuntuMono-B.ttf and /dev/null differ diff --git a/docs/.sphinx/fonts/UbuntuMono-R.ttf b/docs/.sphinx/fonts/UbuntuMono-R.ttf deleted file mode 100644 index fdd309d..0000000 Binary files a/docs/.sphinx/fonts/UbuntuMono-R.ttf and /dev/null differ diff --git a/docs/.sphinx/fonts/UbuntuMono-RI.ttf b/docs/.sphinx/fonts/UbuntuMono-RI.ttf deleted file mode 100644 index 18f81a2..0000000 Binary files a/docs/.sphinx/fonts/UbuntuMono-RI.ttf and /dev/null differ diff --git a/docs/.sphinx/get_vale_conf.py b/docs/.sphinx/get_vale_conf.py old mode 100644 new mode 100755 index 9ee2d0b..13e7966 --- a/docs/.sphinx/get_vale_conf.py +++ b/docs/.sphinx/get_vale_conf.py @@ -1,53 +1,151 @@ #! /usr/bin/env python -import requests import os +import shutil +import subprocess +import tempfile +import sys +import logging +import argparse -DIR = os.getcwd() +# Configure logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' +) +SPHINX_DIR = os.path.join(os.getcwd(), ".sphinx") -def main(): - if os.path.exists(f"{DIR}/.sphinx/styles/Canonical"): - print("Vale directory exists") - else: - os.makedirs(f"{DIR}/.sphinx/styles/Canonical") - - url = ( - "https://api.github.com/repos/canonical/praecepta/" - + "contents/styles/Canonical" - ) - r = requests.get(url) - for item in r.json(): - download = requests.get(item["download_url"]) - file = open(".sphinx/styles/Canonical/" + item["name"], "w") - file.write(download.text) - file.close() - - if os.path.exists(f"{DIR}/.sphinx/styles/config/vocabularies/Canonical"): - print("Vocab directory exists") - else: - os.makedirs(f"{DIR}/.sphinx/styles/config/vocabularies/Canonical") - - url = ( - "https://api.github.com/repos/canonical/praecepta/" - + "contents/styles/config/vocabularies/Canonical" - ) - r = requests.get(url) - for item in r.json(): - download = requests.get(item["download_url"]) - file = open( - ".sphinx/styles/config/vocabularies/Canonical/" + item["name"], - "w" +GITHUB_REPO = "canonical/documentation-style-guide" +GITHUB_CLONE_URL = f"https://github.com/{GITHUB_REPO}.git" + +# Source paths to copy from repo +VALE_FILE_LIST = [ + "styles/Canonical", + "styles/config/vocabularies/Canonical", + "styles/config/dictionaries", + "vale.ini" +] + +def clone_repo_and_copy_paths(file_source_dest, overwrite=False): + """ + Clone the repository to a temporary directory and copy required files + + Args: + file_source_dest: dictionary of file paths to copy from the repository, + and their destination paths + overwrite: boolean flag to overwrite existing files in the destination + + Returns: + bool: True if all files were copied successfully, False otherwise + """ + + if not file_source_dest: + logging.error("No files to copy") + return False + + # Create temporary directory on disk for cloning + temp_dir = tempfile.mkdtemp() + logging.info("Cloning repository <%s> to temporary directory: %s", GITHUB_REPO, temp_dir) + clone_cmd = ["git", "clone", "--depth", "1", GITHUB_CLONE_URL, temp_dir] + + try: + result = subprocess.run( + clone_cmd, + capture_output=True, + text=True, + check=True ) - file.write(download.text) - file.close() - config = requests.get( - "https://raw.githubusercontent.com/canonical/praecepta/main/vale.ini" - ) - file = open(".sphinx/vale.ini", "w") - file.write(config.text) - file.close() + logging.debug("Git clone output: %s", result.stdout) + except subprocess.CalledProcessError as e: + logging.error("Git clone failed: %s", e.stderr) + return False + + # Copy files from the cloned repository to the destination paths + is_copy_success = True + for source, dest in file_source_dest.items(): + source_path = os.path.join(temp_dir, source) + + if not os.path.exists(source_path): + is_copy_success = False + logging.error("Source path not found: %s", source_path) + continue + + if not copy_files_to_path(source_path, dest, overwrite): + is_copy_success = False + logging.error("Failed to copy %s to %s", source_path, dest) + + # Clean up temporary directory + logging.info("Cleaning up temporary directory: %s", temp_dir) + shutil.rmtree(temp_dir) + + return is_copy_success + +def copy_files_to_path(source_path, dest_path, overwrite=False): + """ + Copy a file or directory from source to destination + + Args: + source_path: Path to the source file or directory + dest_path: Path to the destination + overwrite: Boolean flag to overwrite existing files in the destination + + Returns: + bool: True if copy was successful, False otherwise + """ + # Skip if source file doesn't exist + if not os.path.exists(source_path): + logging.warning("Source path not found: %s", source_path) + return False + + logging.info("Copying %s to %s", source_path, dest_path) + # Handle existing files + if os.path.exists(dest_path): + if overwrite: + logging.info(" Destination exists, overwriting: %s", dest_path) + if os.path.isdir(dest_path): + shutil.rmtree(dest_path) + else: + os.remove(dest_path) + else: + logging.info(" Destination exists, skip copying (use overwrite=True to replace): %s", + dest_path) + return True # Skip copying + + # Copy the source to destination + try: + if os.path.isdir(source_path): + # entire directory + shutil.copytree(source_path, dest_path) + else: + # individual files + shutil.copy2(source_path, dest_path) + return True + except (shutil.Error, OSError) as e: + logging.error("Copy failed: %s", e) + return False + +def parse_arguments(): + parser = argparse.ArgumentParser(description="Download Vale configuration files") + parser.add_argument("--no-overwrite", action="store_true", help="Don't overwrite existing files") + return parser.parse_args() + +def main(): + # Define local directory paths + vale_files_dict = {file: os.path.join(SPHINX_DIR, file) for file in VALE_FILE_LIST} + + # Parse command line arguments, default to overwrite_enabled = True + overwrite_enabled = not parse_arguments().no_overwrite + + # Download into /tmp through git clone + if not clone_repo_and_copy_paths(vale_files_dict, overwrite=overwrite_enabled): + logging.error("Failed to download files from repository") + return 1 + + logging.info("Download complete") + return 0 if __name__ == "__main__": - main() + sys.exit(main()) # Keep return code diff --git a/docs/.sphinx/images/Canonical-logo-4x.png b/docs/.sphinx/images/Canonical-logo-4x.png deleted file mode 100644 index fd75696..0000000 Binary files a/docs/.sphinx/images/Canonical-logo-4x.png and /dev/null differ diff --git a/docs/.sphinx/images/front-page-light.pdf b/docs/.sphinx/images/front-page-light.pdf deleted file mode 100644 index bb68cdf..0000000 Binary files a/docs/.sphinx/images/front-page-light.pdf and /dev/null differ diff --git a/docs/.sphinx/images/normal-page-footer.pdf b/docs/.sphinx/images/normal-page-footer.pdf deleted file mode 100644 index dfd73cb..0000000 Binary files a/docs/.sphinx/images/normal-page-footer.pdf and /dev/null differ diff --git a/docs/.sphinx/latex_elements_template.txt b/docs/.sphinx/latex_elements_template.txt deleted file mode 100644 index 322412c..0000000 --- a/docs/.sphinx/latex_elements_template.txt +++ /dev/null @@ -1,119 +0,0 @@ -{ - 'papersize': 'a4paper', - 'pointsize': '11pt', - 'fncychap': '', - 'preamble': r''' -%\usepackage{charter} -%\usepackage[defaultsans]{lato} -%\usepackage{inconsolata} -\setmainfont[UprightFont = *-R, BoldFont = *-B, ItalicFont=*-RI, Extension = .ttf]{Ubuntu} -\setmonofont[UprightFont = *-R, BoldFont = *-B, ItalicFont=*-RI, Extension = .ttf]{UbuntuMono} -\usepackage[most]{tcolorbox} -\tcbuselibrary{breakable} -\usepackage{lastpage} -\usepackage{tabto} -\usepackage{ifthen} -\usepackage{etoolbox} -\usepackage{fancyhdr} -\usepackage{graphicx} -\usepackage{titlesec} -\usepackage{fontspec} -\usepackage{tikz} -\usepackage{changepage} -\usepackage{array} -\usepackage{tabularx} -\definecolor{yellowgreen}{RGB}{154, 205, 50} -\definecolor{title}{RGB}{76, 17, 48} -\definecolor{subtitle}{RGB}{116, 27, 71} -\definecolor{label}{RGB}{119, 41, 100} -\definecolor{copyright}{RGB}{174, 167, 159} -\makeatletter -\def\tcb@finalize@environment{% - \color{.}% hack for xelatex - \tcb@layer@dec% -} -\makeatother -\newenvironment{sphinxclassprompt}{\color{yellowgreen}\setmonofont[Color = 9ACD32, UprightFont = *-R, Extension = .ttf]{UbuntuMono}}{} -\tcbset{enhanced jigsaw, colback=black, fontupper=\color{white}} -\newtcolorbox{termbox}{use color stack, breakable, colupper=white, halign=flush left} -\newenvironment{sphinxclassterminal}{\setmonofont[Color = white, UprightFont = *-R, Extension = .ttf]{UbuntuMono}\sphinxsetup{VerbatimColor={black}}\begin{termbox}}{\end{termbox}} -\newcommand{\dimtorightedge}{% - \dimexpr\paperwidth-1in-\hoffset-\oddsidemargin\relax} -\newcommand{\dimtotop}{% - \dimexpr\height-1in-\voffset-\topmargin-\headheight-\headsep\relax} -\newtoggle{tpage} -\AtBeginEnvironment{titlepage}{\global\toggletrue{tpage}} -\fancypagestyle{plain}{ - \fancyhf{} - \fancyfoot[R]{\thepage\ of \pageref*{LastPage}} - \renewcommand{\headrulewidth}{0pt} - \renewcommand{\footrulewidth}{0pt} -} -\fancypagestyle{normal}{ - \fancyhf{} - \fancyfoot[R]{\thepage\ of \pageref*{LastPage}} - \renewcommand{\headrulewidth}{0pt} - \renewcommand{\footrulewidth}{0pt} -} -\fancypagestyle{titlepage}{% - \fancyhf{} - \fancyfoot[L]{\footnotesize \textcolor{copyright}{© 2024 Canonical Ltd. All rights reserved.}} -} -\newcommand\sphinxbackoftitlepage{\thispagestyle{titlepage}} -\titleformat{\chapter}[block]{\Huge \color{title} \bfseries\filright}{\thechapter .}{1.5ex}{} -\titlespacing{\chapter}{0pt}{0pt}{0pt} -\titleformat{\section}[block]{\huge \bfseries\filright}{\thesection .}{1.5ex}{} -\titlespacing{\section}{0pt}{0pt}{0pt} -\titleformat{\subsection}[block]{\Large \bfseries\filright}{\thesubsection .}{1.5ex}{} -\titlespacing{\subsection}{0pt}{0pt}{0pt} -\setcounter{tocdepth}{1} -\renewcommand\pagenumbering[1]{} -''', - 'sphinxsetup': 'verbatimwithframe=false, pre_border-radius=0pt, verbatimvisiblespace=\\phantom{}, verbatimcontinued=\\phantom{}', - 'extraclassoptions': 'openany,oneside', - 'maketitle': r''' -\begin{titlepage} -\begin{flushleft} - \begin{tikzpicture}[remember picture,overlay] - \node[anchor=south east, inner sep=0] at (current page.south east) { - \includegraphics[width=\paperwidth, height=\paperheight]{front-page-light} - }; - \end{tikzpicture} -\end{flushleft} - -\vspace*{3cm} - -\begin{adjustwidth}{8cm}{0pt} -\begin{flushleft} - \huge \textcolor{black}{\textbf{}{\raggedright{$PROJECT}}} -\end{flushleft} -\end{adjustwidth} - -\vfill - -\begin{adjustwidth}{8cm}{0pt} -\begin{tabularx}{0.5\textwidth}{ l l } - \textcolor{lightgray}{© 2024 Canonical Ltd.} & \hspace{3cm} \\ - \textcolor{lightgray}{All rights reserved.} & \hspace{3cm} \\ - & \hspace{3cm} \\ - & \hspace{3cm} \\ - -\end{tabularx} -\end{adjustwidth} - -\end{titlepage} -\RemoveFromHook{shipout/background} -\AddToHook{shipout/background}{ - \begin{tikzpicture}[remember picture,overlay] - \node[anchor=south west, align=left, inner sep=0] at (current page.south west) { - \includegraphics[width=\paperwidth]{normal-page-footer} - }; - \end{tikzpicture} - \begin{tikzpicture}[remember picture,overlay] - \node[anchor=north east, opacity=0.5, inner sep=35] at (current page.north east) { - \includegraphics[width=4cm]{Canonical-logo-4x} - }; - \end{tikzpicture} - } -''', -} \ No newline at end of file diff --git a/docs/.sphinx/metrics/build_metrics.py b/docs/.sphinx/metrics/build_metrics.py new file mode 100755 index 0000000..529fb85 --- /dev/null +++ b/docs/.sphinx/metrics/build_metrics.py @@ -0,0 +1,94 @@ +#!/usr/bin/python3 + +import sys +import argparse +from pathlib import Path +from html.parser import HTMLParser +from urllib.parse import urlsplit + + +class MetricsParser(HTMLParser): + def __init__(self): + super().__init__() + self.int_link_count = 0 + self.ext_link_count = 0 + self.fragment_count = 0 + self.image_count = 0 + self.in_object = 0 + + @property + def link_count(self): + return self.fragment_count + self.int_link_count + self.ext_link_count + + def read(self, file): + """ + Read *file* (a file-like object with a ``read`` method returning + strings) a chunk at a time, feeding each chunk to the parser. + """ + # Ensure the parser state is reset before each file (just in case + # there's an erroneous dangling ) + self.reset() + self.in_object = 0 + buf = '' + while True: + # Parse 1MB chunks at a time + buf = file.read(1024**2) + if not buf: + break + self.feed(buf) + + def handle_starttag(self, tag, attrs): + """ + Count , , and tags to determine the number of internal + and external links, and the number of images. + """ + attrs = dict(attrs) + if tag == 'a' and 'href' in attrs: + # If there's no href, it's an anchor; if there's no hostname + # (netloc) or path, it's just a fragment link within the page + url = urlsplit(attrs['href']) + if url.netloc: + self.ext_link_count += 1 + elif url.path: + self.int_link_count += 1 + else: + self.fragment_count += 1 + elif tag == 'object': + # tags are a bit complex as they nest to offer fallbacks + # and may contain an fallback. We only want to count the + # outer-most in this case + if self.in_object == 0: + self.image_count += 1 + self.in_object += 1 + elif tag == 'img' and self.in_object == 0: + self.image_count += 1 + + def handle_endtag(self, tag): + if tag == 'object': + # Never let in_object be negative + self.in_object = max(0, self.in_object - 1) + + +def main(args=None): + parser = argparse.ArgumentParser() + parser.add_argument( + 'build_dir', metavar='build-dir', nargs='?', default='.', + help="The directory to scan for HTML files") + config = parser.parse_args(args) + + parser = MetricsParser() + for path in Path(config.build_dir).rglob('*.html'): + with path.open('r', encoding='utf-8', errors='replace') as f: + parser.read(f) + + print('Summarising metrics for build files (.html)...') + print(f'\tlinks: {parser.link_count} (' + f'{parser.fragment_count} #frag…, ' + f'{parser.int_link_count} /int…, ' + f'{parser.ext_link_count} https://ext…' + ')') + print(f'\timages: {parser.image_count}') + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/docs/.sphinx/metrics/build_metrics.sh b/docs/.sphinx/metrics/build_metrics.sh deleted file mode 100755 index bd1ff1c..0000000 --- a/docs/.sphinx/metrics/build_metrics.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# shellcheck disable=all - -links=0 -images=0 - -# count number of links -links=$(find . -type d -path './.sphinx' -prune -o -name '*.html' -exec cat {} + | grep -o " str: + """Get SHA of local files""" + logging.debug(f"Getting hash of {os.path.basename(file)}") + return subprocess.check_output(["git", "hash-object", file]).decode("ascii").strip() + + +# Examines local files +def get_local_files_and_paths(): + """Identify '.sphinx' local files and paths""" + logging.debug("Checking local files and paths") + try: + files = [] + paths = [] + patterns = [".*", "**.*", "metrics/**.*"] + files, paths = [], [] + + for pattern in patterns: + for file in glob.iglob(os.path.join(SPHINX_DIR, pattern), recursive=True): + files.append(os.path.basename(file)) + paths.append(file) + return files, paths + except Exception as e: + logging.debug(e) + raise RuntimeError("get_local_files_and_paths()") from e + + +# General API query with timeout and RequestException +def query_api(url): + """Query an API with a globally set timeout""" + logging.debug(f"Querying {url}") + try: + r = requests.get(url, timeout=TIMEOUT) + return r + except RequestException as e: + raise RuntimeError(f"Failed query_api(): {url}") from e + + +# General file download function +def download_file(url, output_path): + """Download a file to a specified path""" + logging.debug(f"Downloading {os.path.basename(output_path)}") + try: + os.makedirs(os.path.dirname(output_path), exist_ok=True) + with open(output_path, "wb") as file: + file.write(query_api(url).content) + except Exception as e: + logging.debug(e) + raise RuntimeError(f"Failed download_file(): {url}") from e + + +if __name__ == "__main__": + sys.exit(main()) # Keep return code diff --git a/docs/.sphinx/version b/docs/.sphinx/version new file mode 100644 index 0000000..f0bb29e --- /dev/null +++ b/docs/.sphinx/version @@ -0,0 +1 @@ +1.3.0 diff --git a/docs/Makefile b/docs/Makefile index 72fe7c6..de174a9 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,31 +1,185 @@ -# This Makefile stub allows you to customize starter pack (SP) targets. -# Consider this file as a bridge between your project -# and the starter pack's predefined targets that reside in Makefile.sp. +# Minimal makefile for Sphinx documentation # -# You can add your own, non-SP targets here or override SP targets -# to fit your project's needs. For example, you can define and use targets -# named "install" or "run", but continue to use SP targets like "sp-install" -# or "sp-run" when working on the documentation. +# Add your customisation to `Makefile` instead. + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXDIR = .sphinx +SPHINXOPTS ?= -c . -d $(SPHINXDIR)/.doctrees -j auto +SPHINXBUILD ?= $(VENVDIR)/bin/sphinx-build +SOURCEDIR = . +BUILDDIR = _build +VENVDIR = $(SPHINXDIR)/venv +PA11Y = $(SPHINXDIR)/node_modules/pa11y/bin/pa11y.js --config $(SPHINXDIR)/pa11y.json +VENV = $(VENVDIR)/bin/activate +TARGET = * +METRICSDIR = $(SOURCEDIR)/.sphinx/metrics +REQPDFPACKS = latexmk fonts-freefont-otf texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended texlive-font-utils texlive-lang-cjk texlive-xetex plantuml xindy tex-gyre dvipng +CONFIRM_SUDO ?= N +VALE_CONFIG = $(SPHINXDIR)/vale.ini +VALEDIR = $(SPHINXDIR)/venv/lib/python*/site-packages/vale +VOCAB_CANONICAL = $(SPHINXDIR)/styles/config/vocabularies/Canonical +SPHINX_HOST ?= 127.0.0.1 +SPHINX_PORT ?= 8000 # Put it first so that "make" without argument is like "make help". help: - @echo "\n" \ - "------------------------------------------------------------- \n" \ - "* watch, build and serve the documentation: make run \n" \ - "* only build: make html \n" \ - "* only serve: make serve \n" \ - "* clean built doc files: make clean-doc \n" \ - "* clean full environment: make clean \n" \ - "* check links: make linkcheck \n" \ - "* check spelling: make spelling \n" \ - "* check spelling (without building again): make spellcheck \n" \ - "* check inclusive language: make woke \n" \ - "* check accessibility: make pa11y \n" \ - "* check style guide compliance: make vale \n" \ - "* check style guide compliance on target: make vale TARGET=* \n" \ - "* check metrics for documentation: make allmetrics \n" \ - "* other possible targets: make \n" \ - "------------------------------------------------------------- \n" + @echo + @echo "-------------------------------------------------------------" + @echo "* watch, build and serve the documentation: make run" + @echo "* only build: make html" + @echo "* only serve: make serve" + @echo "* clean built doc files: make clean-doc" + @echo "* clean full environment: make clean" + @echo "* check links: make linkcheck" + @echo "* check markdown: make lint-md" + @echo "* check spelling: make spelling" + @echo "* check spelling (without building again): make spellcheck" + @echo "* check inclusive language: make woke" + @echo "* check accessibility: make pa11y" + @echo "* check style guide compliance: make vale" + @echo "* check style guide compliance on target: make vale TARGET=*" + @echo "* check metrics for documentation: make allmetrics" + @echo "* other possible targets: make " + @echo "-------------------------------------------------------------" + @echo + +.PHONY: help full‑help html epub pdf linkcheck spelling spellcheck woke \ + vale pa11y run serve install pa11y‑install \ + vale‑install pdf‑prep pdf‑prep‑force clean clean‑doc allmetrics \ + update lint-md + +full-help: $(VENVDIR) + @. $(VENV); $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + @echo "\n\033[1;31mNOTE: This help texts shows unsupported targets!\033[0m" + @echo "Run 'make help' to see supported targets." + +# If requirements are updated, venv should be rebuilt and timestamped. +$(VENVDIR): + @echo "... setting up virtualenv" + python3 -m venv $(VENVDIR) || { echo "You must install python3-venv before you can build the documentation."; exit 1; } + . $(VENV); pip install $(PIPOPTS) --require-virtualenv \ + --upgrade -r requirements.txt \ + --log $(VENVDIR)/pip_install.log + @test ! -f $(VENVDIR)/pip_list.txt || \ + mv $(VENVDIR)/pip_list.txt $(VENVDIR)/pip_list.txt.bak + @. $(VENV); pip list --local --format=freeze > $(VENVDIR)/pip_list.txt + @touch $(VENVDIR) + +pa11y-install: + @command -v $(PA11Y) >/dev/null || { \ + echo "Installing \"pa11y\" from npm..."; echo; \ + mkdir -p $(SPHINXDIR)/node_modules/ ; \ + npm install --prefix $(SPHINXDIR) pa11y; \ + } + +pymarkdownlnt-install: + @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/pymarkdown || pip install pymarkdownlnt + +install: $(VENVDIR) + +run: install + . $(VENV); $(VENVDIR)/bin/sphinx-autobuild -b dirhtml --host $(SPHINX_HOST) --port $(SPHINX_PORT) "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) + +# Does not depend on $(BUILDDIR) to rebuild properly at every run. +html: install + . $(VENV); $(SPHINXBUILD) --fail-on-warning --keep-going -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) + +epub: install + . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) + +serve: html + cd "$(BUILDDIR)"; python3 -m http.server --bind $(SPHINX_HOST) $(SPHINX_PORT) + +clean: clean-doc + @test ! -e "$(VENVDIR)" -o -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" + rm -rf $(VENVDIR) + rm -rf $(SPHINXDIR)/node_modules/ + rm -rf $(SPHINXDIR)/styles + rm -rf $(VALE_CONFIG) + +clean-doc: + git clean -fx "$(BUILDDIR)" + rm -rf $(SPHINXDIR)/.doctrees + +linkcheck: install + . $(VENV) ; $(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) || { grep --color -F "[broken]" "$(BUILDDIR)/output.txt"; exit 1; } + exit 0 + +pa11y: pa11y-install html + find $(BUILDDIR) -name *.html -print0 | xargs -n 1 -0 $(PA11Y) + +lint-md: pymarkdownlnt-install + @. $(VENV); pymarkdownlnt --config $(SPHINXDIR)/.pymarkdown.json scan --recurse --exclude=./$(SPHINXDIR)/** $(SOURCEDIR) + +vale-install: install + @. $(VENV); test -f $(VALE_CONFIG) || python3 $(SPHINXDIR)/get_vale_conf.py + @echo '.Name=="Canonical.400-Enforce-inclusive-terms"' > $(SPHINXDIR)/styles/woke.filter + @echo '.Level=="error" and .Name!="Canonical.500-Repeated-words" and .Name!="Canonical.000-US-spellcheck"' > $(SPHINXDIR)/styles/error.filter + @echo '.Name=="Canonical.000-US-spellcheck"' > $(SPHINXDIR)/styles/spelling.filter + @. $(VENV); find $(VALEDIR)/vale_bin -size 195c -exec vale --version \; + +woke: vale-install + @cat $(VOCAB_CANONICAL)/accept.txt > $(VOCAB_CANONICAL)/accept_backup.txt + @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(VOCAB_CANONICAL)/accept.txt + @echo "Running Vale acceptable term check against $(TARGET). To change target set TARGET= with make command" + @. $(VENV); vale --config="$(VALE_CONFIG)" --filter='$(SPHINXDIR)/styles/woke.filter' --glob='*.{md,rst}' $(TARGET) + @cat $(VOCAB_CANONICAL)/accept_backup.txt > $(VOCAB_CANONICAL)/accept.txt && rm $(VOCAB_CANONICAL)/accept_backup.txt + +vale: vale-install + @cat $(VOCAB_CANONICAL)/accept.txt > $(VOCAB_CANONICAL)/accept_backup.txt + @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(VOCAB_CANONICAL)/accept.txt + @echo "Running Vale against $(TARGET). To change target set TARGET= with make command" + @. $(VENV); vale --config="$(VALE_CONFIG)" --filter='$(SPHINXDIR)/styles/error.filter' --glob='*.{md,rst}' $(TARGET) + @cat $(VOCAB_CANONICAL)/accept_backup.txt > $(VOCAB_CANONICAL)/accept.txt && rm $(VOCAB_CANONICAL)/accept_backup.txt + +spelling: vale-install + @cat $(VOCAB_CANONICAL)/accept.txt > $(VOCAB_CANONICAL)/accept_backup.txt + @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(VOCAB_CANONICAL)/accept.txt + @echo "Running Vale against $(TARGET). To change target set TARGET= with make command" + @. $(VENV); vale --config="$(VALE_CONFIG)" --filter='$(SPHINXDIR)/styles/spelling.filter' --glob='*.{md,rst}' $(TARGET) + @cat $(VOCAB_CANONICAL)/accept_backup.txt > $(VOCAB_CANONICAL)/accept.txt && rm $(VOCAB_CANONICAL)/accept_backup.txt + +spellcheck: spelling + @echo "Please note that the \`make spellcheck\` command is being deprecated in favor of \`make spelling\`" + +pdf-prep: install + @for packageName in $(REQPDFPACKS); do (dpkg-query -W -f='$${Status}' $$packageName 2>/dev/null | \ + grep -c "ok installed" >/dev/null && echo "Package $$packageName is installed") && continue || \ + (echo; echo "PDF generation requires the installation of the following packages: $(REQPDFPACKS)" && \ + echo "" && echo "Run 'sudo make pdf-prep-force' to install these packages" && echo "" && echo \ + "Please be aware these packages will be installed to your system") && exit 1 ; done + +pdf-prep-force: + apt-get update + apt-get upgrade -y + apt-get install --no-install-recommends -y $(REQPDFPACKS) \ + +pdf: pdf-prep + @. $(VENV); sphinx-build -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) + @rm ./$(BUILDDIR)/latex/front-page-light.pdf || true + @rm ./$(BUILDDIR)/latex/normal-page-footer.pdf || true + @find ./$(BUILDDIR)/latex -name "*.pdf" -exec mv -t ./$(BUILDDIR) {} + + @rm -r $(BUILDDIR)/latex + @echo + @echo "Output can be found in ./$(BUILDDIR)" + @echo + +allmetrics: html + @echo "Recording documentation metrics..." + @echo "Checking for existence of vale..." + . $(VENV) + @. $(VENV); test -d $(VALEDIR) || pip install vale + @. $(VENV); test -f $(VALE_CONFIG) || python3 $(SPHINXDIR)/get_vale_conf.py + @. $(VENV); find $(VALEDIR)/vale_bin -size 195c -exec vale --config "$(VALE_CONFIG)" $(TARGET) > /dev/null \; + @eval '$(METRICSDIR)/source_metrics.sh $(PWD)' + @. $(VENV); python3 $(METRICSDIR)/build_metrics.py $(BUILDDIR) + +update: install + @. $(VENV); .sphinx/update_sp.py +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: - $(MAKE) -f Makefile.sp sp-$@ + $(MAKE) --no-print-directory install + . $(VENV); $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/Makefile.sp b/docs/Makefile.sp deleted file mode 100644 index beaf79d..0000000 --- a/docs/Makefile.sp +++ /dev/null @@ -1,170 +0,0 @@ -# Minimal makefile for Sphinx documentation -# -# `Makefile.sp` is from the Sphinx starter pack and should not be -# modified. -# Add your customisation to `Makefile` instead. - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXDIR = .sphinx -SPHINXOPTS ?= -c . -d $(SPHINXDIR)/.doctrees -j auto -SPHINXBUILD ?= $(VENVDIR)/bin/sphinx-build -SOURCEDIR = . -BUILDDIR = _build -VENVDIR = $(SPHINXDIR)/venv -PA11Y = $(SPHINXDIR)/node_modules/pa11y/bin/pa11y.js --config $(SPHINXDIR)/pa11y.json -VENV = $(VENVDIR)/bin/activate -TARGET = * -ALLFILES = *.rst **/*.rst -METRICSDIR = $(SOURCEDIR)/.sphinx/metrics -REQPDFPACKS = latexmk fonts-freefont-otf texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended texlive-font-utils texlive-lang-cjk texlive-xetex plantuml xindy tex-gyre dvipng -CONFIRM_SUDO ?= N - -.PHONY: sp-full-help sp-woke-install sp-spellcheck-install sp-pa11y-install sp-install sp-run sp-html \ - sp-epub sp-serve sp-clean sp-clean-doc sp-spelling sp-spellcheck sp-linkcheck sp-woke \ - sp-allmetrics sp-pa11y sp-pdf-prep-force sp-pdf-prep sp-pdf Makefile.sp sp-vale sp-bash - -sp-full-help: $(VENVDIR) - @. $(VENV); $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - @echo "\n\033[1;31mNOTE: This help texts shows unsupported targets!\033[0m" - @echo "Run 'make help' to see supported targets." - -# If requirements are updated, venv should be rebuilt and timestamped. -$(VENVDIR): - python3 -c "import venv" || \ - (echo "You must install python3-venv before you can build the documentation."; exit 1) - @echo "... setting up virtualenv" - python3 -m venv $(VENVDIR) - . $(VENV); pip install $(PIPOPTS) --require-virtualenv \ - --upgrade -r $(SPHINXDIR)/requirements.txt \ - --log $(VENVDIR)/pip_install.log - @test ! -f $(VENVDIR)/pip_list.txt || \ - mv $(VENVDIR)/pip_list.txt $(VENVDIR)/pip_list.txt.bak - @. $(VENV); pip list --local --format=freeze > $(VENVDIR)/pip_list.txt - @touch $(VENVDIR) - -sp-woke-install: - @type woke >/dev/null 2>&1 || \ - { \ - echo "Installing system-wide \"woke\" snap..."; \ - confirm_sudo=$(CONFIRM_SUDO); \ - if [ "$$confirm_sudo" != "y" ] && [ "$$confirm_sudo" != "Y" ]; then \ - read -p "This requires sudo privileges. Proceed? [y/N]: " confirm_sudo; \ - fi; \ - if [ "$$confirm_sudo" = "y" ] || [ "$$confirm_sudo" = "Y" ]; then \ - sudo snap install woke; \ - else \ - echo "Installation cancelled."; \ - fi \ - } - -sp-spellcheck-install: - @type aspell >/dev/null 2>&1 || \ - { \ - echo "Installing system-wide \"aspell\" packages..."; \ - confirm_sudo=$(CONFIRM_SUDO); \ - if [ "$$confirm_sudo" != "y" ] && [ "$$confirm_sudo" != "Y" ]; then \ - read -p "This requires sudo privileges. Proceed? [y/N]: " confirm_sudo; \ - fi; \ - if [ "$$confirm_sudo" = "y" ] || [ "$$confirm_sudo" = "Y" ]; then \ - sudo apt-get install aspell aspell-en; \ - else \ - echo "Installation cancelled."; \ - fi \ - } - -sp-pa11y-install: - @type $(PA11Y) >/dev/null 2>&1 || { \ - echo "Installing \"pa11y\" from npm... \n"; \ - mkdir -p $(SPHINXDIR)/node_modules/ ; \ - npm install --prefix $(SPHINXDIR) pa11y; \ - } - -sp-install: $(VENVDIR) - -sp-run: sp-install - . $(VENV); $(VENVDIR)/bin/sphinx-autobuild -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) - -# Doesn't depend on $(BUILDDIR) to rebuild properly at every run. -sp-html: sp-install - . $(VENV); $(SPHINXBUILD) -W --keep-going -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) - -sp-epub: sp-install - . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) - -sp-serve: sp-html - cd "$(BUILDDIR)"; python3 -m http.server --bind 127.0.0.1 8000 - -sp-clean: sp-clean-doc - @test ! -e "$(VENVDIR)" -o -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" - rm -rf $(VENVDIR) - rm -rf $(SPHINXDIR)/node_modules/ - rm -rf $(SPHINXDIR)/styles - rm -rf $(SPHINXDIR)/vale.ini - -sp-clean-doc: - git clean -fx "$(BUILDDIR)" - rm -rf $(SPHINXDIR)/.doctrees - -sp-spellcheck: sp-spellcheck-install - . $(VENV) ; python3 -m pyspelling -c $(SPHINXDIR)/spellingcheck.yaml -j $(shell nproc) - -sp-spelling: sp-html sp-spellcheck - -sp-linkcheck: sp-install - . $(VENV) ; $(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) || { grep --color -F "[broken]" "$(BUILDDIR)/output.txt"; exit 1; } - exit 0 - -sp-woke: sp-woke-install - woke $(ALLFILES) --exit-1-on-failure \ - -c https://raw.githubusercontent.com/canonical/Inclusive-naming/main/config.yml - -sp-pa11y: sp-pa11y-install sp-html - find $(BUILDDIR) -name *.html -print0 | xargs -n 1 -0 $(PA11Y) - -sp-vale: sp-install - @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/vale || pip install vale - @. $(VENV); test -f $(SPHINXDIR)/vale.ini || python3 $(SPHINXDIR)/get_vale_conf.py - @. $(VENV); find $(SPHINXDIR)/venv/lib/python*/site-packages/vale/vale_bin -size 195c -exec vale --config "$(SPHINXDIR)/vale.ini" $(TARGET) > /dev/null \; - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - @cat $(SPHINXDIR)/.wordlist.txt $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt - @echo "" - @echo "Running Vale against $(TARGET). To change target set TARGET= with make command" - @echo "" - @. $(VENV); vale --config "$(SPHINXDIR)/vale.ini" --glob='*.{md,txt,rst}' $(TARGET) || true - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt && rm $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - -sp-pdf-prep: sp-install - @for packageName in $(REQPDFPACKS); do (dpkg-query -W -f='$${Status}' $$packageName 2>/dev/null | \ - grep -c "ok installed" >/dev/null && echo "Package $$packageName is installed") && continue || \ - (echo "\nPDF generation requires the installation of the following packages: $(REQPDFPACKS)" && \ - echo "" && echo "Run 'sudo make pdf-prep-force' to install these packages" && echo "" && echo \ - "Please be aware these packages will be installed to your system") && exit 1 ; done - -sp-pdf-prep-force: - apt-get update - apt-get upgrade -y - apt-get install --no-install-recommends -y $(REQPDFPACKS) \ - -sp-pdf: sp-pdf-prep - @. $(VENV); sphinx-build -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) - @rm ./$(BUILDDIR)/latex/front-page-light.pdf || true - @rm ./$(BUILDDIR)/latex/normal-page-footer.pdf || true - @find ./$(BUILDDIR)/latex -name "*.pdf" -exec mv -t ./$(BUILDDIR) {} + - @rm -r $(BUILDDIR)/latex - @echo "\nOutput can be found in ./$(BUILDDIR)\n" - -sp-allmetrics: sp-html - @echo "Recording documentation metrics..." - @echo "Checking for existence of vale..." - . $(VENV) - @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/vale || pip install vale - @. $(VENV); test -f $(SPHINXDIR)/vale.ini || python3 $(SPHINXDIR)/get_vale_conf.py - @. $(VENV); find $(SPHINXDIR)/venv/lib/python*/site-packages/vale/vale_bin -size 195c -exec vale --config "$(SPHINXDIR)/vale.ini" $(TARGET) > /dev/null \; - @eval '$(METRICSDIR)/source_metrics.sh $(PWD)' - @eval '$(METRICSDIR)/build_metrics.sh $(PWD) $(METRICSDIR)' - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile.sp - . $(VENV); $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py index cf96c08..1d93b77 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -import ast import datetime import os import yaml @@ -61,7 +60,7 @@ # -H 'Accept: application/vnd.github.v3.raw' \ # https://api.github.com/repos/canonical/ | jq '.created_at' -copyright = "%s AGPL-3.0, %s" % (datetime.date.today().year, author) +copyright = "%s CC-BY-SA, %s" % (datetime.date.today().year, author) # Documentation website URL @@ -71,7 +70,7 @@ # NOTE: The Open Graph Protocol (OGP) enhances page display in a social graph # and is used by social media platforms; see https://ogp.me/ -ogp_site_url = "https://canonical-chisel.readthedocs-hosted.com/" +ogp_site_url = "https://documentation.ubuntu.com/chisel/" # Preview name of the documentation website @@ -85,7 +84,7 @@ # # TODO: To customise the preview image, update as needed. -ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" +ogp_image = "https://assets.ubuntu.com/v1/cc828679-docs_illustration.svg" # Product favicon; shown in bookmarks, browser tabs, etc. @@ -133,22 +132,45 @@ # # NOTE: If set, links for viewing the documentation source files # and creating GitHub issues are added at the bottom of each page. - "github_url": "https://github.com/canonical/chisel", + "github_url": "https://github.com/canonical/chisel-docs", # Docs branch in the repo; used in links for viewing the source files # # TODO: To customise the branch, uncomment and update as needed. - # 'github_version': 'main', + 'repo_default_branch': 'main', # Docs location in the repo; used in links for viewing the source files # + + # TODO: To customise the directory, uncomment and update as needed. "repo_folder": "/docs/", # TODO: To enable or disable the Previous / Next buttons at the bottom of pages # Valid options: none, prev, next, both - "sequential_nav": "both", + # "sequential_nav": "both", + # TODO: To enable listing contributors on individual pages, set to True + "display_contributors": False, + # Required for feedback button - "github_issues": "enabled", + 'github_issues': 'enabled', } +html_extra_path = [] + +# Allow opt-in build of the OpenAPI "Hello" example so docs stay clean by default. +if os.getenv("OPENAPI", ""): + tags.add("openapi") + html_extra_path.append("how-to/assets/openapi.yaml") + +# TODO: To enable the edit button on pages, uncomment and change the link to a +# public repository on GitHub or Launchpad. Any of the following link domains +# are accepted: +# - https://github.com/example-org/example" +# - https://launchpad.net/example +# - https://git.launchpad.net/example +# +# html_theme_options = { +# 'source_edit_link': 'https://github.com/canonical/sphinx-docs-starter-pack', +# } + # Project slug; see https://meta.discourse.org/t/what-is-category-slug/87897 # # TODO: If your documentation is hosted on https://docs.ubuntu.com/, @@ -156,11 +178,44 @@ slug = "chisel" +####################### +# Sitemap configuration: https://sphinx-sitemap.readthedocs.io/ +####################### + +# Use RTD canonical URL to ensure duplicate pages have a specific canonical URL + +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") + +# URL scheme. Add language and version scheme elements. +# When configured with RTD variables, check for RTD environment so manual runs succeed: + +if 'READTHEDOCS_VERSION' in os.environ: + version = os.environ["READTHEDOCS_VERSION"] + sitemap_url_scheme = '{version}{link}' +else: + sitemap_url_scheme = 'MANUAL/{link}' + +# Include `lastmod` dates in the sitemap: + +sitemap_show_lastmod = True + +# Exclude generated pages from the sitemap: +sitemap_excludes = [ + '404/', + 'genindex/', + 'search/', +] + +# TODO: Add more pages to sitemap_excludes if needed. Wildcards are supported. +# For example, to exclude module pages generated by autodoc, add '_modules/*'. + +####################### # Template and asset locations +####################### -html_static_path = [".sphinx/_static"] -templates_path = [".sphinx/_templates"] +# html_static_path = ["_static"] +# templates_path = ["_templates"] ############# @@ -187,13 +242,18 @@ # # TODO: Remove or adjust the ACME entry after you update the contributing guide -linkcheck_ignore = ["http://127.0.0.1:8000"] - +linkcheck_ignore = [ + "http://127.0.0.1:8000", + "https://www.gnu.org/*", +] # A regex list of URLs where anchors are ignored by 'make linkcheck' linkcheck_anchors_ignore_for_url = [r"https://github\.com/.*"] +# give linkcheck multiple tries on failure +# linkcheck_timeout = 30 +linkcheck_retries = 3 ######################## # Configuration extras # @@ -214,27 +274,29 @@ # https://www.sphinx-doc.org/en/master/usage/extensions/index.html # NOTE: The canonical_sphinx extension is required for the starter pack. -# It automatically enables the following extensions: -# - custom-rst-roles -# - myst_parser -# - notfound.extension -# - related-links -# - sphinx_copybutton -# - sphinx_design -# - sphinx_reredirects -# - sphinx_tabs.tabs -# - sphinxcontrib.jquery -# - sphinxext.opengraph -# - terminal-output -# - youtube-links extensions = [ "canonical_sphinx", + "notfound.extension", + "sphinx_design", + "sphinx_reredirects", + "sphinx_tabs.tabs", + "sphinxcontrib.jquery", + "sphinxext.opengraph", + "sphinx_config_options", + "sphinx_contributor_listing", + "sphinx_filtered_toctree", + "sphinx_related_links", + "sphinx_roles", + "sphinx_terminal", + "sphinx_ubuntu_images", + "sphinx_youtube_links", "sphinxcontrib.cairosvgconverter", "sphinx_last_updated_by_git", + "sphinx.ext.intersphinx", + "sphinx_sitemap", ] - # Excludes files or directories from processing exclude_patterns = [ @@ -243,32 +305,20 @@ # Adds custom CSS files, located under 'html_static_path' -html_css_files = [ - "css/pdf.css", -] +# html_css_files = [] # Adds custom JavaScript files, located under 'html_static_path' -html_js_files = [ - "js/checkbox.js", -] +# html_js_files = [] # Specifies a reST snippet to be appended to each .rst file -if os.path.exists("./reuse/links.txt"): - rst_epilog = """ - .. include:: /reuse/links.txt - """ - -# To reuse sentences or paragraphs that have little markup and special -# formatting, use substitutions. -# https://canonical-documentation-with-sphinx-and-readthedocscom.readthedocs-hosted.com/style-guide-myst/#substitution - -if os.path.exists("./reuse/substitutions.yaml"): - with open("./reuse/substitutions.yaml", "r") as fd: - myst_substitutions = yaml.safe_load(fd.read()) +rst_epilog = """ +.. include:: /reuse/links.txt +.. include:: /reuse/substitutions.txt +""" # Feedback button at the top; enabled by default # @@ -279,13 +329,15 @@ # Your manpage URL # -# TODO: To enable manpage links, uncomment and update as needed. +# TODO: To enable manpage links, uncomment and replace {codename} with required +# release, preferably an LTS release (e.g. noble). Do *not* substitute +# {section} or {page}; these will be replaced by sphinx at build time # # NOTE: If set, adding ':manpage:' to an .rst file # adds a link to the corresponding man section at the bottom of the page. -# manpages_url = f'https://manpages.ubuntu.com/manpages/{codename}/en/' + \ -# f'man{section}/{page}.{section}.html' +# manpages_url = 'https://manpages.ubuntu.com/manpages/{codename}/en/' + \ +# 'man{section}/{page}.{section}.html' # Specifies a reST snippet to be prepended to each .rst file @@ -304,27 +356,12 @@ if "discourse_prefix" not in html_context and "discourse" in html_context: html_context["discourse_prefix"] = html_context["discourse"] + "/t/" -##################### -# PDF configuration # -##################### - -latex_additional_files = [ - "./.sphinx/fonts/Ubuntu-B.ttf", - "./.sphinx/fonts/Ubuntu-R.ttf", - "./.sphinx/fonts/Ubuntu-RI.ttf", - "./.sphinx/fonts/UbuntuMono-R.ttf", - "./.sphinx/fonts/UbuntuMono-RI.ttf", - "./.sphinx/fonts/UbuntuMono-B.ttf", - "./.sphinx/images/Canonical-logo-4x.png", - "./.sphinx/images/front-page-light.pdf", - "./.sphinx/images/normal-page-footer.pdf", -] +# Workaround for substitutions.yaml -latex_engine = "xelatex" -latex_show_pagerefs = True -latex_show_urls = "footnote" +if os.path.exists('./reuse/substitutions.yaml'): + with open('./reuse/substitutions.yaml', 'r') as fd: + myst_substitutions = yaml.safe_load(fd.read()) -with open(".sphinx/latex_elements_template.txt", "rt") as file: - latex_config = file.read() +# Add configuration for intersphinx mapping -latex_elements = ast.literal_eval(latex_config.replace("$PROJECT", project)) +intersphinx_mapping = {} diff --git a/docs/how-to/index.md b/docs/how-to/index.md index 1639dd1..b6e59dc 100644 --- a/docs/how-to/index.md +++ b/docs/how-to/index.md @@ -40,7 +40,6 @@ with Ubuntu Pro. install-pro-package-slices ``` - ## Creating a slice definition Creating slice definitions can be simple and fun. Make sure to follow the best diff --git a/docs/how-to/install-chisel.md b/docs/how-to/install-chisel.md index 6c1c961..72f4e65 100644 --- a/docs/how-to/install-chisel.md +++ b/docs/how-to/install-chisel.md @@ -7,7 +7,6 @@ methods: - {ref}`install_chisel_source` - {ref}`install_chisel_snap` - (install_chisel_binary)= ## Install the binary @@ -47,6 +46,7 @@ the latest Chisel binary: ```sh sudo mv chisel /usr/local/bin/ ``` + (install_chisel_source)= @@ -67,7 +67,6 @@ Alternatively, you can install the latest version of Chisel from source: go install github.com/canonical/chisel/cmd/chisel@latest ``` - (install_chisel_snap)= ## Install Snap @@ -85,7 +84,6 @@ directory, i.e. the `--root` option of the {ref}`cut_command_reference` must poi inside `$HOME`. ``` - ## Verify installation @@ -100,7 +98,7 @@ chisel This should produce output similar to the following: ```{terminal} -:input: chisel +chisel Chisel can slice a Linux distribution using a release database and construct a new filesystem using the finely defined parts. diff --git a/docs/how-to/install-pro-package-slices.md b/docs/how-to/install-pro-package-slices.md index b3adb5a..3e2619b 100644 --- a/docs/how-to/install-pro-package-slices.md +++ b/docs/how-to/install-pro-package-slices.md @@ -148,7 +148,7 @@ machine esm.ubuntu.com/infra/ubuntu/ login bearer password Finally, run Chisel to install the required packages. ```{terminal} -:input: chisel cut --release ubuntu-20.04 --root out/ openssl_bins +chisel cut --release ubuntu-20.04 --root out/ openssl_bins 2025/02/11 15:28:20 Consulting release repository... 2025/02/11 15:28:22 Fetching current ubuntu-20.04 release... diff --git a/docs/how-to/slice-a-package.md b/docs/how-to/slice-a-package.md index fb3b0bd..093239f 100644 --- a/docs/how-to/slice-a-package.md +++ b/docs/how-to/slice-a-package.md @@ -38,7 +38,8 @@ indicated by the package. Example: vim-tiny pkg dependencies ```{terminal} - :input: apt depends vim-tiny + apt depends vim-tiny + vim-tiny Depends: vim-common (= 2:9.1.0016-1ubuntu7.8) Depends: libacl1 (>= 2.2.23) @@ -66,7 +67,7 @@ indicated by the package. Example: vim-tiny contents in Ubuntu 24.04, for amd64 ```{terminal} - :input: dpkg -c vim-tiny_2%3a9.1.0016-1ubuntu7.8_amd64.deb + dpkg -c vim-tiny_2%3a9.1.0016-1ubuntu7.8_amd64.deb drwxr-xr-x root/root 0 2025-04-01 20:12 ./ drwxr-xr-x root/root 0 2025-04-01 20:12 ./etc/ @@ -120,7 +121,8 @@ indicated by the package. Example: vim-tiny conffiles ```{terminal} - :input: cat DEBIAN/conffiles + cat DEBIAN/conffiles + /etc/vim/vimrc.tiny ``` @@ -383,7 +385,7 @@ There are **two schools of thought** when designing slices: Let's closely look at the `/usr/bin/vim.tiny` file. Let's use the `file` command to determine the type. ```{terminal} - :input: file /usr/bin/vim.tiny + file /usr/bin/vim.tiny /usr/bin/vim.tiny: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=244c06f7943459e771bbf3279ef507ad64f477b5, for GNU/Linux 3.2.0, stripped ``` @@ -393,7 +395,8 @@ There are **two schools of thought** when designing slices: libraries it depends on. ```{terminal} - :input: ldd /usr/bin/vim.tiny + ldd /usr/bin/vim.tiny + linux-vdso.so.1 (0x00007ffcdfecd000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x0000744edc6ac000) libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x0000744edc678000) @@ -562,7 +565,8 @@ specific function. Examples: Test the `bins` binary: ```{terminal} - :input: sudo chroot rootfs/ vim.tiny --version + sudo chroot rootfs/ vim.tiny --version + VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Apr 01 2025 15:29:41) Included patches: 1-16, 647-648, 678, 697, 689, 17-496, 707 Modified by @@ -602,7 +606,7 @@ specific function. Examples: Run the test with `spread`: ```{terminal} - :input: spread lxd:tests/spread/integration/vim-tiny + spread lxd:tests/spread/integration/vim-tiny ... 2025-04-14 18:29:40 Preparing lxd:ubuntu-noble:tests/spread/integration/vim-tiny (lxd:ubuntu-noble)... diff --git a/docs/how-to/use-chisel-in-dockerfile.md b/docs/how-to/use-chisel-in-dockerfile.md index 9b5691f..fb4595f 100644 --- a/docs/how-to/use-chisel-in-dockerfile.md +++ b/docs/how-to/use-chisel-in-dockerfile.md @@ -4,7 +4,6 @@ Chiseled file systems are ideal for creating minimal and distroless-like container images. This guide shows how to use Chisel in a Dockerfile to create a chiseled Docker image. - ## Design the image Let's set some goals for our chiseled image. Consider a Python 3 image, which @@ -26,12 +25,10 @@ Finally, we will copy the staging area's root file system to the `/` directory in the final stage. The final stage's base image will be [`scratch`]. Thus, the image only contains the root file system installed by Chisel and nothing else. - ## Write the Dockerfile Create a `Dockerfile` and open it with your favorite text editor. - ## Install Chisel and dependencies To make building easier and configurable, let's first define some variables that @@ -70,7 +67,6 @@ ADD "https://github.com/canonical/chisel/releases/download/${CHISEL_VERSION}/chi RUN tar -xvf chisel.tar.gz -C /usr/bin/ ``` - ## Prepare the chiseled root file system Now that we have Chisel installed in the `builder` stage, we can install the @@ -103,7 +99,6 @@ RUN cp /etc/passwd /etc/group /staging-rootfs/etc \ && install -o ubuntu -g ubuntu -d /staging-rootfs/home/ubuntu ``` - ### Copy the root file system to the final image Finally, we will initialize a new stage where we will copy the prepared root @@ -115,7 +110,6 @@ FROM scratch COPY --from=builder /staging-rootfs / ``` - ### Set user and working directory Now we will set the `USER` to `ubuntu` and the `WORKDIR` to `/home/ubuntu`. @@ -125,7 +119,6 @@ USER ubuntu WORKDIR /home/ubuntu ``` - ### Set the entrypoint All that remains is to set the entrypoint to `python3`. @@ -134,7 +127,6 @@ All that remains is to set the entrypoint to `python3`. ENTRYPOINT ["python3"] ``` - ## Build and test the image Let's copy all the code-blocks above and save it to `Dockerfile`. @@ -188,7 +180,7 @@ docker build -t python:3-chiseled . Once it's built, run the following command to check if the interpreter works. ```{terminal} -:input: docker run -it python:3-chiseled +docker run -it python:3-chiseled Python 3.12.3 (main, Feb 4 2025, 14:48:35) [GCC 13.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. @@ -216,7 +208,7 @@ print(x) Run the following command to run the script in our container image. ```{terminal} -:input: docker run -v $PWD/src:/src:ro python:3-chiseled /src/app.py +docker run -v $PWD/src:/src:ro python:3-chiseled /src/app.py 2025-03-11 06:36:50.717280 ``` diff --git a/docs/reference/cmd/cut.md b/docs/reference/cmd/cut.md index 48e2f47..1b868bf 100644 --- a/docs/reference/cmd/cut.md +++ b/docs/reference/cmd/cut.md @@ -26,7 +26,7 @@ we can run the following: ```{terminal} -:input: chisel cut --release ubuntu-24.04 --root rootfs/ hello_bins +chisel cut --release ubuntu-24.04 --root rootfs/ hello_bins 2024/11/26 12:21:35 Consulting release repository... 2024/11/26 12:21:37 Cached ubuntu-24.04 release is still up-to-date. diff --git a/docs/reference/cmd/find.md b/docs/reference/cmd/find.md index 9b0e041..7199cc8 100644 --- a/docs/reference/cmd/find.md +++ b/docs/reference/cmd/find.md @@ -16,7 +16,7 @@ current host, unless the `--release` option is used. Run the following command to search python3.10 slices in `ubuntu-22.04` release: ```{terminal} -:input: chisel find --release ubuntu-22.04 python3.10 +chisel find --release ubuntu-22.04 python3.10 2024/11/26 13:11:08 Consulting release repository... 2024/11/26 13:11:10 Fetching current ubuntu-22.04 release... @@ -40,7 +40,7 @@ because the find command finds partially-matched slices. The first three lines are logs, which you can ignore with: ```{terminal} -:input: chisel find --release ubuntu-22.04 python3.10 2>/dev/null +chisel find --release ubuntu-22.04 python3.10 2>/dev/null Slice Summary python3.10_copyright - diff --git a/docs/reference/cmd/help.md b/docs/reference/cmd/help.md index be8812b..41ff997 100644 --- a/docs/reference/cmd/help.md +++ b/docs/reference/cmd/help.md @@ -2,12 +2,12 @@ The **help** command displays information about commands. - ## Example ```{terminal} :scroll: -:input: chisel help --all + +chisel help --all Chisel can slice a Linux distribution using a release database and construct a new filesystem using the finely defined parts. diff --git a/docs/reference/cmd/info.md b/docs/reference/cmd/info.md index 5d21e26..2230c93 100644 --- a/docs/reference/cmd/info.md +++ b/docs/reference/cmd/info.md @@ -14,7 +14,6 @@ the output is a list of YAML documents separated by a `---` line. Slice definitions are shown according to their definition in the selected release. For example, globs are not expanded. - ## Options - `--release` is a {{chisel_releases_repo}} branch or local directory (e.g. ubuntu-22.04). @@ -24,7 +23,7 @@ the selected release. For example, globs are not expanded. The following illustrates using the `info` command to inspect multiple slices: ```{terminal} -:input: chisel info hello libgcc-s1_libs 2>logs +chisel info hello libgcc-s1_libs 2>logs package: hello archive: ubuntu diff --git a/docs/reference/cmd/version.md b/docs/reference/cmd/version.md index eefa0cc..bcfd847 100644 --- a/docs/reference/cmd/version.md +++ b/docs/reference/cmd/version.md @@ -2,11 +2,10 @@ The **version** command displays the Chisel version and exits. - ## Example ```{terminal} -:input: chisel version +chisel version v1.0.0 ``` diff --git a/docs/reference/security.md b/docs/reference/security.md index cf5361d..d7fb59a 100644 --- a/docs/reference/security.md +++ b/docs/reference/security.md @@ -12,14 +12,14 @@ Chisel is written in Go. ## Detailed Process -1. Chisel downloads and parses the YAMLs from +1. Chisel downloads and parses the YAML files from [chisel-releases](https://github.com/canonical/chisel-releases) repo[^1]. The Go package [net/http](https://pkg.go.dev/net/http) is used and a tarball is downloaded over HTTPS. Checksum of the tarball is not checked after downloading. Chisel maintains a cache of these files[^2]. When making new requests to - download a release, Chisel reads the Etag from cache and checks whether the - cache is still valid. If it is valid, the cached release YAMLs are used. + download a release, Chisel reads the entity tag from cache and checks whether the + cache is still valid. If it is valid, the cached release YAML files are used. 1. Chisel downloads a few *InRelease* files from the [Ubuntu Archive](http://archive.ubuntu.com) but these files are never cached. The InRelease files are signed by GPG, and Chisel verifies[^3] the integrity using the