Adding zsh ternary operator in npm script - bad subsitution - zsh

I am wanting to use a ternary operator in my npm script:
"scripts": {
"build" "node ${%(ENVVAR=nope.foo.bar)}.js"
}
So that I can use it like:
ENVVAR=nope yarn build
And obtain the resulting command of:
"node foo.js"
However my attempts above (tried parens and square brackets) always yield bad substitution
What is the proper syntax to include a ternary operator in my parameter expansion for this (zsh shell)

The npm docs state:
"The actual shell your script is run within is platform dependent. By default, on Unix-like systems it is the /bin/sh command, on Windows it is the cmd.exe. The actual shell referred to by /bin/sh also depends on the system. As of npm#5.1.0 you can customize the shell with the script-shell configuration."
Therefore given that the shell npm utilizes on *nix is typically sh consider the following npm script instead (Unless of course your npm's script-shell has actually been configured to zsh):
"scripts": {
"build": "[[ $ENVVAR = \"nope\" ]] && val=foo || val=bar; node \"${val}.js\""
}
Note: You can check which shell npm is utilizing via the npm config command: npm config get script-shell
Alternatively, for cross-platform regardless of which shell npm is configured to utilize, consider evaluating a node.js script inline which "shells-out" the node ... command. For example the following (albeit somewhat verbose) npm script utilizes execSync:
"scripts": {
"build": "node -e \"const val = process.env.ENVVAR === 'nope' ? 'foo' : 'bar'; require('child_process').execSync('node ' + val + '.js', { stdio: [0,1,2] })\""
}

Related

Protractor Headless browser Testing using XVFB+Grunt runner on centos 7 linux distribution

Below is my gruntfile.js . I can run the protractor tests on UI using 'grunt protractor:run command.
However, when i try running command ' grunt protractor-xvfb' so that i can run my tests in headless mode, the browser still launches and tests execute in the same way as using grunt protractor:run command.
What i am expecting is that the tests run in background.
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
protractor: {
options: {
keepAlive: true,
configFile: "../spike-protractor/app/Conf/conf.js",
noColor: false,
args: {
baseUrl: 'https://xxx/xxx/'
}
},
run: {}
},
shell: {
xvfb: {
command: 'Xvfb :99 -ac -screen 0 1600x1200x24',
options: {
async: true
}
}
},
env: {
xvfb: {
DISPLAY: ':99'
}
}
});
grunt.loadNpmTasks('grunt-protractor-runner');
grunt.loadNpmTasks('grunt-shell-spawn');
grunt.loadNpmTasks('grunt-env');
grunt.loadNpmTasks('grunt-protractor-webdriver');
grunt.registerTask('protractor-chrome', ['protractor:chrome']);
grunt.registerTask('protractor-xvfb', [
'shell:xvfb',
'env:xvfb',
'protractor:run',
'shell:xvfb:kill'
]);
}
I tried commenting out line code 'protractor:run'from grunt.registerTask and running grunt protractor-xvfb gives me the below output which is correct as per code. This executes so fast as if nothing happened. i think there is something that i am missing in config/code to achieve headless testing .
Running "shell:xvfb" (shell) task
Running "env:xvfb" (env) task
Running "shell:xvfb:kill" (shell) task
Done.
how do i actually proceed on doing headless testing using xvfb + grunt+ protractor ?
Is probably more practical for your use case to go with Zalenium if you want headless Chrome or Firefox testing, video recording, VNC live preview, local dashboard.html among other features.
You can get started with the one-liner:
curl -sSL https://raw.githubusercontent.com/dosel/t/i/p | bash -s start
And/or also watch the presentation:
https://www.youtube.com/watch?v=W5qMsVrob6I
You did not specify to run your conf.js properly.
Remove the part
grunt.registerTask('protractor-chrome', ['protractor:chrome']);
from your gruntfile.js specified in your question.
Edit your gruntfile.js and add below:
grunt.registerTask('protractor-xvfb', [
'shell:xvfb',
'env:xvfb',
'protractor:run',
'shell:xvfb:kill'
]);
Once you add it if you want to run without xvfb use command "grunt protractor:run".
If you want to run using xvfb then use command "grunt protractor-xvfb"
I found a workaround for this to use the below command and specify conf.js -
xvfb-run --server-args='-screen 0, 1600x1200x24' protractor app/Conf/conf.js
Doing this allows to me run my tests in headless mode.
Even if you are not using Grunt in your project, you can directly do npm install xvfb and use this command... pass it to teamcity command line parameters and it will work there as well.

Packaged Electron App cannot find module sqlite3

Background
Within an Electron app, sqlite3 doesn't work right after npm install --save. I got it working after doing some web research, by:
(1) downgrading my node version (via n) to match Electron's node version; and
(2) rebuilding sqlite with the right module name/targets with this package.json script:
"rebuild-sqlite3": "cd node_modules/sqlite3 && npm run prepublish && node-gyp configure --module_name=node_sqlite3 --module_path=../lib/binding/electron-v1.2-darwin-x64 && node-gyp rebuild --target=1.2.6 --arch=x64 --target_platform=darwin --dist-url=https://atom.io/download/atom-shell --module_name=node_sqlite3 --module_path=../lib/binding/electron-v1.2-darwin-x64"
After that, Sqlite3 works in development (i.e. when I run electron . in the project dir).
Problem
I package the app with electron-packager: "./node_modules/.bin/webpack -p && ./node_modules/electron-packager/cli.js ./ --out ./bin --platform=darwin --arch=x64 --version=1.2.6 --overwrite --ignore=\"ignore|bin|node_modules\""
When I open the app by double-clicking the created (appName).app, the console complains: `Uncaught Error: Cannot find module
Question
How can I get sqlite3 to be found in the final packaged product? Even "hacks" or workarounds are welcome, as I tried various fixes to no avail.
I leave this answer for someone who has the same problem and is wasting their time to figure out.
step1
npm install sqlite3
electron .
I expected to work fine. but I had an error 'cannot find node module sqlite3'
step2
npm install electron-rebuild --save-dev
electron-rebuild -f -w sqlite3
electron .
it worked.
but if you used 'electron-packager' to package and make executable file, It didn't work. the same error occured.
"electron-packager . electron-tutorial-app --overwrite --asar --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=new --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName=\"Electron Test\"",
step3
I spent pretty much time to figure out. At the end, I figured out. the solution was using electron-packager API and integrating afterCopy with electron-rebuild.
# build.js
const packager = require('electron-packager');
const rebuild = require('electron-rebuild');
packager({
dir: '../dir',
overwrite: true,
asar: true,
platform: 'win32',
arch: 'ia32',
icon: 'assets/icons/win/icon.ico',
prune: true,
out: 'hello',
executableName: 'hello',
afterCopy: [(buildPath, electronVersion, platform, arch, callback) => {
rebuild.rebuild({ buildPath, electronVersion, arch })
.then(() => callback())
.catch((error) => callback(error));
}],
})
node build.js
reference
electron-rebuild manual 'How can I integrate this into Electron packager?'
electron-packager API doc
Doesn't the --ignore=\"ignore|bin|node_modules\" you pass to electron-packager ignore everything in the node_modules dir, the very place where the sqlite3 module is installed?

How to execute a bash script as sbt task?

I want to automatically build documentation for my Java Play 2.3 application.
At the moment, I use a Makefile to generate images from *.dotfiles and combine Markdown sources together into Html/PDF:
dot diagram1.dot -Tpdf -o diagram1.pdf
dot diagram2.dot -Tpdf -o diagram2.pdf
pandoc doc1.markdown -o doc1.pdf
# ...
Now I want to run these simple bash commands directly from SBT.
What's the best way to do this?
I found some SBT Documentation plugins in the SBT reference, but nothing to run a simple shell script.
You can find some answers in External Processes in the official documentation of sbt, e.g.
To run an external command, follow it with an exclamation mark !:
"find project -name *.jar" !
Don't forget to use import scala.sys.process._ so ! can be resolved as a method of String.
Do the following in activator console (aka sbt shell) to execute yourshell.sh - mind the eval command and the quotes around the name of the script:
eval "yourshell.sh" !
To have it available as a task add the following to build.sbt of your project:
lazy val execScript = taskKey[Unit]("Execute the shell script")
execScript := {
"yourshell.sh" !
}
We had the requirement to execute some npm scripts as sbt task and let the build fail if one of the npm scripts fails. Took me some time to find a way to create a Task that works on Windows and Unix. And so here is what I came up with.
lazy val buildFrontend = taskKey[Unit]("Execute frontend scripts")
buildFrontend := {
val s: TaskStreams = streams.value
val shell: Seq[String] = if (sys.props("os.name").contains("Windows")) Seq("cmd", "/c") else Seq("bash", "-c")
val npmInstall: Seq[String] = shell :+ "npm install"
val npmTest: Seq[String] = shell :+ "npm run test"
val npmLint: Seq[String] = shell :+ "npm run lint"
val npmBuild: Seq[String] = shell :+ "npm run build"
s.log.info("building frontend...")
if((npmInstall #&& npmTest #&& npmLint #&& npmBuild !) == 0) {
s.log.success("frontend build successful!")
} else {
throw new IllegalStateException("frontend build failed!")
}
},
(run in Compile) <<= (run in Compile).dependsOn(buildFrontend)

Reloading/loading Grunt tasks after grunt-check-dependencies installs a Grunt task module

I have been trying to use grunt-check-dependencies to check for NPM module dependencies before running further Grunt tasks. The problem is that this doesn't help when one of the missing NPM dependencies is a Grunt task, e.g. grunt-contrib-concat.
Since Grunt apparently registers tasks before the 'checkDependencies' task is run, even though 'checkDependencies' will successfully install any missing Grunt task modules, it does this "too late" -- Grunt has already determined that the missing modules are missing, and the Grunt build run therefore fails.
One approach that will work is to always use a command line of e.g. "npm install; grunt ...", but I thought I would see if anyone has a completely 'Grunt-internal' solution.
Here's an example Grunt output that demonstrates the issue.
% rm -rf node_modules/grunt-contrib-concat ; grunt
>> Local Npm module "grunt-contrib-concat" not found. Is it installed?
Running "checkDependencies:this" (checkDependencies) task
>> grunt-contrib-concat: not installed!
Invoking npm install...
npm http GET https://registry.npmjs.org/grunt-contrib-concat
npm http 304 https://registry.npmjs.org/grunt-contrib-concat
grunt-contrib-concat#0.3.0 node_modules/grunt-contrib-concat
Warning: Task "concat:dev" not found. Use --force to continue.
Aborted due to warnings.
Here is the example gruntfile.js that caused the above output/error:
module.exports = function(grunt) {
'use strict';
var config = {
concat: {
dev: {
src: ['foo1.js', 'foo2.js'],
dest: 'foo_concat.js'
}
},
checkDependencies: {
this: {
options: {
npmInstall: true
},
},
}
};
// trying to make sure all npm nodules listed in package.json are
// installed before other grunt tasks
grunt.loadNpmTasks('grunt-check-dependencies');
grunt.task.run('checkDependencies');
// load grunt tasks
require('load-grunt-tasks')(grunt);
// alternate approach to loading tasks; exhibits same problem
// grunt.loadNpmTasks('grunt-contrib-concat');
grunt.initConfig(config);
grunt.registerTask('default', ['concat:dev']);
}

WebDriver + Protractor with grunt

I'm trying to run end-to-end tests with WebDriver and Protractor. No problem when I run it manually with:
webdriver-manager start
and then
protractor test-UI/e2e/conf.js
Now I would like to launch them from a grunt command, so I tried with grunt-shell, joining them with '&&'. But as WebDriver waits, tests are never started. Did someone try this before?
Thanks.
There is a fork of Grunt-shell called Grunt-shell-spawn (Github Repo) which allows you to run background processes asynchronously. This happens to work very well with starting the selenium webdriver server helping to automate the protractor testing process. There are a few grunt plugins specifically for starting the webdriver server but from my experience they all have small bugs that cause errors once the tests are finished or require you to mark a flag keepAlive: true which means it will not kill the webdriver server process forcing you to ctrl+c or close and re-open the command prompt which can cause a lot of issues when devs are using the functional tests and with continuous integration (CI) servers. Grunt-shell-spawn has the ability to kill the process as you can see at the end of my 'test' task which is really invaluable for maintaining consistency and ease of use.
'use strict';
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-shell-spawn');
grunt.loadNpmTasks('grunt-protractor-runner');
var path = require('path');
grunt.initConfig({
...
...
...
shell: {
updateserver: {
options: {
stdout: true
},
command: "node " + path.resolve('node_modules/protractor/bin/webdriver-manager') + ' update --standalone --chrome'
},
startserver: {
options: {
stdout:false,
stdin: false,
stderr: false,
async:true
},
command: 'node ' + path.resolve('node_modules/protractor/bin/webdriver-manager') + ' start --standalone'
},
});
grunt.registerTask('test',[
'shell:updateserver',
'shell:startserver',
'protractor:e2e',
'shell:startserver:kill'
]);
You can to install grunt-protractor-runner
npm install grunt-protractor-runner --save-dev
Check this blog with details
http://www.codeorbits.com/blog/2014/01/26/angularjs-end-to-end-testing-with-protractor-easy-set-up-with-yeoman/
Try running grunt --verbose to see more details on whats happening.

Resources