I have a large Node repo with many npm scripts to manage the project. I created an interactive script with Inquirer.js to act as an entry point to help developers to navigate. The script outputs the result in JSON.
To pick the selected npm script, and run it, I tried the following:
{
"scripts": {
"dev": "node dev.js | jq .project | xargs yarn run"
}
}
But instead of seeing the Inquirer script, this command stalls with an error message coming from jq.
What's the right way to wait for the result before piping to the next program?
Related
I am using Azure Devops to build and deploy my git repo to a third party vps. I do this by logging into the server from Azure Devops through SSH, executing a shell script to pull git repo, and build it with ie. vue-cli and Laravel.
When the bash script is executed I receive a lot of errors on nearly all commands although everything is succeeding - can anyone tell me how to get rid of these unless something is really failing (would be nice to fail if npm build exit with code 1 for instance).
See screenshot below.
Screenshots are only really helpful for visual issues. You can use PasteBin or etc to share long logs if necessary.
According to this issue Azure just follows the lead of whatever shell it's running code in. So, in Bash it continues unless explicitly told to stop.
To easily change this behavior you can add set -e (or set -o errexit) at the start of your script. The errexit option causes Bash to exit as soon as a command/etc returns a non-zero exit code.
Another worthy addition is the set -o pipefail option. If you've got any pipes like command1 | command2 this will return the first non-zero exit code from a chain of pipes of any length as the result. So, if command1 fails above but command2 succeeds it would return the failure code from command1 instead of overwriting it.
Finally, set -u (or -o nounset) causes an error when unset variables are encountered during parameter expansion. If running in a non-interactive shell, it will also exit.
Many scripts combine these by running set -euo pipefail at the beginning to stop them from running after the first problem is encountered.
If you want to explicitly force a bash script to exit you can use || and && accordingly. The expression command || exit will exit if the command fails and command && exit will exit if the command succeeds.
This seems to be one bug starting from npm V.3.10.8. You can check this discussion.
As a workaround you can add this script to package.json and run the command with --no-optional switch:
"optionalDependencies": {
"fsevents": "*"
},
Also, there's possibility that your NPM version is too old. You can use Node.js tool installer task with version spec = 12.x to install higher node.js and npm versions.
I've a big Jenkins pipeline and when build is run, lot of console output is generated which causes space issue on Jenkins master.
I've following code in Jenkins pipeline with Shell Script, which logs every file being removed. I've lots of log files that cause lot of console output -
stage('Logs Cleanup') {
steps {
script {
sh '''rm -rf /home/oracle/test/logs1/* /home/oracle/test/logs2/*'''
}
}
}
Is there any way I can suppress output of that command?
NOTE: If same command it run from Terminal, it logs nothing in output.
For your specific delete using Jenkins only:
stage('Logs Cleanup') {
steps {
dir ('/home/oracle/test/logs1/') {
deleteDir()
}
dir ('/home/oracle/test/logs2/') {
deleteDir()
}
}
}
Looks like there are some comments that solve the problem for you, but no one mentioned that you can control the output of sh commands through the command itself.
The sh command has some optional parameters that can be used; one of them is returnStdout. In your case, you can suppress stdout like this:
stage('Logs Cleanup') {
steps {
script {
sh script: 'rm -rf /home/oracle/test/logs1/* /home/oracle/test/logs2/*', returnStdout: false
}
}
}
There are some other useful parameters, for example returnStatus will return the status code of the command for use in the pipeline.
I'm executing this code:
node('my_windows_slave') {
sh 'ls'
}
In my Windows slave I can properly execute sh command:
But the pipeline script can't run the .sh file:
[Pipeline] sh
[D:\workspace\sandbox_pipeline] Running shell script
sh: D:\workspace\sandbox_pipeline#tmp\durable-2d7dd2f8\script.sh: command not found
What I could notice is that this .sh file is not even created, once I tried with bat and worked fined.
Any clue what could be the problem?
[UPDATE]
Jenkins somehow can't create the SH temporary file. Already checked the log, permissions, everything that came to my mind.
I will leave my workaround as an answer for while before approve it once I'm still not 100% sure about the root cause and might someone else show up with a elegant solution...
def shell(command) {
return bat(returnStdout: true, script: "sh -x -c \"${command}\"").trim()
}
Attention
You still executing SH commands in a CMD, it means some %d for example can break your SH command.
Use the bat step instead of sh.
From Jenkins docs:
Windows-based systems should use the bat step for executing batch commands.
I have having trouble chaining scripts in npm. I am using webpack, running a build script then would like to run a bash file after. Both commands are working, but not if chaining them.
In my package.json I have this:
"scripts": {
"build-staging": "webpack --config webpack-staging.config.js -p || ./build-staging.sh"
},
If I run npm run build-staging it webpack runs the build and works fine. It does not run my build-staing.sh however. If I manually run this bash file it runs, so my issue is having it chain and run after the webpack script is finished. I've seen that the pipe || should do this, but no luck.
Am I doing the pipe wrong, or does the bash script not run because webpack does not 'kill' the script once finished? I am not able to run any more commands unless I use Crtl+C, maybe that's the issue?
Thanks!
|| is only used to run a program if the previous command failed (returned a non-zero status).
$ bash -c "exit 0" || echo "This won't run"
$ bash -c "exit 1" || echo "This will run"
This will run
$
If you want your second script to run regardless, you could use
"scripts": {
"build-staging": "webpack --config webpack-staging.config.js -p ; ./build-staging.sh"
},
Or if you only want it to run on success (which is more likely), you could use && instead of ||. Note that ; may not be supported by your platform. As mentioned in the comments, ; doesn't work on Windows, but && does.
I am using the scripts feature of npm to conveniently start my service by typing npm start. In my package.json file, I have this:
{
...
"scripts": {
"start": "NODE_PATH=. node index.js",
....
}
}
The NODE_PATH is the troublesome part. I do this so I can write in my javascript files: require('lib/mymodule'); instead of require('../lib/mymodule'); or some variant. There is a different syntax for setting an environment variable for a command on Windows. It would be cmd /C "set NODE_PATH=. && node index.js".
How can I accomplish running the right start command based on the operating system?