quackage 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/launch.json +18 -0
- package/LICENSE +21 -0
- package/README.md +46 -0
- package/debug/.browserslistrc-BACKUP +1 -0
- package/debug/Harness.js +1 -0
- package/debug/package.json +16 -0
- package/gulp/Quackage-Gulpfile.js +140 -0
- package/package.json +69 -0
- package/source/Default-Quackage-Configuration.json +30 -0
- package/source/Quackage.js +129 -0
- package/source/utility/Quackage-Execute-Process-Base.js +38 -0
- package/source/utility/Quackage-Execute-Process.js +64 -0
- package/test/Quackage_tests.js +38 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"type": "node",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"name": "Launch Program",
|
|
11
|
+
"skipFiles": [
|
|
12
|
+
"<node_internals>/**"
|
|
13
|
+
],
|
|
14
|
+
"program": "${workspaceFolder}/source/Quackage.js",
|
|
15
|
+
"args":["build"]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Steven Velozo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Quackage
|
|
2
|
+
|
|
3
|
+
Package. Test. Duck. Name a more iconic trio.
|
|
4
|
+
|
|
5
|
+
Who doesn't love managing configuration and tooling? I can tell you who doesn't love it. I don't love it.
|
|
6
|
+
|
|
7
|
+
This standardizes:
|
|
8
|
+
|
|
9
|
+
1. Building an app for a browser
|
|
10
|
+
2. Transpiling an app for ... older browsers
|
|
11
|
+
3. Running unit tests
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
First you need to install the thing. The easy way is npm or whatever you use to get your packages, which installs the package and puts a couple commands in your node_modules/.bin folder. You run it either with `quack` or `q` for short.
|
|
16
|
+
|
|
17
|
+
```shell
|
|
18
|
+
npm install --save-dev quackage
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Second, quack like a duck.
|
|
22
|
+
|
|
23
|
+
### For instance, you can check your build configurations:
|
|
24
|
+
|
|
25
|
+
```shell
|
|
26
|
+
npx quack check-build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### You can build the app
|
|
31
|
+
|
|
32
|
+
```shell
|
|
33
|
+
npx quack build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### You can test
|
|
37
|
+
|
|
38
|
+
```shell
|
|
39
|
+
npx quack test
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## If you hate this, you can always inject commands into your `package.json` file:
|
|
43
|
+
|
|
44
|
+
```shell
|
|
45
|
+
npx quack enhance-my-package
|
|
46
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
since 2018
|
package/debug/Harness.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log('Fancy debug harness here. Shame if it would get quacked.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "quackage-debug",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "Harness.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"Small",
|
|
11
|
+
"official",
|
|
12
|
+
"different."
|
|
13
|
+
],
|
|
14
|
+
"author": "steven velozo",
|
|
15
|
+
"license": "MIT"
|
|
16
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
After hours of reading and trying various ways of using gulp-env, environment variables
|
|
5
|
+
and babel browesrslistrc / package.json environments it is clear that the state of using
|
|
6
|
+
these tools is a mess. There are ways of getting it to work but none of them feel like
|
|
7
|
+
they will work well in the long term (all of the examples seem to be in bands of about
|
|
8
|
+
a year or two of working before the pattern changes entirely).
|
|
9
|
+
|
|
10
|
+
WHY did we need such a crazy compatible version? wkhtmltopdf is why. It uses a very
|
|
11
|
+
old incompatible version of the QT browser.
|
|
12
|
+
|
|
13
|
+
Therefore, we will use a very old and simple method.
|
|
14
|
+
|
|
15
|
+
1) There is a config file (gulpfile-config.json), documented here, describing the inputs and outputs for the build operation.
|
|
16
|
+
|
|
17
|
+
const _CONFIG = (
|
|
18
|
+
{
|
|
19
|
+
// The input source file that should be passed to browserify:
|
|
20
|
+
// (if you need to auto-instantiate an object, for instance)
|
|
21
|
+
EntrypointInputSourceFile: `${__dirname}/source/Fable-Browser-Shim.js`,
|
|
22
|
+
|
|
23
|
+
// The name of the packaged object to be passed to browserify:
|
|
24
|
+
// (browserify sets this to global scope and window.SOMEOBJECTNAMEHERE where SOMEOBJECTNAMEHERE is the string below)
|
|
25
|
+
LibraryObjectName: `Fable`,
|
|
26
|
+
|
|
27
|
+
// The folder to write the library files and maps out to:
|
|
28
|
+
LibraryOutputFolder: `${__dirname}/dist/`,
|
|
29
|
+
|
|
30
|
+
// The name of the unminified version of the packaged library, for easy debugging:
|
|
31
|
+
LibraryUniminifiedFileName: `fable.js`,
|
|
32
|
+
|
|
33
|
+
// The name of the minified version of the packaged library, for production release:
|
|
34
|
+
LibraryMinifiedFileName: `fable.min.js`
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
2) We are using a .browserslistrc file... this is what tells gulp-babel, through the
|
|
38
|
+
magic of the @babel/preset-env library, how to transpile the library into a compatible
|
|
39
|
+
enough format for our targets.
|
|
40
|
+
|
|
41
|
+
For example as of writing this, there are two targets we want:
|
|
42
|
+
|
|
43
|
+
* Modern browsers in the last five years, expressed as a .browserslistrc with the string "since 2018"
|
|
44
|
+
* Very old janky browsers expressed as a .browserslistrc with the string "> 0.01%"
|
|
45
|
+
... which is interpreted as anything more than 0.01% of browsers in existence or something like that
|
|
46
|
+
|
|
47
|
+
3) Because we want multiple outputs, and, the tools do fine if we want one output but some of
|
|
48
|
+
the toolchain doesn't like making different targets well, we're just going to have multiple
|
|
49
|
+
configurations and .browserslistrc files. So if our spec above says we need a ".browserslistrc"
|
|
50
|
+
file and a "gulpfile-config.json", we're going to make the following two sets of configuration:
|
|
51
|
+
|
|
52
|
+
* .browserslistrc_default, .gulpfile-config_default.json
|
|
53
|
+
* .browserslistrc_compatible, .gulpfile-config_compatible.json
|
|
54
|
+
|
|
55
|
+
4) We will copy, synchronously, these files to where the rest of our toolchain expects
|
|
56
|
+
them, before we begin the build. This will be done by looking at the GULP_CUSTOM_BUILD_TARGET
|
|
57
|
+
environment variable. This allows us to create new targets to experiment by copying a couple files,
|
|
58
|
+
jimmying the settings and setting an environment variable before running the pipeline.
|
|
59
|
+
|
|
60
|
+
5) We will run the toolchain and it will happily think it's just doing a single build and kinda work.
|
|
61
|
+
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
// ---> Now load the config and get on with building <--- \\
|
|
65
|
+
console.log(``);
|
|
66
|
+
console.log(`---> Loading the gulp config...`);
|
|
67
|
+
const _CONFIG = require(`${process.cwd()}/.gulpfile-quackage-config.json`);
|
|
68
|
+
console.log(` > Building to [${_CONFIG.LibraryUniminifiedFileName}] and [${_CONFIG.LibraryMinifiedFileName}]`)
|
|
69
|
+
|
|
70
|
+
// ---> Boilerplate Browser Uglification and Packaging <--- \\
|
|
71
|
+
console.log(``);
|
|
72
|
+
console.log(`--> Gulp is taking over!`);
|
|
73
|
+
|
|
74
|
+
const libBrowserify = require('browserify');
|
|
75
|
+
const libGulp = require('gulp');
|
|
76
|
+
|
|
77
|
+
const libVinylSourceStream = require('vinyl-source-stream');
|
|
78
|
+
const libVinylBuffer = require('vinyl-buffer');
|
|
79
|
+
|
|
80
|
+
const libSourcemaps = require('gulp-sourcemaps');
|
|
81
|
+
const libGulpUtil = require('gulp-util');
|
|
82
|
+
const libBabel = require('gulp-babel');
|
|
83
|
+
const libTerser = require('gulp-terser');
|
|
84
|
+
|
|
85
|
+
// Build the module for the browser
|
|
86
|
+
libGulp.task('minified',
|
|
87
|
+
() => {
|
|
88
|
+
// set up the custom browserify instance for this task
|
|
89
|
+
var tmpBrowserify = libBrowserify(
|
|
90
|
+
{
|
|
91
|
+
entries: _CONFIG.EntrypointInputSourceFile,
|
|
92
|
+
standalone: _CONFIG.LibraryObjectName,
|
|
93
|
+
debug: true
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return tmpBrowserify.bundle()
|
|
97
|
+
.pipe(libVinylSourceStream(_CONFIG.LibraryMinifiedFileName))
|
|
98
|
+
.pipe(libVinylBuffer())
|
|
99
|
+
.pipe(libSourcemaps.init({loadMaps: true}))
|
|
100
|
+
// Oddly, having a .babelrc with this same thing behaves differently, and is the behavior we want
|
|
101
|
+
//.pipe(libBabel({"presets": ["@babel/preset-env"]}))
|
|
102
|
+
.pipe(libBabel())
|
|
103
|
+
.pipe(libTerser())
|
|
104
|
+
.on('error', libGulpUtil.log)
|
|
105
|
+
.pipe(libSourcemaps.write('./'))
|
|
106
|
+
.pipe(libGulp.dest(_CONFIG.LibraryOutputFolder));
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Build the module for the browser
|
|
110
|
+
libGulp.task('debug',
|
|
111
|
+
() => {
|
|
112
|
+
// set up the custom browserify instance for this task
|
|
113
|
+
var tmpBrowserify = libBrowserify(
|
|
114
|
+
{
|
|
115
|
+
entries: _CONFIG.EntrypointInputSourceFile,
|
|
116
|
+
standalone: _CONFIG.LibraryObjectName,
|
|
117
|
+
debug: true
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return tmpBrowserify.bundle()
|
|
121
|
+
.pipe(libVinylSourceStream(_CONFIG.LibraryUniminifiedFileName))
|
|
122
|
+
.pipe(libVinylBuffer())
|
|
123
|
+
// Oddly, having a .babelrc with this same thing behaves differently, and is the behavior we want
|
|
124
|
+
//.pipe(libBabel({"presets": ["@babel/preset-env"]}))
|
|
125
|
+
.pipe(libBabel())
|
|
126
|
+
.on('error', libGulpUtil.log)
|
|
127
|
+
.pipe(libGulp.dest(_CONFIG.LibraryOutputFolder));
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
libGulp.task
|
|
131
|
+
(
|
|
132
|
+
'build',
|
|
133
|
+
libGulp.series('debug', 'minified')
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
libGulp.task
|
|
137
|
+
(
|
|
138
|
+
'default',
|
|
139
|
+
libGulp.series('debug', 'minified')
|
|
140
|
+
);
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "quackage",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Building. Testing. Quacking.",
|
|
5
|
+
"main": "source/Quackage.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node source/Quackage.js",
|
|
8
|
+
"coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
|
|
9
|
+
"test": "./node_modules/.bin/mocha -u tdd -R spec",
|
|
10
|
+
"build": "./node_modules/.bin/gulp build",
|
|
11
|
+
"build-compatible": "GULP_CUSTOM_BUILD_TARGET=compatible ./node_modules/.bin/gulp build"
|
|
12
|
+
},
|
|
13
|
+
"mocha": {
|
|
14
|
+
"diff": true,
|
|
15
|
+
"extension": [
|
|
16
|
+
"js"
|
|
17
|
+
],
|
|
18
|
+
"package": "./package.json",
|
|
19
|
+
"reporter": "spec",
|
|
20
|
+
"slow": "75",
|
|
21
|
+
"timeout": "5000",
|
|
22
|
+
"ui": "tdd",
|
|
23
|
+
"watch-files": [
|
|
24
|
+
"source/**/*.js",
|
|
25
|
+
"test/**/*.js"
|
|
26
|
+
],
|
|
27
|
+
"watch-ignore": [
|
|
28
|
+
"lib/vendor"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/stevenvelozo/quackage.git"
|
|
34
|
+
},
|
|
35
|
+
"browser": {
|
|
36
|
+
"./source/utility/Quackage-Execute-Process.js": "./source/utility/Quackage-Execute-Process-Base.js"
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"keywords": [
|
|
40
|
+
"entity",
|
|
41
|
+
"behavior"
|
|
42
|
+
],
|
|
43
|
+
"author": "Steven Velozo <steven@velozo.com> (http://velozo.com/)",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/stevenvelozo/quackage/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/stevenvelozo/quackage",
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@babel/core": "^7.22.1",
|
|
51
|
+
"@babel/preset-env": "^7.22.2",
|
|
52
|
+
"browserify": "^17.0.0",
|
|
53
|
+
"chai": "4.3.7",
|
|
54
|
+
"commander": "^10.0.1",
|
|
55
|
+
"gulp": "^4.0.2",
|
|
56
|
+
"gulp-babel": "^8.0.0",
|
|
57
|
+
"gulp-env": "^0.4.0",
|
|
58
|
+
"gulp-sourcemaps": "^3.0.0",
|
|
59
|
+
"gulp-terser": "^2.1.0",
|
|
60
|
+
"gulp-util": "^3.0.8",
|
|
61
|
+
"mocha": "10.2.0",
|
|
62
|
+
"npm-check-updates": "^16.10.12",
|
|
63
|
+
"nyc": "^15.1.0",
|
|
64
|
+
"pict": "^1.0.55",
|
|
65
|
+
"retold-data-service": "^1.0.3",
|
|
66
|
+
"vinyl-buffer": "^1.0.1",
|
|
67
|
+
"vinyl-source-stream": "^2.0.0"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"QuackageBaseGulpfile": "require('{~Data:AppData.QuackageFolder~}/gulp/Quackage-Gulpfile.js');",
|
|
3
|
+
"GulpfileConfiguration":
|
|
4
|
+
{
|
|
5
|
+
"EntrypointInputSourceFile": "{~Data:AppData.CWD~}/{~Data:AppData.Package.main~}",
|
|
6
|
+
"LibraryObjectName": "{~Data:AppData.Package.name~}",
|
|
7
|
+
"LibraryOutputFolder": "{~Data:AppData.CWD~}/dist/",
|
|
8
|
+
"LibraryUniminifiedFileName": "{~Data:AppData.Package.name~}.{~Data:Record.BuildFileLabel~}js",
|
|
9
|
+
"LibraryMinifiedFileName": "{~Data:AppData.Package.name~}.{~Data:Record.BuildFileLabel~}min.js"
|
|
10
|
+
},
|
|
11
|
+
"DefaultBabelRC":
|
|
12
|
+
{
|
|
13
|
+
"presets": ["@babel/preset-env"]
|
|
14
|
+
},
|
|
15
|
+
"GulpExecutions":
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
"Hash": "default",
|
|
19
|
+
"Name": "Default standard build.",
|
|
20
|
+
"BuildFileLabel": "",
|
|
21
|
+
"BrowsersListRC": "since 2018"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"Hash": "compatible",
|
|
25
|
+
"Name": "Default standard build.",
|
|
26
|
+
"BuildFileLabel": "compatible.",
|
|
27
|
+
"BrowsersListRC": "> 0.01%"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const libFS = require('fs');
|
|
2
|
+
const libPict = require('pict');
|
|
3
|
+
const libCommander = require('commander').Command;
|
|
4
|
+
|
|
5
|
+
const _QuackagePackage = require('../package.json');
|
|
6
|
+
const _QuackageDefaultConfiguration = require('./Default-Quackage-Configuration.json');
|
|
7
|
+
|
|
8
|
+
let _Pict = new libPict(
|
|
9
|
+
{
|
|
10
|
+
Product: 'Quackage',
|
|
11
|
+
ProductVersion: '1.0.0'
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
_Pict.serviceManager.addAndInstantiateServiceType('QuackageProcess', require('./utility/Quackage-Execute-Process.js'));
|
|
15
|
+
|
|
16
|
+
// Grab the current working directory for the quackage
|
|
17
|
+
_Pict.AppData.CWD = _Pict.QuackageProcess.cwd();
|
|
18
|
+
_Pict.AppData.QuackageFolder = _Pict.QuackageProcess.quackageFolder();
|
|
19
|
+
|
|
20
|
+
// Check that a package.json is in the folder we are quacking from
|
|
21
|
+
try
|
|
22
|
+
{
|
|
23
|
+
_Pict.AppData.Package = require(`${_Pict.AppData.CWD}/package.json`);
|
|
24
|
+
}
|
|
25
|
+
catch (pError)
|
|
26
|
+
{
|
|
27
|
+
_Pict.log.error(`No package.json found in [${_Pict.AppData.CWD}]. Please run quackage from a folder with a package.json file.`);
|
|
28
|
+
_Pict.log.info(`Quack a nice day!`)
|
|
29
|
+
_Pict.QuackageProcess.exitParentProcess(1);
|
|
30
|
+
}
|
|
31
|
+
finally
|
|
32
|
+
{
|
|
33
|
+
// Check for a quackage.json file
|
|
34
|
+
try
|
|
35
|
+
{
|
|
36
|
+
_Pict.AppData.QuackagePackage = require(`${_Pict.AppData.CWD}/.quackage.json`);
|
|
37
|
+
_Pict.AppData.QuackagePackage = _Pict.Utility.extend(_QuackageDefaultConfiguration, _Pict.AppData.QuackagePackage);
|
|
38
|
+
}
|
|
39
|
+
catch (pError)
|
|
40
|
+
{
|
|
41
|
+
_Pict.log.warn(`No quackage.json found in [${_Pict.AppData.CWD}]. Using default configuration.`);
|
|
42
|
+
_Pict.AppData.QuackagePackage = _QuackageDefaultConfiguration;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Use the Commander library to deal with CLI parameters
|
|
46
|
+
_Pict.Command = new libCommander();
|
|
47
|
+
|
|
48
|
+
_Pict.Command.name('quackage')
|
|
49
|
+
.description('CLI testing and building meant to be run from a folder with a package.json and customized with a quackage.json')
|
|
50
|
+
.version(_QuackagePackage.version);
|
|
51
|
+
|
|
52
|
+
_Pict.Command.command('build')
|
|
53
|
+
.description('Build your npm module into a dist folder')
|
|
54
|
+
.argument('[config]', 'optional hash of the configuration you want to run -- otherwise all are built', "ALL")
|
|
55
|
+
//.option('-s, --separator <char>', 'separator character', ',')
|
|
56
|
+
.action((pString, pOptions) =>
|
|
57
|
+
{
|
|
58
|
+
let tmpActionsToExecute = pString.toUpperCase();
|
|
59
|
+
let tmpActionSet = [];
|
|
60
|
+
|
|
61
|
+
_Pict.log.info(`Building your module to ${pString} from the command...`,pOptions);
|
|
62
|
+
|
|
63
|
+
// ##. Load the gulp config and code template files into our pict
|
|
64
|
+
_Pict.TemplateProvider.addTemplate('Gulpfile-Configuration', JSON.stringify(_Pict.AppData.QuackagePackage.GulpfileConfiguration,null,4));
|
|
65
|
+
_Pict.TemplateProvider.addTemplate('Gulpfile-QuackageBase', _Pict.AppData.QuackagePackage.QuackageBaseGulpfile);
|
|
66
|
+
|
|
67
|
+
// ##. Figure out which actions to execute
|
|
68
|
+
for (let i = 0; i < _Pict.AppData.QuackagePackage.GulpExecutions.length; i++)
|
|
69
|
+
{
|
|
70
|
+
if (tmpActionsToExecute == 'ALL' || tmpActionsToExecute.includes(_Pict.AppData.QuackagePackage.GulpExecutions[i].Name.toUpperCase()))
|
|
71
|
+
{
|
|
72
|
+
tmpActionSet.push(_Pict.AppData.QuackagePackage.GulpExecutions[i]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (tmpActionSet.length < 1)
|
|
77
|
+
{
|
|
78
|
+
_Pict.log.error(`No actions to execute for the configuration hash [${pString}]`);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ##. Enumerate the actions, executing each one, in series asynchronously
|
|
83
|
+
_Pict.Utility.eachLimit(
|
|
84
|
+
tmpActionSet, 1,
|
|
85
|
+
(pAction, fActionCallback) =>
|
|
86
|
+
{
|
|
87
|
+
_Pict.log.info(`Executing action [${pAction.Name}]...`);
|
|
88
|
+
|
|
89
|
+
// ## .browserslistrc
|
|
90
|
+
if (pAction.hasOwnProperty('BrowsersListRC'))
|
|
91
|
+
{
|
|
92
|
+
// ## Backup the .browserslistrc file if it existst
|
|
93
|
+
if (libFS.existsSync(`${_Pict.AppData.CWD}/.browserslistrc`))
|
|
94
|
+
{
|
|
95
|
+
libFS.copyFileSync(`${_Pict.AppData.CWD}/.browserslistrc`, `${_Pict.AppData.CWD}/.browserslistrc-BACKUP`);
|
|
96
|
+
_Pict.log.info(`Contents of existing .browserslistrc backed up to .browserslistrc-BACKUP and output below:`, {FileContents:libFS.readFileSync(`${_Pict.AppData.CWD}/.browserslistrc`).toString()});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ## Write out the browserslistrc
|
|
100
|
+
libFS.writeFileSync(`${_Pict.AppData.CWD}/.browserslistrc`, pAction.BrowsersListRC);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// ## .babelrc
|
|
104
|
+
if (_Pict.AppData.QuackagePackage.DefaultBabelRC)
|
|
105
|
+
{
|
|
106
|
+
if (libFS.existsSync(`${_Pict.AppData.CWD}/.babelrc`))
|
|
107
|
+
{
|
|
108
|
+
_Pict.log.info(`Leaving the existing .babelrc file in place. Please make sure it is compatible with the build you are trying to make.`);
|
|
109
|
+
}
|
|
110
|
+
else
|
|
111
|
+
{
|
|
112
|
+
libFS.writeFileSync(`${_Pict.AppData.CWD}/.babelrc`, JSON.stringify(_Pict.AppData.QuackagePackage.DefaultBabelRC,null,4));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ## gulpfile-quackage-config.json
|
|
117
|
+
libFS.writeFileSync(`${_Pict.AppData.CWD}/.gulpfile-quackage-config.json`, _Pict.parseTemplateByHash('Gulpfile-Configuration', pAction));
|
|
118
|
+
// ## gulpfile-quackage.js
|
|
119
|
+
libFS.writeFileSync(`${_Pict.AppData.CWD}/.gulpfile-quackage.js`, _Pict.parseTemplateByHash('Gulpfile-QuackageBase', {AppData:_Pict.AppData, Record:pAction}));
|
|
120
|
+
|
|
121
|
+
// Now execute the gulpfile using our custom service provider!
|
|
122
|
+
_Pict.QuackageProcess.execute(`./node_modules/.bin/gulp`, [`--gulpfile`, `${_Pict.AppData.CWD}/.gulpfile-quackage.js`], {cwd:_Pict.AppData.CWD}, fActionCallback);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
_Pict.Command.parse();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = _Pict;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const libPict = require('pict');
|
|
2
|
+
|
|
3
|
+
class BaseQuackageProcessExecutionService extends libPict.ServiceProviderBase
|
|
4
|
+
{
|
|
5
|
+
constructor(pFable, pManifest, pServiceHash)
|
|
6
|
+
{
|
|
7
|
+
super(pFable, pManifest, pServiceHash);
|
|
8
|
+
|
|
9
|
+
this.serviceType = 'QuackageProcess';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
cwd()
|
|
13
|
+
{
|
|
14
|
+
return `ABSTRACT_CWD`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
quackageFolder()
|
|
19
|
+
{
|
|
20
|
+
return `ABSTRACT_QUACKAGE_FOLDER`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exitParentProcess(pCode)
|
|
24
|
+
{
|
|
25
|
+
return 'ABSTRACT_EXIT_PARENT_PROCESS';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
execute(pProcess, pArguments, pOptions, fCallback)
|
|
29
|
+
{
|
|
30
|
+
// Now log out what our execution would be!
|
|
31
|
+
this.log.info(`Executing process: ${pProcess}`);
|
|
32
|
+
this.log.trace(`Full command: ${pProcess} ${pArguments.join(' ')}`, pOptions);
|
|
33
|
+
|
|
34
|
+
return fCallback();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = BaseQuackageProcessExecutionService;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const libQuackageExecuteProcessBase = require(`./Quackage-Execute-Process-Base.js`);
|
|
2
|
+
const libChildProcess = require('child_process');
|
|
3
|
+
|
|
4
|
+
class BaseQuackageProcessExecutionService extends libQuackageExecuteProcessBase
|
|
5
|
+
{
|
|
6
|
+
constructor(pFable, pManifest, pServiceHash)
|
|
7
|
+
{
|
|
8
|
+
super(pFable, pManifest, pServiceHash);
|
|
9
|
+
|
|
10
|
+
this.serviceType = 'QuackageProcess';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
cwd()
|
|
14
|
+
{
|
|
15
|
+
return process.cwd();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
quackageFolder()
|
|
19
|
+
{
|
|
20
|
+
return `${__dirname}/../..`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exitParentProcess(pCode)
|
|
24
|
+
{
|
|
25
|
+
process.exit(pCode);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
execute(pProcess, pArguments, pOptions, fCallback)
|
|
29
|
+
{
|
|
30
|
+
// Now log out what our execution would be!
|
|
31
|
+
this.log.info(`Executing process: ${pProcess}`);
|
|
32
|
+
this.log.trace(`Full command: ${pProcess} ${pArguments.join(' ')}`, pOptions);
|
|
33
|
+
|
|
34
|
+
// Now execute the gulpfile!
|
|
35
|
+
const tmpProcess = libChildProcess.spawn(pProcess, pArguments, pOptions);
|
|
36
|
+
|
|
37
|
+
tmpProcess.stdout.on('data',
|
|
38
|
+
(pConsoleOutput) =>
|
|
39
|
+
{
|
|
40
|
+
this.log.trace(pConsoleOutput);
|
|
41
|
+
});
|
|
42
|
+
tmpProcess.stderr.on('data',
|
|
43
|
+
(pConsoleOutput) =>
|
|
44
|
+
{
|
|
45
|
+
this.log.error(pConsoleOutput);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
tmpProcess.stderr.on('error',
|
|
49
|
+
(pError) =>
|
|
50
|
+
{
|
|
51
|
+
this.log.error(`Process execution failed in your quackage manager! Error: ${pError.message}`);
|
|
52
|
+
return fCallback(pError);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
tmpProcess.stderr.on('close',
|
|
56
|
+
(pError) =>
|
|
57
|
+
{
|
|
58
|
+
this.log.info(`Process completed successfully, with a quack!`);
|
|
59
|
+
return fCallback(pError);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = BaseQuackageProcessExecutionService;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for Quackage
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
*
|
|
6
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
var libQuackage = require('../source/Quackage.js');
|
|
10
|
+
|
|
11
|
+
var Chai = require("chai");
|
|
12
|
+
var Expect = Chai.expect;
|
|
13
|
+
|
|
14
|
+
suite
|
|
15
|
+
(
|
|
16
|
+
'Quackage',
|
|
17
|
+
function()
|
|
18
|
+
{
|
|
19
|
+
setup ( () => {} );
|
|
20
|
+
|
|
21
|
+
suite
|
|
22
|
+
(
|
|
23
|
+
'Execution Sanity',
|
|
24
|
+
function()
|
|
25
|
+
{
|
|
26
|
+
test
|
|
27
|
+
(
|
|
28
|
+
'Quackage should load up okay.',
|
|
29
|
+
function()
|
|
30
|
+
{
|
|
31
|
+
let testQuackage = new libQuackage();
|
|
32
|
+
Expect(testQuackage.settings.Product).to.equal('ApplicationNameHere')
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
);
|