Zuletzt aktiv 1 month ago

Änderung 35614cc9c04baa9e1768a2a57b1145ecffd99dd7

assets-watcher.js Originalformat
1import chokidar from 'chokidar';
2import fs from 'fs'
3import fse from 'fs-extra';
4import child_process from 'child_process';
5
6// ====================================================================
7// |
8// ====================================================================
9function log(message) {
10 const options = {
11 encoding: "utf-8",
12 flag: "a+",
13 };
14 const datetime = new Date().toISOString()
15 message = `[${datetime}] ${message}\n`
16 fse.outputFileSync('/logs/builder/assets.log', message, options);
17 console.log(message)
18}
19
20// ====================================================================
21// |
22// ====================================================================
23function copyAllIntoWWW(paths) {
24 return new Promise((resolve, reject) => {
25 for(const path of paths) {
26 log(path)
27 if (!fs.existsSync(path)) {
28 log(`Directory does not exist in project: ${path}`)
29 continue;
30 }
31
32 var publicPath = path
33 publicPath = publicPath.replace('/app','/www')
34 try {
35 child_process.execSync(`mkdir -p ${publicPath} & cp -rf ${path}/* ${publicPath}`);
36 log(`Done copying: ${path}`)
37 } catch (err) {
38 console.error(err)
39 }
40 }
41 });
42}
43
44// ====================================================================
45// |
46// ====================================================================
47function copyIntoWWW(path) {
48
49 // Do not compile inside .delete folders
50 if (path.includes(".delete")) {
51 return
52 }
53
54 log(path);
55
56 var publicPath = path
57 publicPath = publicPath.replace('/app','/www')
58
59 try {
60 child_process.execSync(`cp -rf ${path} ${publicPath}`);
61 log(`Done copying: ${path}`)
62 } catch (err) {
63 console.error(err)
64 }
65}
66
67// ====================================================================
68// |
69// ====================================================================
70function deleteFromWWW(path) {
71
72 // Do not compile inside .delete folders
73 if (path.includes(".delete")) {
74 return
75 }
76
77 log(path);
78
79 var publicPath = path
80 publicPath = publicPath.replace('/app','/www')
81
82 try {
83 child_process.execSync(`rm -rf ${path} ${publicPath}`);
84 log(`Done deleting: ${path}`)
85 } catch (err) {
86 console.error(err)
87 }
88}
89
90
91// ====================================================================
92// |
93// ====================================================================
94function startWatcher(watchFolders) {
95 // https://github.com/paulmillr/chokidar
96 const options = {
97 awaitFinish: true,
98 ignoreInitial: true,
99 usePolling: true,
100 interval: 100,
101 depth: 5
102 }
103
104 const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => {
105 log(event, path);
106 });
107
108 watcher
109 .on('add', path => copyIntoWWW(path))
110 .on('addDir', path => copyIntoWWW(path))
111 .on('change', path => copyIntoWWW(path))
112 .on('unlink', path => deleteFromWWW(path))
113 .on('unlinkDir', path => deleteFromWWW(path));
114
115 watcher
116 .on('ready', () => log('********** Watch is running **********'));
117}
118
119
120// ====================================================================
121// | MAIN
122// ====================================================================
123async function go() {
124 const watchFolders = [
125 '/app/css',
126 '/app/docs',
127 '/app/fonts',
128 '/app/images',
129 '/app/libs',
130 '/app/lib'
131 ]
132 if (process.argv[2] == 'recompile') {
133 await copyAllIntoWWW(watchFolders)
134 startWatcher(watchFolders);
135 } else {
136 startWatcher(watchFolders);
137 }
138}
139
140go()
builder-init.sh Originalformat
1#!/bin/bash
2CANARY_FILE=/app/.provisioning/builder-rebuild
3
4if [ ! -f "$CANARY_FILE" ] ; then
5 echo "Initialization incomplete! Running Builder Rebulid..."
6 cd /opt/builder && bash ./clean-and-build.sh &
7 mkdir -p /app/.provisioning && date +%F_%T >> /app/.provisioning/builder-rebuild
8else
9
10 ln -sf /app/docs /www
11 ln -sf /app/fonts /www
12 ln -sf /app/images /www
13 ln -sf /app/libs /www
14 ln -sf /app/lib /www
15
16 pm2 delete all
17 pm2 start /opt/builder/sass-watcher.js
18 pm2 start /opt/builder/javascript-watcher.js
19 pm2 start /opt/builder/jade-watcher.js
20 # pm2 start /opt/builder/pug-watcher.js
21 # pm2 start /opt/builder/assets-watcher.js
22
23fi
clean-and-build.sh Originalformat
1#!/bin/bash
2pm2 stop all
3
4ln -sf /app/docs /www
5ln -sf /app/fonts /www
6ln -sf /app/images /www
7ln -sf /app/libs /www
8ln -sf /app/lib /www
9
10# PM2 Style
11pm2 delete all
12pm2 start /opt/builder/sass-watcher.js -- recompile
13pm2 start /opt/builder/javascript-watcher.js -- recompile
14pm2 start /opt/builder/jade-watcher.js -- recompile
15# pm2 start /opt/builder/pug-watcher.js -- recompile
16# pm2 start /opt/builder/assets-watcher.js -- recompile
jade-watcher.js Originalformat
1import chokidar from 'chokidar';
2import fs from 'fs'
3import fse from 'fs-extra';
4import jade from 'jade';
5import klaw from 'klaw';
6import beautify from 'beautify';
7import cleaner from 'clean-html';
8import fg from 'fast-glob';
9import inliner from '@css-inline/css-inline';
10
11// ====================================================================
12// |
13// ====================================================================
14function log(message) {
15 const options = {
16 encoding: "utf-8",
17 flag: "a+",
18 };
19 const datetime = new Date().toISOString()
20 message = `[${datetime}] ${message}\n`
21 fse.outputFileSync('/logs/builder/jade.log', message, options);
22 console.log(message)
23}
24
25// ====================================================================
26// |
27// ====================================================================
28function compile(path) {
29
30 log(`${path} was changed`)
31
32 // Do not compile inside .delete folders
33 if (path.includes(".delete")) {
34 return
35 }
36
37 // Do not compile inside _partials folders
38 if (path.includes("layouts")) {
39 log("Recompiling /app/views/layouts")
40 compileAll('/app/views/layouts/**/*.jade')
41 return
42 }
43
44 // Do not compile inside _partials folders
45 if (path.includes("_partials") || path.includes("partials")) {
46 log("Recompiling /app/views")
47 compileAll('/app/views/**/*.jade')
48 return
49 }
50
51 // Do not compile partials (begins with _)
52 const filename = path.split("/").slice(-1).toString()
53 if (filename.startsWith("_")) {
54 const underscorecount = (filename.match(/_/g) || []).length;
55 const directoryIndex = 0 - underscorecount
56 const parentDirectory = path.split("/").slice(0,directoryIndex).join("/")+'/**/*.jade'
57 log("Recompiling "+parentDirectory)
58 compileAll( parentDirectory )
59 return
60 }
61
62 // Do not compile if the file does not end with .jade
63 if (!path.endsWith(".jade")) {
64 return
65 }
66
67 log(` Recompiling ${path}`)
68 const options = {
69 basedir: '/app/views'
70 }
71 var result = '';
72 result = jade.renderFile(path,options);
73
74 var publicPath = path
75 publicPath = publicPath.replace('/app/views','/www')
76 publicPath = publicPath.replace('.jade','.html')
77
78 // Convert to CSS Inline for Email Templates
79 // if (publicPath.includes("/www/emails")) {
80 // console.log('Inlining Email Template CSS')
81 // result = inliner.inline(result);
82 // console.log('Inlining Email Template CSS Done');
83 // }
84
85 //-
86 //- Clean HTML Section. Could cause more harm then good. Disabled for now
87 //-
88 // try {
89 // cleaner.clean(result, output => {
90 // fse.outputFileSync(publicPath, output);
91 // });
92 // } catch (err) {
93 // try {
94 // var pretty_options = {format: 'html'}
95 // fse.outputFileSync(publicPath, beautify(result, pretty_options));
96 // } catch (err) {
97 // fse.outputFileSync(publicPath, result);
98 // log(`[ERROR] HTML Cleaner: ${path}`)
99 // log(err)
100 // log(`[ERROR] Unformatted jade file was saved`)
101 // }
102 // }
103 fse.outputFileSync(publicPath, result);
104}
105
106// ====================================================================
107// |
108// ====================================================================
109function compileParents(path) {
110
111 // Do not compile inside .delete folders
112 if (path.includes(".delete")) {
113 return
114 }
115
116 // Do not compile partials (begins with _)
117 const filename = path.split("/").slice(-1).toString()
118 if (filename.startsWith("_")) {
119 return
120 }
121
122 // Do not compile inside _partials folders
123 if (path.includes("_partials") || path.includes("partials")) {
124 return
125 }
126
127 // Do not compile if the file does not end with .jade
128 if (!path.endsWith(".jade")) {
129 return
130 }
131
132 // log(` Recompiling ${path}`)
133 const options = {
134 basedir: '/app/views'
135 }
136 var result = '';
137 result = jade.renderFile(path, options);
138
139 var publicPath = path
140 publicPath = publicPath.replace('/app/views','/www')
141 publicPath = publicPath.replace('.jade','.html')
142
143 // Convert to CSS Inline for Email Templates
144 // if (publicPath.includes("/www/emails")) {
145 // console.log('Inlining Email Template CSS')
146 // result = inliner.inline(result);
147 // console.log('Inlining Email Template CSS Done');
148 // }
149
150 //-
151 //- Clean HTML Section. Could cause more harm then good. Disabled for now
152 //-
153 // try {
154 // cleaner.clean(result, output => {
155 // fse.outputFileSync(publicPath, output);
156 // });
157 // } catch (err) {
158 // try {
159 // var pretty_options = {format: 'html'}
160 // fse.outputFileSync(publicPath, beautify(result, pretty_options));
161 // } catch (err) {
162 // fse.outputFileSync(publicPath, result);
163 // log(`[ERROR] HTML Cleaner: ${path}`)
164 // log(err)
165 // log(`[ERROR] Unformatted jade file was saved`)
166 // }
167 // }
168 fse.outputFileSync(publicPath, result);
169
170}
171
172// ====================================================================
173// |
174// ====================================================================
175function compileAll(glob) {
176 return new Promise((resolve, reject) => {
177 const jadeFiles = fg.globSync(glob)
178 for (const file of jadeFiles) {
179 compileParents(file);
180 }
181 });
182}
183
184// ====================================================================
185// |
186// ====================================================================
187function startWatcher() {
188 const watchFolders = [
189 '/app/views/**/*.jade',
190 ]
191
192 // https://github.com/paulmillr/chokidar
193 const options = {
194 awaitFinish: true,
195 ignoreInitial: true,
196 usePolling: true,
197 interval: 100
198 }
199
200 const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => {
201 });
202
203 watcher
204 .on('add', path => compile(path))
205 .on('change', path => compile(path))
206 .on('unlink', path => compile(path));
207
208 watcher
209 .on('ready', () => log('********** Watch is running **********'));
210}
211
212// ====================================================================
213// | MAIN
214// ====================================================================
215async function go() {
216 if (process.argv[2] == 'recompile') {
217 await compileAll('/app/views/**/*.jade');
218 startWatcher();
219 } else {
220 startWatcher();
221 }
222}
223
224go()
javascript-watcher.js Originalformat
1import chokidar from 'chokidar';
2import fs from 'fs'
3import fse from 'fs-extra';
4import path from 'path';
5import fg from 'fast-glob';
6
7// ====================================================================
8// |
9// ====================================================================
10function log(message) {
11 const options = {
12 encoding: "utf-8",
13 flag: "a+",
14 };
15 const datetime = new Date().toISOString()
16 message = `[${datetime}] ${message}\n`
17 fse.outputFileSync('/logs/builder/javascript.log', message, options);
18 console.log(message)
19}
20
21// ====================================================================
22// |
23// ====================================================================
24function concatJavascript(path) {
25 log('-----------------------');
26 log(path);
27
28 var publicPath = path
29 publicPath = publicPath.replace('/app/js','/www/js')
30
31 var jsFolder = path;
32 jsFolder = jsFolder.split("/")[3];
33
34 const source = `/app/js/${jsFolder}`
35 const destination = `/www/js/${jsFolder}.js`
36 fs.readdir(source, (err, files) => {
37 if (err) throw err;
38
39 fse.ensureFileSync(destination)
40 fs.writeFileSync(destination,'')
41 var sortedfiles = files.sort()
42 sortedfiles.forEach(file => {
43 const filePath = `${source}/${file}`
44 var contents = fs.readFileSync(filePath);
45 const spacer = `\n// ====================================================================\n// |\n// |\n// | ${file}\n// |\n// |\n// ====================================================================\n`
46 fs.appendFileSync(destination, spacer+contents)
47 });
48 });
49
50}
51
52// ====================================================================
53// |
54// ====================================================================
55function compileAll(glob) {
56 return new Promise((resolve, reject) => {
57 const javascriptFiles = fg.globSync(glob)
58 for (const file of javascriptFiles) {
59 concatJavascript(file);
60 }
61 log(`Done`)
62 });
63}
64
65// ====================================================================
66// |
67// ====================================================================
68function startWatcher(watchFolders) {
69
70 // https://github.com/paulmillr/chokidar
71 const options = {
72 awaitFinish: true,
73 ignoreInitial: true,
74 usePolling: true,
75 interval: 100
76 }
77
78 const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => {
79 log(event, path);
80 });
81
82 watcher
83 .on('add', path => concatJavascript(path))
84 .on('change', path => concatJavascript(path))
85 .on('unlink', path => concatJavascript(path));
86
87 watcher
88 .on('ready', () => log('********** Watch is running **********'));
89
90}
91
92// ====================================================================
93// | MAIN
94// ====================================================================
95async function go() {
96 const watchFolders = [
97 '/app/js'
98 ]
99 if (process.argv[2] == 'recompile') {
100 await compileAll('/app/js/*/**.js')
101 startWatcher(watchFolders);
102 } else {
103 startWatcher(watchFolders);
104 }
105}
106
107go()
package.json Originalformat
1{
2 "name": "workflowmasters-builder",
3 "type": "module",
4 "devDependencies": {
5 "beautify": "0.0.8",
6 "chokidar": "3.6.0",
7 "character-parser": "4.0.0",
8 "clean-html": "2.0.1",
9 "concat-files": "0.1.1",
10 "fast-glob": "3.3.1",
11 "fs-extra": "11.1.1",
12 "glob": "10.3.10",
13 "html-prettify": "1.0.7",
14 "jade": "1.11.0",
15 "klaw": "4.1.0",
16 "pug": "3.0.2",
17 "sass": "1.64.1",
18 "through2": "4.0.2",
19 "@css-inline/css-inline":"0.14.1",
20 "watcher": "2.2.2"
21 },
22 "scripts": {
23 "watch": "./watcher.js",
24 "test": "gulp test"
25 }
26}
pug-watcher.js Originalformat
1import chokidar from 'chokidar';
2import fs from 'fs'
3import fse from 'fs-extra';
4import pug from 'pug';
5import klaw from 'klaw';
6import pretty from 'pretty';
7
8// ====================================================================
9// |
10// ====================================================================
11function log(message) {
12 const options = {
13 encoding: "utf-8",
14 flag: "a+",
15 };
16 const datetime = new Date().toISOString()
17 message = `[${datetime}] ${message}\n`
18 fse.outputFileSync('/logs/builder/pug.log', message, options);
19 console.log(message)
20}
21
22// ====================================================================
23// |
24// ====================================================================
25function printChange(path) {
26 log(path)
27}
28
29// ====================================================================
30// |
31// ====================================================================
32function compile(path) {
33
34 // Do not compile inside .delete folders
35 if (path.includes(".delete")) {
36 return
37 }
38
39 // Do not compile partials (begins with _)
40 const filename = path.split("/").slice(-1).toString()
41 if (filename.startsWith("_")) {
42 compileAll()
43 return
44 }
45
46 // Do not compile inside _partials folders
47 if (path.includes("_partials") || path.includes("partials")) {
48 log('Partial Edited. Recompile all!')
49 compileAll()
50 return
51 }
52
53 // Do not compile if the file does not end with .pug
54 if (!path.endsWith(".pug")) {
55 log('Partial Edited. Recompile all!')
56 return
57 }
58
59 log(`Recompiling ${path}`)
60 const result = pug.renderFile(path);
61
62 var publicPath = path
63 publicPath = publicPath.replace('/app/views','/www')
64 publicPath = publicPath.replace('.pug','.html')
65
66 fse.outputFile(publicPath, pretty(result), err => {
67 if (err) {
68 console.error(err);
69 }
70 // file written successfully
71 });
72
73}
74
75// ====================================================================
76// |
77// ====================================================================
78function compileParents(path) {
79
80 // Do not compile inside .delete folders
81 if (path.includes(".delete")) {
82 return
83 }
84
85 // Do not compile partials (begins with _)
86 const filename = path.split("/").slice(-1).toString()
87 if (filename.startsWith("_")) {
88 return
89 }
90
91 // Do not compile inside _partials folders
92 if (path.includes("_partials") || path.includes("partials")) {
93 return
94 }
95
96 // Do not compile if the file does not end with .pug
97 if (!path.endsWith(".pug")) {
98 return
99 }
100
101 log(`Recompiling ${path}`)
102 const result = pug.renderFile(path);
103
104 var publicPath = path
105 publicPath = publicPath.replace('/app/views','/www')
106 publicPath = publicPath.replace('.pug','.html')
107
108 fse.outputFile(publicPath, pretty(result), err => {
109 if (err) {
110 console.error(err);
111 }
112 // file written successfully
113 });
114
115}
116
117
118// ====================================================================
119// |
120// ====================================================================
121function compileAll() {
122 klaw('/app/views')
123 .on('data', item => compileParents(item.path))
124}
125
126// ====================================================================
127// |
128// ====================================================================
129const watchFolders = [
130 '/app/views/**/*.pug',
131]
132
133var ignoreInitial = true
134if (process.argv[2] == 'recompile') {
135 ignoreInitial = false
136}
137
138// https://github.com/paulmillr/chokidar
139const options = {
140 awaitFinish: true,
141 ignoreInitial: true,
142 usePolling: true,
143 interval: 100
144}
145
146const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => {
147 // log(event, path);
148});
149
150watcher
151 .on('add', path => compile(path))
152 .on('change', path => compile(path))
153 .on('unlink', path => compile(path));
sass-watcher.js Originalformat
1import chokidar from 'chokidar';
2import fs from 'fs'
3import fse from 'fs-extra';
4import * as sass from 'sass';
5import fg from 'fast-glob';
6
7// ====================================================================
8// |
9// ====================================================================
10function log(message) {
11 const options = {
12 encoding: "utf-8",
13 flag: "a+",
14 };
15 const datetime = new Date().toISOString()
16 message = `[${datetime}] ${message}\n`
17 fse.outputFileSync('/logs/builder/sass.log', message, options);
18 console.log(message)
19}
20
21// ====================================================================
22// |
23// ====================================================================
24function compile(path) {
25 log('-----------------------');
26
27 // Do not compile inside .delete folders
28 if (path.includes(".delete")) {
29 return
30 }
31
32 const filename = path.split("/").slice(-1).toString()
33 if (filename.startsWith("_")) {
34 compileAll()
35 return
36 }
37
38 const options = {
39 logger: {
40 warn(message, options) {
41 if (options.span) {
42 log('====================================================================================================================')
43 log(`Warning when compiling: ${options.span.url.pathname}:`)
44 log(` ${message}\n`)
45 }
46 },
47 debug(message, options) {
48 if (options.span) {
49 log('====================================================================================================================')
50 log(`Debug message compiling: ${options.span.url.pathname}:`)
51 log(` ${message}\n`)
52 }
53 }
54 }
55 }
56
57 try {
58 const result = sass.compile(path, options);
59 var publicPath = path
60 publicPath = publicPath.replace('/app/scss','/www/css')
61 publicPath = publicPath.replace('.scss','.css')
62 fse.outputFileSync(publicPath, result.css);
63 } catch (err) {
64 log(`[ERROR] SASS Compile: ${path}`)
65 log(err)
66 }
67
68}
69
70// ====================================================================
71// |
72// ====================================================================
73function compileParents(path) {
74
75 // Do not compile inside .delete folders
76 if (path.includes(".delete")) {
77 return
78 }
79
80 // Do not compile partials (begins with _)
81 const filename = path.split("/").slice(-1).toString()
82 if (filename.startsWith("_")) {
83 return
84 }
85
86 // Do not compile if the file does not end with .scss
87 if (!path.endsWith(".scss")) {
88 return
89 }
90
91 const options = {
92 logger: {
93 warn(message, options) {
94 if (options.span) {
95 log('=============================')
96 log(`Warning when compiling: ${options.span.url.pathname}:`)
97 log(` ${message}\n`)
98 }
99 },
100 debug(message, options) {
101 if (options.span) {
102 log('=============================')
103 log(`Debug message compiling: ${options.span.url.pathname}:`)
104 log(` ${message}\n`)
105 }
106 }
107 }
108 }
109
110 try {
111 const result = sass.compile(path, options);
112 var publicPath = path
113 publicPath = publicPath.replace('/app/scss','/www/css')
114 publicPath = publicPath.replace('.scss','.css')
115 fse.outputFileSync(publicPath, result.css);
116 } catch (err) {
117 log(`[ERROR] SASS Compile: ${path}`)
118 log(err)
119 }
120
121
122}
123
124// ====================================================================
125// |
126// ====================================================================
127function compileAll(glob) {
128 return new Promise((resolve, reject) => {
129 const sassFiles = fg.globSync(glob)
130 for (const file of sassFiles) {
131 compileParents(file);
132 }
133 log(`Done`)
134 });
135}
136
137// ====================================================================
138// |
139// ====================================================================
140function startWatcher(watchFolders) {
141
142 // https://github.com/paulmillr/chokidar
143 const options = {
144 awaitFinish: true,
145 ignoreInitial: true,
146 usePolling: true,
147 interval: 100
148 }
149
150 const watcher = chokidar.watch(watchFolders, options).on('all', (event, path) => {
151 log(`${path} was ${event}`);
152 });
153
154 watcher
155 .on('add', path => compile(path))
156 .on('change', path => compile(path))
157 .on('unlink', path => compile(path));
158
159 watcher
160 .on('ready', () => log('********** Watch is running **********'));
161
162}
163
164// ====================================================================
165// | MAIN
166// ====================================================================
167async function go() {
168 const watchFolders = [
169 '/app/scss/**/*.scss'
170 ]
171 if (process.argv[2] == 'recompile') {
172 await compileAll('/app/scss/**/*.scss')
173 startWatcher(watchFolders);
174 } else {
175 startWatcher(watchFolders);
176 }
177}
178
179go()