Compare commits

...

2 commits

Author SHA1 Message Date
f0cb191971 feat: update 2025-11-09 14:20:34 +01:00
665eabe250 feat: update tutorial 2025-11-08 10:37:28 +01:00
274 changed files with 466 additions and 605 deletions

162
build.py
View file

@ -5,6 +5,7 @@ from json import dump, loads
from pathlib import Path
from ruamel.yaml import YAML
from ansi2html import Ansi2HTMLConverter
from bs4 import BeautifulSoup
from rougail import Rougail
from rougail.config import get_rougail_config
@ -13,11 +14,12 @@ from rougail.user_data_yaml import RougailUserDataYaml
from rougail.output_doc import RougailOutputDoc
PREVIOUS = Path("previous.yml")
if __name__ == "__main__":
commit_id = sys.argv[1]
builder_dir = sys.argv[1]
previous = Path(builder_dir) / "previous.yml"
with Path("install.txt").open() as fh:
cmd = fh.read()
commit_id = sys.argv[2]
# rougailconfig = RougailConfig.copy()
rougailconfig = get_rougail_config(backward_compatibility=False, add_extra_options=False)
rougailconfig['main_structural_directories'] = ['firefox']
@ -39,10 +41,10 @@ if __name__ == "__main__":
has_mode = True
else:
has_mode = False
rougailconfig['step.output'] = 'doc'
rougail = Rougail(rougailconfig)
config = rougail.run()
# print(config.value.get())
rougailconfig['step.output'] = 'doc'
rougailconfig['doc.output_format'] = 'github'
rougailconfig['doc.title_level'] = 3
inventory = RougailOutputDoc(config, rougailconfig=rougailconfig.copy())
@ -57,70 +59,81 @@ if __name__ == "__main__":
doc = ''
yaml = YAML()
namespace = 'firefox'
file_found = False
if rougailconfig['main_namespace']:
all_dirs = [[rougailconfig['main_structural_directories']], [['foxyproxy']]]
dirname = "foxyproxy"
else:
all_dirs = [[rougailconfig['main_structural_directories']]]
dirname = "firefox"
doc += inv_formatter.title('Screenshot', 2) + '\n'
doc += f'<img src="{namespace}.png" width=50% height=50% alt="{namespace.capitalize()} Proxy setting"/>\n\n'
# with doc_file.open('r') as docfh:
# doc += docfh.read()
doc += '\n' + inv_formatter.title('Structure', 2) + '\n'
print(all_dirs)
for r in all_dirs:
for dirs in r:
for d in dirs:
print(d)
files = list(Path(d).iterdir())
files.sort()
for f in files:
namespace = f.parent.name
file_found = True
if f.name.endswith('.yml') or f.name.endswith('.yaml'):
doc += inv_formatter.title(str(f), 3)
doc += '\n```yml\n'
with f.open(encoding="utf8") as file_fh:
doc += file_fh.read()
doc += '\n```\n'
doc += '\n' + inv_formatter.title('Clone and install', 2) + '\n\n'
doc += "To test this tutorial, you need to download this repository and install Rougail:\n\n"
doc += f'```shell\n{cmd}```\n\n'
doc += "Then switch to the tutorial page:\n\n"
doc += f"```shell\ngit switch --detach {commit_id}\n```\n"
tree = Path('tree.html')
display_yml = None
if tree.is_file():
doc += '\n' + inv_formatter.title('Structure', 2) + '\n\n'
with tree.open() as fh:
soup = BeautifulSoup(fh.read(), features="lxml")
doc += str(soup.find('p')) + "\n\n"
for f in Path('.').iterdir():
if f.name.startswith('DISPLAY_'):
filename = f.name[9:]
display_yml = Path(dirname) / filename
break
else:
files = list(Path(dirname).iterdir())
files.sort()
for f in reversed(files):
if not f.name.endswith('.yml'):
continue
display_yml = f
break
if display_yml:
doc += f"Contents of the {str(display_yml)} file"
doc += '\n\n```yml\n'
with display_yml.open(encoding="utf8") as file_fh:
doc += file_fh.read()
doc += '\n```\n'
rougailconfig['step.output'] = 'doc'
rougailconfig["doc.title_level"] = 4
inv_doc = inventory.run()[1]
if file_found and inv_doc:
doc += inv_formatter.title('Generated documentation', 3)
CMD = f"foo@bar:~$ git switch --detach {commit_id}\n"
CMD += "foo@bar:~$ rougail -m firefox/ "
if has_namespace:
CMD += "-s Firefox "
if has_foxyproxy:
CMD += "-xn FoxyProxy -xd 0 foxyproxy/ "
if has_mode:
CMD += "--modes_level basic standard advanced "
cmd = CMD + "-o doc -do github"
doc += f'```console\n{cmd}\n```\n'
CMD = "rougail -m firefox/ "
if has_namespace:
CMD += "-s Firefox "
if has_foxyproxy:
CMD += "-xn FoxyProxy -xd 0 foxyproxy/ "
if has_mode:
CMD += "--modes_level basic standard advanced "
if inv_doc:
doc += inv_formatter.title("Let's generate the documentation", 3)
cmd = CMD + "-o doc"
doc += f'```shell\n{cmd}\n```\n'
doc += inv_doc
if PREVIOUS.is_file():
rougailconfig["doc.title_level"] = 5
if previous.is_file():
rougailconfig["doc.contents"] = ["changelog"]
rougailconfig["doc.previous_json_file"] = str(PREVIOUS)
rougailconfig["doc.previous_json_file"] = str(previous)
inv_doc = inventory.run()[1]
if file_found and inv_doc:
doc += inv_formatter.title('Changelog', 3)
cmd = CMD + "-o doc --doc.contents variables changelog -do github"
doc += f'```console\n{cmd}\n```\n'
doc += inv_doc
if inv_doc:
doc += inv_formatter.title("Let's generate the changelog", 3)
cmd = CMD + "-o doc --doc.contents changelog"
doc += f'```shell\n{cmd}\n```\n'
doc += inv_doc + "\n"
# save PREVIOUS
rougailconfig["doc.contents"] = ["variables"]
rougailconfig['doc.output_format'] = 'json'
data = inventory.run()[1]
if data:
with PREVIOUS.open('w') as fh:
with previous.open('w') as fh:
dump(loads(data), fh)
#
rougailconfig['step.output'] = 'console'
config = Path('config')
if config.is_dir():
doc += inv_formatter.title('User data', 2)
doc += inv_formatter.title('User datas', 2)
configs = list(config.iterdir())
configs.sort()
for idx, dirname in enumerate(configs):
@ -133,15 +146,7 @@ if __name__ == "__main__":
doc += '\n```yml\n'
with filename.open(encoding="utf8") as file_fh:
doc += file_fh.read()
doc += '\n```\n'
# with filename.open(encoding="utf8") as file_fh:
# objects = yaml.load(file_fh)
# doc += inv_formatter.yaml(objects)
#readme = dirname / 'README.md'
#if readme.is_file():
# doc += inv_formatter.title('Description', 4)
# with readme.open() as fh:
# doc += fh.read() + '\n\n'
doc += '```\n'
rougail = Rougail(rougailconfig)
tiramisu_config = rougail.run()
rougailconfig['step.user_data'] = ['yaml']
@ -157,26 +162,51 @@ if __name__ == "__main__":
console = export.run()[1]
conv = Ansi2HTMLConverter(inline=True)
doc += inv_formatter.title('Output', 4)
cmd = CMD + f"-u yaml -ff {filename}"
doc += f"```console\n{cmd}\n```\n"
cmd = CMD + f"-u yaml -yf {filename}"
with (dirname / "cmd_ro.txt").open("w") as fh:
fh.write(cmd)
doc += f"```shell\n{cmd}\n```\n"
conv_data = '<pre>' + conv.convert(console, full=False) + "</pre>\n"
doc += conv_data
with open(dirname / 'output_ro.html', 'w') as fh_output:
fh_output.write(conv_data)
if (config / 'read_write').is_file():
tiramisu_config.property.read_write
if (dirname / 'invalid').is_file():
errors2 = rougail.user_datas(ret, invalid_user_datas_error=True)
export = RougailOutputConsole(tiramisu_config,
rougailconfig=rougailconfig,
user_data_errors=data.errors,
user_data_warnings=data.warnings,
user_data_errors=errors2['errors'],
user_data_warnings=errors2['warnings'],
)
console = export.run()[1]
conv = Ansi2HTMLConverter(inline=True)
doc += inv_formatter.title('Output when invalid user datas is an error', 4)
cmd2 = cmd + " --cli.invalid_user_datas_error"
with (dirname / "cmd_invalid.txt").open("w") as fh:
fh.write(cmd2)
doc += f"```shell\n{cmd2}\n```\n"
conv_data = '<pre>' + conv.convert(console, full=False) + "</pre>\n"
doc += conv_data
with open(dirname / 'output_invalid.html', 'w') as fh_output:
fh_output.write(conv_data)
if (dirname / 'read_write').is_file():
trougailconfig = rougailconfig.copy()
trougailconfig["console.mandatory"] = False
tiramisu_config.property.read_write()
errors2 = rougail.user_datas(ret, invalid_user_datas_error=True)
export = RougailOutputConsole(tiramisu_config,
rougailconfig=trougailconfig,
user_data_errors=errors2['errors'],
user_data_warnings=errors2['warnings'],
)
console = export.run()[1]
conv = Ansi2HTMLConverter(inline=True)
doc += inv_formatter.title('Output in read write mode', 4)
cmd = cmd + " --cli.read_write"
doc += f"```console\n{cmd}\n```\n"
cmd2 = cmd + " --cli.read_write"
with (dirname / "cmd_rw.txt").open("w") as fh:
fh.write(cmd2)
doc += f"```shell\n{cmd2}\n```\n"
conv_data = '<pre>' + conv.convert(console, full=False) + "</pre>\n"
doc += '<pre>' + conv_data + "</pre>\n"
doc += conv_data
with open(dirname / 'output_rw.html', 'w') as fh_output:
fh_output.write(conv_data)
#

View file

@ -11,7 +11,7 @@ if [ -d $DEST ]; then
exit 1
fi
export LC_ALL=C
export LC_ALL=C.UTF-8
BUILDER="$(pwd)"
mkdir -p $DEST/firefox
@ -22,12 +22,15 @@ touch summary_total.md
cd "$DEST"
DEST="$(pwd)"
TUTO_ROOT=https://forge.cloud.silique.fr/stove/rougail-tutorials/src/commit
cp "$BUILDER"/firefox.png .
cp "$BUILDER"/foxyproxy.png .
cp "$BUILDER"/summary.md .
cp "$BUILDER"/install.txt .
touch README.md
"$BUILDER"/build.py "$VERSION"
"$BUILDER"/build.py "$BUILDER" "$VERSION"
rm -rf summary.md
rm -rf summary_total.md
rm -rf jinja_caches
@ -38,11 +41,11 @@ git commit -am"$(cat $BUILDER/TITLE)"
cd - > /dev/null
for i in $(ls -d "examples"/* | sort); do
num=$(echo $(basename "$i"))
echo "$num"
commit_id="v${VERSION}_$num"
summary="[tutorial $(basename $i)] $(head -n 1 $i/README.md)"
echo "- [$summary](https://forge.cloud.silique.fr/stove/rougail-tutorials/src/commit/$commit_id/README.md) ([diff](https://forge.cloud.silique.fr/stove/rougail-tutorials/compare/${commit_id}~1..$commit_id))" >> summary_total.md
num=$(echo $(basename "$i"))
echo "$num"
commit_id="v${VERSION}_$num"
summary="[tutorial $commit_id] $(head -n 1 $i/README.md)"
echo "- [$summary](https://forge.cloud.silique.fr/stove/rougail-tutorials/src/commit/$commit_id/README.md) ([diff](https://forge.cloud.silique.fr/stove/rougail-tutorials/compare/${commit_id}~1..$commit_id))" >> summary_total.md
done
for i in $(ls -d "examples"/* | sort); do
@ -53,17 +56,20 @@ for i in $(ls -d "examples"/* | sort); do
echo " - $(head -n 1 $i/SUBTITLE.md)" >> summary.md
fi
if [ -f "$i/README.md" ]; then
rm -rf "$DEST/config"
rm -rf "$DEST/config" "$DEST/tree.html"
num=$(echo $(basename "$i"))
echo "$num"
commit_id="v${VERSION}_$num"
summary="[tutorial $(basename $i)] $(head -n 1 $i/README.md)"
summary="[tutorial $commit_id)] $(head -n 1 $i/README.md)"
diff_url="https://forge.cloud.silique.fr/stove/rougail-tutorials/compare/${commit_id}~1..$commit_id"
echo " - [$summary](https://forge.cloud.silique.fr/stove/rougail-tutorials/src/commit/$commit_id/README.md) ([diff]($diff_url))" >> summary.md
cp "summary_total.md" "$DEST"
BEFORE=$PWD
cd "$i/structural_files"
echo "====================="
if [ -d firefox ]; then
for j in $(ls firefox/*.yml 2>/dev/null); do
echo "++++ $j"
cp "$j" "$DEST/$j"
done
fi
@ -73,14 +79,18 @@ for i in $(ls -d "examples"/* | sort); do
cp "$j" "$DEST/$j"
done
fi
cp "DISPLAY_*" "$DEST/" 2> /dev/null || true
cd $DEST
tree -H $TUTO_ROOT/$commit_id/ -P "*.yml" > tree.html
cd - > /dev/null
cp -f ../README.md "$DEST"
if [ -d ../config ]; then
cp -aL ../config "$DEST"
fi
msg="[tutorial $(basename $i)] $(cat ../README.md)"
msg="[tutorial $commit_id] $(cat ../README.md)"
[ -e ../firefox.png ] && cp ../firefox.png "$DEST"
[ -e ../foxyproxy.png ] && cp ../foxyproxy.png "$DEST"
cd - > /dev/null
cd $BEFORE
cd "$DEST"
#
before=$(grep "commit/$commit_id/README.md" summary_total.md -B1 | wc -l)
@ -100,8 +110,8 @@ for i in $(ls -d "examples"/* | sort); do
if [ -f config/mode ]; then
mv config/mode mode
fi
"$BUILDER"/build.py "$commit_id"
rm -rf config/*/README.md config/read_write config/namespace
"$BUILDER"/build.py "$BUILDER" "$commit_id"
rm -rf config/*/README.md config/*/read_write config/namespace config/*/invalid DISPLAY_*
rm -rf jinja_caches summary.md summary_before.md summary_after.md summary_total.md
if [ -f mode ]; then
MODE=1
@ -109,7 +119,7 @@ for i in $(ls -d "examples"/* | sort); do
else
MODE=0
fi
git add *.png README.md
git add *.png README.md install.txt tree.html
if [ -d config ]; then
git add config
else
@ -145,11 +155,11 @@ This is what the page looks like:
" > README.md
echo '# Installation
```bash
# python -m venv rougail
# . rougail/bin/activate
# pip install rougail-cli rougail-output-exporter rougail-output-doc rougail-user-data-file
```
To test this tutorial, you need to download this repository and install Rougail:
```bash' >> README.md
cat install.txt >> README.md
echo '```
' >> README.md
echo "# Summary
@ -159,7 +169,7 @@ cp "$BUILDER"/firefox.png .
cp "$BUILDER"/foxyproxy.png .
cat "$BUILDER"/summary.md >> README.md
echo >> README.md
rm -rf firefox foxyproxy mode
rm -rf firefox foxyproxy mode install.txt tree.html
git add .
git commit -am"Summary"
#

View file

@ -1 +1 @@
A structured file with format version
An empty structured file with format version

View file

@ -1 +1 @@
Structural file
Making a structure file

1
examples/001/README.md Normal file
View file

@ -0,0 +1 @@
A first variable with only a name

1
examples/001/SUBTITLE.md Normal file
View file

@ -0,0 +1 @@
Let's create our first "variable"

View file

@ -0,0 +1 @@
The user data file is empty. So it's only default value that will be used.

BIN
examples/001/firefox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

9
examples/002/README.md Normal file
View file

@ -0,0 +1,9 @@
Describe the variable
We can add a description to this first variable.
This information is useful for:
- documentation
- error message
- help user to known which value to set to this variable (for example with [the user data plugin Questionary](https://forge.cloud.silique.fr/stove/rougail-user-data-questionary)).

View file

@ -0,0 +1 @@
The user data file is empty. So it's only default value that will be used.

View file

@ -0,0 +1,2 @@
---
proxy_mode: No proxy

7
examples/003/README.md Normal file
View file

@ -0,0 +1,7 @@
Set a default value
Now we can define the default value of this variable.
If the user doesn't touch this variable's value, the value is "No proxy"
As user intervention is no more required, so the variable change it's default mode too (from "basic" to "standard").

View file

@ -0,0 +1 @@
The user data file is empty. So it's only default value that will be used.

View file

@ -0,0 +1,2 @@
---
proxy_mode: No proxy

View file

@ -0,0 +1 @@
"foo" should be an invalid value for this variable.

View file

@ -0,0 +1,2 @@
---
proxy_mode: foo

View file

@ -1,4 +1,4 @@
A variable with type "choice"
Limits the possible values for the variable
"Foo" should not be an option to the "proxy_mode" variable.

View file

@ -0,0 +1 @@
The user data file is empty. So it's only default value that will be used.

View file

@ -0,0 +1,2 @@
---
proxy_mode: No proxy

View file

@ -0,0 +1 @@
"foo" should be an invalid value for this variable.

View file

@ -0,0 +1,2 @@
---
proxy_mode: foo

View file

@ -1 +1 @@
A first variable with only a name
Creating a new family

View file

@ -1 +1 @@
Variable: choice the proxy mode
Group variables inside "families"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

View file

@ -0,0 +1,8 @@
%YAML 1.2
---
version: 1.1
manual:
description: Manual proxy configuration
type: family
...

View file

@ -1,9 +1,8 @@
The variable description
Or a sub family
We can add a description to this first variable.
Inside a family, we can have variables or families.
This information is useful for:
The "type" for family "manual" became unecessary because container an other family, so it's not a variable.
The description can now be has family comment.
- documentation
- error message
- help user to known which value to set to this variable (for example with [the user data plugin Questionary](https://forge.cloud.silique.fr/stove/rougail-user-data-questionary)).
In disabled attribute, it's better tu use relative path (we will see the reason in an other slide).

View file

@ -1 +0,0 @@
../010/config

View file

@ -0,0 +1,10 @@
%YAML 1.2
---
version: 1.1
manual: # Manual proxy configuration
http_proxy:
description: HTTP Proxy
type: family
...

View file

@ -1,7 +1 @@
A default value
Now we can define the default value of this variable.
If the user doesn't touch this variable's value, the value is "No proxy"
As user intervention is no more required, so the variable change it's default mode too (from "basic" to "standard").
Putting a variable inside of a family or a sub family

View file

@ -1 +0,0 @@
../010/config

View file

@ -0,0 +1,4 @@
---
manual:
http_proxy:
address: example.net

View file

@ -0,0 +1,5 @@
---
manual:
http_proxy:
address: example.net
port: 3128

View file

@ -6,7 +6,5 @@ manual: # Manual proxy configuration
http_proxy: # HTTP Proxy
address:
description: HTTP address
type: domainname
address: # HTTP address
...

View file

@ -1 +0,0 @@
../010/config

View file

@ -1,15 +0,0 @@
%YAML 1.2
---
version: 1.1
proxy_mode:
description: Configure Proxy Access to the Internet
type: choice
choices:
- No proxy
- Auto-detect proxy settings for this network
- Use system proxy settings
- Manual proxy configuration
- Automatic proxy configuration URL
default: No proxy
...

View file

@ -1,3 +0,0 @@
Choice type is optional
The type is optional in choice type (if we have choices attributes, it's a choice option).

View file

@ -1 +0,0 @@
../010/config

View file

@ -1,14 +1 @@
A family
The "manual" mode structural descriptions are write in a new files to separate things. But Rougail will concatenate variables and families.
We create a family, which will contain other variables.
This family has:
- a description
- a type
As there is no variable inside this family, the type is mandatory. Without it, Rougail will create a variable.
In fact, this family will be deleted by Rougail too because it is empty.
A variable with type "domainname"

View file

@ -1 +0,0 @@
Family: proxy manual

1
examples/020/TITLE.md Normal file
View file

@ -0,0 +1 @@
Constrainte the value of a variable with it's type

View file

@ -0,0 +1,4 @@
---
manual:
http_proxy:
address: example.net

View file

@ -0,0 +1,4 @@
---
manual:
http_proxy:
address: 192.168.0.1

View file

@ -0,0 +1,4 @@
---
manual:
http_proxy:
address: not a valid domain name

View file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

View file

@ -2,7 +2,11 @@
---
version: 1.1
manual:
description: Manual proxy configuration
type: family
manual: # Manual proxy configuration
http_proxy: # HTTP Proxy
address:
description: HTTP address
type: domainname
...

View file

@ -1,8 +1 @@
A sub family
Inside a family, we can have variables or families.
The "type" for family "manual" became unecessary because container an other family, so it's not a variable.
The description can now be has family comment.
In disabled attribute, it's better tu use relative path (we will see the reason in an other slide).
A variable with type's parameters

1
examples/021/config Symbolic link
View file

@ -0,0 +1 @@
../020/config

View file

@ -4,7 +4,11 @@ version: 1.1
manual: # Manual proxy configuration
http_proxy:
description: HTTP Proxy
type: family
http_proxy: # HTTP Proxy
address:
description: HTTP address
type: domainname
params:
allow_ip: true
...

View file

@ -1 +1 @@
A variable inside sub family
A variable with type "port"

View file

@ -3,4 +3,4 @@ proxy_mode: Manual proxy configuration
manual:
http_proxy:
address: example.net
port: '3128'
port: 3128

View file

@ -0,0 +1,6 @@
---
proxy_mode: Manual proxy configuration
manual:
http_proxy:
address: example.net
port: 100000

View file

View file

@ -6,5 +6,14 @@ manual: # Manual proxy configuration
http_proxy: # HTTP Proxy
address: # HTTP address
address:
description: HTTP address
type: domainname
params:
allow_ip: true
port:
description: HTTP Port
type: port
default: 8080
...

View file

@ -1 +1 @@
A variable with type "domainname"
A variable with type "boolean"

View file

@ -1 +0,0 @@
Variable: type and type parameters

View file

@ -1 +0,0 @@
HTTP Manual mode

View file

@ -0,0 +1,4 @@
---
manual:
http_proxy:
address: example.net

View file

@ -1,2 +0,0 @@
---
proxy_mode: Manual proxy configuration

View file

@ -0,0 +1,5 @@
---
manual:
http_proxy:
address: example.net
use_for_https: false

View file

@ -1,2 +0,0 @@
If "use_for_https" is false, HTTPS variables are visible in read only mode and in read write mode.

View file

@ -1,9 +0,0 @@
---
proxy_mode: Manual proxy configuration
manual:
http_proxy:
address: http.proxy.net
port: '3128'
use_for_https: false
https_proxy:
address: https.proxy.net

View file

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View file

@ -1 +1 @@
A variable with type's parameters
Copy HTTP manual proxy to HTTPS manual proxy

View file

@ -1 +1 @@
../022/config
../020/config

View file

@ -1,14 +0,0 @@
%YAML 1.2
---
version: 1.1
manual: # Manual proxy configuration
http_proxy: # HTTP Proxy
address:
description: HTTP address
type: domainname
params:
allow_ip: true
...

View file

@ -1 +0,0 @@
A variable with type "port"

View file

@ -1 +0,0 @@
../022/config

View file

@ -1,19 +0,0 @@
%YAML 1.2
---
version: 1.1
manual: # Manual proxy configuration
http_proxy: # HTTP Proxy
address:
description: HTTP address
type: domainname
params:
allow_ip: true
port:
description: HTTP Port
type: port
default: 8080
...

View file

@ -1 +0,0 @@
A disabled family

View file

@ -1 +0,0 @@
Property: disabled

Some files were not shown because too many files have changed in this diff Show more