Mongo --quiet Not Suppressing --eval output - javascript

I'm writing this script that takes in t and uses it in test.js. I'm going to have the output be emailed to me and my collegues.
% mongo my_db --eval 't=9999;' --quiet test.js
9999
------------------------------------------------
Info about stuff going back 9999 days to 2012-08-17.
------------------------------------------------
Stuff x: 433321 (12.43%)
Stuff y: 2723426 (81.57%)
Total: 4524524524
Is there a way to not have what I pass in to --eval be outputted to console so I don't have that dangling '9999' at the top of my results?
Edit: This may be a bug with the --quiet option
See:
https://jira.mongodb.org/browse/SERVER-4391

Bit of a hack, but until that bug gets fixed you could just pipe to tail +2 first and that would exclude the output you do not want, something like:
% mongo my_db --eval 't=9999;' --quiet test.js | tail +2
This worked for me in a quick test to leave out the 9999 line.

Just in case anybody stumbles over this issue. I had the same problem and got an answer on that solves the problem without shell magic:
Use result from mongodb in shell script

I realize it has been a while. Posting a solution, hoping it might help someone who landed into this.
Prefixing a command with a void usually silences outputs.
For example, try:
$ mongo <server>/db script.js --eval 'void (yyyymm="2011-11")'
(NOTE: brackets are important)

Related

How to get Jenkins BUILD_NUMBER in JavaScript using GULP/NODE?

I have a gulp task getBuildNumber which uses Child Process to execute the script.
gulp.task('getBuildNumber', function() {
var buildNumber = child_process.execSync("echo $BUILD_NUMBER").toString().trim();
console.log(buildNumber);
});
When I run the following command for gulp
npm run gulp -- getBuildNumber
I always get the output as $BUILD_NUMBER and not the actual Jenkins build number.
Can someone please suggest on how to proceed with this?
You can access environment variables with process.env.
For example:
console.log(process.env.BUILD_NUMBER);
According to https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback, you need to escape special characters:
exec('echo "The \\$HOME variable is $HOME"');
In your case, this means you'd need to use
[...]child_process.execSync("echo \\$BUILD_NUMBER").toString().trim();[...]
^^

Detect Browserify broken build before committing/deploying

I'm using Browserify to bundle up my JS before pushing to my Bitbucket repo, and then using Codeship to test the build and push to Heroku.
I'm using Node/Express to serve my app, and in my index.jade I have a <script /> pointing to /dist/index.js.
A couple of times, I've mistakenly pushed my latest code with broken Browserify output, ie. the contents of /dist/index.js will be:
console.error('cannot find module XYZ')
And I've deployed this to my live app. UH OH.
I've put in a very rudimentary test which gets ran on Codeship which I'm hoping should avoid this in the future:
var exit = function() {
process.exit(1)
}
var success = function() {
process.exit(0)
}
var fs = require('fs')
var index
try {
index = fs.readFileSync(__dirname + '/../public/dist/index.js', 'utf-8')
} catch (e) {
exit()
}
if(!index){
exit()
}
var invalid = index.length < 1000
if(invalid){
return exit()
}
success()
I'm just checking if the file exists, and that the contents of the file is over 1000 characters.
Not sure if there's a specific answer to this, but would be a reasonable approach to making sure broken Browserify output never gets committed/deployed?
I haven't used Codeship before, but I have used other similar services. You haven't described how you push - I'm going to assume you're using git.
With git, this becomes easy: write a pre-push hook that will abort the push if something fails. Here's an example from a project I'm working on:
#!/bin/bash
# the protected branches
#
protected_branches='develop master'
# Check if we actually have commits to push
#
commits=`git log #{u}..`
if [ -z "$commits" ]; then
exit 0
fi
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
# is the current branch in the list of protected branchs? if so, then run the
# tests
#
if grep -q "$current_branch" <<< "$protected_branches"; then
# move into the dir containing the tests
#
pushd $(git rev-parse --show-toplevel)/contract >/dev/null
gulp test
RESULT=$?
# back to whatever dir we were in before
#
popd >/dev/null
if [ $RESULT -ne 0 ]; then
echo "-------- Failed Tests"
exit 1
fi
fi
exit 0
This is a modified version of a script I found in this blog post.
Basically, this script checks to see if I'm pushing one of the protected branches and, if so, runs my tests. If those test fail, then the push is aborted.
You could, of course, change the conditions under which the push is aborted. For example, write some code to check & see if your browserify bundle is correct and fail if it's not. You mention checking the length of your bundle - maybe something like length=$(ls -l | cut -c 30-34) and then check the value of length (sorry, I'm not a real bash guru).
The benefit of this approach is that the messed up code never leaves your local machine - you run the test locally and if it fails, the code doesn't get pushed. This is likely to be faster than running in on Codeship's service.

Bulk fix missing semicolons that JSHints finds in project

I have a project of 100+ javascript files each with 1-5 missing semicolons according to JSHint (as a result multiple people working on the project with different conventions).
I'd like to bulk fix everything as it's not practical to fix each individually. I've found this: https://github.com/jshint/fixmyjs but I don't see a way only fix semicolons without 'fixing' other things (tabs -> spaces, for example).
Does anyone know of way to do this? I'm comfortable with the possibility that it might cause breakage/introduce bugs. I've look over the errors and they look pretty routine.
I really hope you like this as a solution. Be vary careful that you verify with jshint again after you've fixed the issues. And out of curiosity, how did you manage to get so many broken javascript files?
#!/bin/sh
function fixFile {
for i in `jshint $1 | grep -i "Missing semicolon" \
| sed -e 's/\([^0-9]*\)\([0-9]*\)\(.*$\)/\2/'`;
do
sed -i $1 -e $i's/\(\s*\)$/;/'
done
}
fixFile $1
The above uses jshint to produce some error lines, greps them for the missing semicolon errors only, extracts the line number of each error, then seds the file in place on that line to remove any trailing whitespace and replace it with a semicolon.
The file...
var a = 5, c = 4
function helloWorld() {
if (this == doesntmakesense)
console.log('hello' + 'world');
}
console.log(a+c);
console.log('finished')
...becomes...
var a = 5, c = 4;
function helloWorld() {
if (this == doesntmakesense)
console.log('hello' + 'world');
}
console.log(a+c);
console.log('finished');
Where petty semantic errors are ignored, and only semicolons treated.
I'd save the bash script as something like fixFile.sh and then run find . -name "*.js" -exec ./fixFile.sh {} \;
But please commit beforehand. All commands are run at your own risk ;)
There is a safer way of adding missing semicolons than using regular expressions. Use the following steps to configure fixmyjs to only fix semicolons as originally asked by Evan:
Install fixmyjs
npm install fixmyjs -g
Create a fixmyjs config file fixmyjs-config with the following content
{ "asi": false }
Run fixmyjs
fixmyjs --config [fixmyjs-config] --legacy yourfile.js
Reference: https://github.com/jshint/fixmyjs/issues/86
Google Closure JS Linter has a program that comes with it, able to correct some of the more regular violations such as this one I believe, it's named fixjsstyle (python btw)

Console.log debug messages managing

My JS code is usually full of console.log() debug messages. Sometimes it is better to turn them off, or to turn off some part of them.
I can, for example, wrap console.log() statement in some function with conditions which are defined by some constants. Is it the best way to manage debug output or are more elegant alternatives?
Bunyan logging module is popular for node.js
Example code hi.js:
var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'myapp'});
log.info('hi');
log.warn({lang: 'fr'}, 'au revoir');
Output:
{"name":"myapp","hostname":"localhost","pid":40161,"level":30,"msg":"hi","time":"2013-01- 04T18:46:23.851Z","v":0}
{"name":"myapp","hostname":"localhost","pid":40161,"level":40,"lang":"fr","msg":"au revoir","time":"2013-01-04T18:46:23.853Z","v":0}
You can then filtering from command lines:
$ node hi.js | bunyan -l warn
[2013-01-04T19:08:37.182Z] WARN: myapp/40353 on localhost: au revoir (lang=fr)
Wrapping console.log into a function works well. But notice that there are also a lot of logging utilities out there for javascript. A little google on "js logger" may yield suitable results.
If you're using Node.js then debug is extremely effective as an alternative to console.log()
It's basically a substitute for console.log() except you can enable it at the command line with the DEBUG environment variable based on how you've initialized it in each file.
Let's say I have a project with a couple of files referenced from my index.js file:
one.js
var debug = require('debug')('one-one');
var func = function() {
debug('func');
}
two.js
var debug = require('debug')('one-two');
var func = function() {
debug('func');
}
You've initialized debug with the name "one-one" in the first file and "one-two" in the second file.
On the command line I can run them like this:
node index.js
Result: no debug output. However, if I run it like this:
DEBUG=* node index.js
The both the debug statements will get written out, however, in different colors and with the debug name (one-one or one-two) so I can tell which file they came from.
Now let's say you want to narrow it down a bit more. You could run:
DEBUG=*-two node index.js
To only get output from debug that's been set with "-two" at the end of the name or
DEBUG=one-* node index.js
to get everything starting with "one-"
You can also say that you want everything, or a set of things, or exclude patterns or sets. To exclude something you precede it with a dash, an example:
DEBUG=one*,monkey*,-monkey:banana,-elephant,-chimp:* node index.js
This will include everything starting with "one" or "monkey" and exclude anything called "monkey:banana", or "elephant" or starting with "chimp:"
If you wanted to exclude everything except then:
DEBUG=*,-pattern1,-pattern2 node index.js
JS logger is quite good and lightweight tool with flixible settings for log messages levels and several predefined logging levels (DEBUG, INFO, WARN, ERROR).

How to pass argument to Mongo Script

I've been using mongo and script files like this:
$ mongo getSimilar.js
I would like to pass an argument to the file:
$ mongo getSimilar.js apples
And then in the script file pick up the argument passed in.
var arg = $1;
print(arg);
Use --eval and use shell scripting to modify the command passed in.
mongo --eval "print('apples');"
Or make global variables (credit to Tad Marshall):
$ cat addthem.js
printjson( param1 + param2 );
$ ./mongo --nodb --quiet --eval "var param1=7, param2=8" addthem.js
15
You can't do that, but you could put them in another script and load that first:
// vars.js
msg = "apples";
and getSimilar.js was:
print(msg);
Then:
$ mongo vars.js getSimilar.js
MongoDB shell version: blah
connecting to: test
loading file: vars.js
loading file: getSimilar.js
apples
Not quite as convenient, though.
Set a shell var:
password='bladiebla'
Create js script:
cat <<EOT > mongo-create-user.js
print('drop user admin');
db.dropUser('admin');
db.createUser({
user: 'admin',
pwd: '${password}',
roles: [ 'readWrite']
});
EOT
Pass script to mongo:
mongo mongo-create-user.js
I used a shell script to pipe a mongo command to mongo. In the mongo command I used an arg I passed to the shell script (i.e. i used $1):
#!/bin/sh
objId=$1
EVAL="db.account.find({\"_id\" : \"$objId\"})"
echo $EVAL | mongo localhost:27718/balance_mgmt --quiet
2022 update:
when using mongosh you can read the execution arguments from process.argv
mongosh script.js param1 param2
// process.argv will be [.... , 'param1', param2']
the tricky bit is that mongosh will try to execute the parameters (e.g. param1 and param2) as additional scripts, but this can be prevented by ending the script using quit(). (TBH, I'm not sure it's by design / intended / documented)
I wrote a small utility to solve the problem for myself. With the mongoexec utility, you would be able to run the command ./getSimilar.js apples by adding the following to the beginning of your script:
#!/usr/bin/mongoexec --quiet
Within the script, you can then access the arguments as args[0].
https://github.com/pveierland/mongoexec
I solved this problem, by using the javascript bundler parcel: https://parceljs.org/
With this, one can use node environment variables in a script like:
var collection = process.env.COLLECTION;
when building with parcel, the env var gets inlined:
parcel build ./src/index.js --no-source-maps
The only downside is, that you have to rebuild the script every time you want to change the env vars. But since parcel is really fast, this is not really a problem imho.

Categories

Resources