OILS / build / wiki.ysh View on Github | oils.pub

205 lines, 45 significant
1#!/usr/bin/env ysh
2#
3# Script to build and deploy the wiki to pages.oils.pub
4# (oils-for-unix.github.io). This is used for the dev guide.
5#
6# # Usage:
7#
8# build/wiki.ysh render
9# build/wiki.ysh build-search-index
10# build/wiki.ysh local-serve
11# build/wiki.ysh commit-push
12#
13# # Action: render
14#
15# This will clone the oils-for-unix/oils wiki, and render all of the markdown
16# files using doc tools. The docs are saved to _tmp/wiki/out.
17#
18# # Action: build-search-index
19#
20# This will download the pagefind tool, and run it over the wiki built in
21# build-search-index. This is used for our static wiki-wide search.
22#
23# # Action: local-serve
24#
25# Run a server with the current build locally. This will also copy the contents
26# of web/ into the build folder so that CSS is present in the preview.
27#
28# # Action: commit-push
29#
30# This will get the latest oils-for-unix/oils-for-unix.github.io, copy the wiki
31# build into the clone and then commit + push it.
32#
33# This requires an environment variable to be set (usually in GitHub Actions
34# secrets): `OILS_PAGES_GITHUB_TOKEN`. This is a PAT with `content: write`
35# permissions to the oils-for-unix.github.io repo.
36
37const WIKI_OUT_DIR = '_tmp/wiki/out'
38const WIKI_DIR = '_tmp/wiki/git'
39const PAGES_DIR = '_tmp/wiki/oils-for-unix.github.io'
40
41proc pull-latest(dir, repo) {
42 ## Pull the latest commit from $repo to $dir. Will clone if necessary
43
44 if test -d $dir {
45 echo "$repo already cloned to $dir, pulling latest"
46
47 cd $dir {
48 git pull
49 }
50
51 return
52 }
53
54 echo "Cloning $repo to $dir"
55 mkdir -p $dir
56 git clone $repo $dir
57}
58
59
60func slugify(s) {
61 return (s.replace(" ", "-").replace(",", " "))
62}
63
64proc pre-render-wikilinks() {
65 ## GitHub wikis have a unique [[link syntax]] which references topic within
66 ## the wiki.
67 ##
68 ## This function converts that syntax to the traditional
69 ## [link syntax](./link-syntax.html) which will render correctly once fed to
70 ## doctools.
71 for line in (io.stdin) {
72 var mdlink = line.replace(/ '[[' <capture ![']']* as link> ']]' /,
73 ^"[$link]($[slugify(link)].html)")
74 write -- $[mdlink]
75 }
76}
77
78proc render-one(path) {
79 mkdir -p $WIKI_OUT_DIR
80
81 var name = path.replace(/ %start dot* '/' <capture dot* as name> '.md' /, ^"$[slugify(name)]")
82 var title = name.replace('-', ' ')
83 var dest = "$WIKI_OUT_DIR/$name.html"
84
85 fopen >$dest {
86 echo """
87 <!DOCTYPE html>
88 <html>
89 <head>
90 <meta name="viewport" content="width=device-width, initial-scale=1">
91 <title>$title</title>
92
93 <link rel="stylesheet" type="text/css" href="../web/base.css" />
94
95 <style>
96 #search > div {
97 margin-top: 8px;
98 width: 100%;
99 }
100
101 #search input[type=text], #search button {
102 padding: 4px 8px;
103
104 background-color: #EEE;
105 color: #444;
106 }
107
108 /* We cannot control the search UI, so manually calculate widths for sizing */
109 #search input {
110 padding-right: 4px !important; /* Pagefind likes to add a large padding here, disable it */
111
112 width: calc(100%
113 - max(10%, 50px) /* button width */
114 - 20px /* margins */);
115
116 border: 1px solid #EEE;
117 }
118
119 #search button {
120 width: calc(max(10%, 50px));
121
122 border: 1px solid #AAA;
123 }
124
125 /* This is the load more results button */
126 #search .pagefind-ui__drawer button {
127 margin-left: 0;
128 margin-right: 0;
129 width: 100%;
130 }
131 </style>
132 </head>
133 <body class="width40">
134
135 <div id="search"></div>
136 <hr>
137 """
138
139 pre-render-wikilinks <$path | cmark
140
141 echo """
142 <script src="./pagefind/pagefind-ui.js"></script>
143 <script>
144 window.addEventListener('DOMContentLoaded', (event) => {
145 new PagefindUI({ element: "#search", showSubResults: true });
146 });
147 </script>
148 </body>
149 </html>
150 """
151 }
152}
153
154proc build-search-index() {
155 python3 -m pip install 'pagefind[extended]'
156 python3 -m pagefind --site $WIKI_OUT_DIR
157}
158
159
160proc render() {
161 ## Pull the latest version of the wiki and render it
162
163 pull-latest $WIKI_DIR https://github.com/oils-for-unix/oils.wiki.git
164 find $WIKI_DIR -name '*.md' -print0 | xargs -I {} -0 -- $0 render-one {}
165}
166
167
168proc local-preview() {
169 cp -r web $WIKI_OUT_DIR/..
170
171 python3 -m http.server -d $WIKI_OUT_DIR/..
172}
173
174
175proc commit-push() {
176 ## Commit and push the most recent build to oils-for-unix.github.io
177
178 var PAT = ENV.OILS_PAGES_GITHUB_TOKEN
179 pull-latest $PAGES_DIR "https://x-access-token:$PAT@github.com/oils-for-unix/oils-for-unix.github.io.git"
180
181 # Stash and pending changes (there should be none)
182 cd $PAGES_DIR {
183 git add .
184 git stash
185 }
186
187 # Update the wiki
188 rm -rf $PAGES_DIR/wiki
189 cp -r $WIKI_OUT_DIR $PAGES_DIR/wiki
190
191 cd $PAGES_DIR {
192 git add wiki
193
194 if git diff --quiet --staged {
195 echo 'No changes, will not commit'
196 } else {
197 var date = $(date --rfc-email)
198 git commit -m "Bump wiki $date"
199 git push
200 }
201 }
202}
203
204
205runproc @ARGV