-
Star
(349)
You must be signed in to star a gist -
Fork
(42)
You must be signed in to fork a gist
-
-
Save DarrenN/8c6a5b969481725a4413 to your computer and use it in GitHub Desktop.
# Version key/value should be on his own line | |
PACKAGE_VERSION=$(cat package.json \ | |
| grep version \ | |
| head -1 \ | |
| awk -F: '{ print $2 }' \ | |
| sed 's/[",]//g') | |
echo $PACKAGE_VERSION |
grep version package.json | awk -F \" '{print $4}'
Simple solution for both Mac and Linux: (works great even if there's multiple keywords version
in your package.json
)
awk -F'"' '/"version": ".+"/{ print $4; exit; }' package.json
To remove spaces I simply added the space to the sed expression, and removed the new lines
PACKAGE_VERSION=$(cat package.json|grep version|head -1|awk -F: '{ print $2 }'|sed 's/[", ]//g')
Simple solution for both Mac and Linux: (works great even if there's multiple keywords
version
in yourpackage.json
)awk -F'"' '/"version": ".+"/{ print $4; exit; }' package.json
Thanks! @maitrungduc1410, the faster and simpler solution!
Verified with time
:
$ time awk -F \" '/"version": ".+"/ { print $4; exit; }' package.json
To remove spaces I simply added the space to the sed expression, and removed the new lines
PACKAGE_VERSION=$(cat package.json|grep version|head -1|awk -F: '{ print $2 }'|sed 's/[", ]//g')
Given a package.json
containing
{
"private": true,
"version": "0.1.0",
"license": "MIT",
"scripts": {
"version": "echo $npm_package_version"
}
}
And the version attribute consists only of digits and periods
When executing - on both mac
or alpine
Linux - I've got
$ cat ./package.json | grep -m 1 version | sed 's/[^0-9.]//g'
0.1.0
Is there a way to get rid of either sed
or grep
? 🤔
Incredible, thank you.
used
grep '"version"' package.json | cut -d '"' -f 4 | head -n 1
and for anyone who seeks to use it in .gitlab-ci.yml, check the before_script section bellow:
build:dev:
stage: build:dev
variables:
NAMESPACE: "dev"
before_script:
- PROJECT_VERSION=$(grep '"version"' package.json | cut -d '"' -f 4 | head -n 1)
script:
- docker build --network host -f ./Dockerfile -t $CI_REGISTRY_IMAGE:$NAMESPACE-$PROJECT_VERSION-$CI_PIPELINE_ID .
only:
- develop
tags:
- build_sv
Since npm 7.20, we have a simpler solution
npm pkg get version
The output is in JSON format with a double quote.
To remove it, use this
npm pkg get version | sed 's/"//g'
Awesome, @alvis! 😍
This is my new favourite! 👏🏼👏🏼👏🏼👏🏼👏🏼👏🏼
Since npm 7.20, we have a simpler solution
npm pkg get versionThe output is in JSON format with a double quote.
To remove it, use thisnpm pkg get version | sed 's/"//g'
When it comes to performance, do u happen to know if is it the same (or better) than
npm pkg get version | tr -d '"'`
? 🤔
@roalcantara You are asking if two commands that replace two bytes in a short string have different performance. This is talk of microseconds at best. If you really wonder about something, do a test. Here is the performance of the sole NPM command:
$ time command npm pkg get version
"0.0.1"
real 0m0.218s
user 0m0.156s
sys 0m0.050s
carlerik at carl-eriks-air in ~/dev/nimble/frontend (2978-vite-build)
$ time npm pkg get version
"0.0.1"
real 0m0.262s
user 0m0.154s
sys 0m0.055s
I ran it twice, as caching in the file system affects the result. The important bit is that the "user" and "sys" time is consistent: about 150ms of cpu time. That is JUST for invoking NPM.
Now, just see how the two other commands we pipe this into fares:
$ time (echo "0.0.1" | sed 's/"//g') > /dev/null && time (echo "0.0.1" | tr -d '"') > /dev/null
real 0m0.030s
user 0m0.001s
sys 0m0.009s
real 0m0.004s
user 0m0.001s
sys 0m0.003s
As you see, none of these commands take more than a single millisecond of cpu time.
I like @GuyMograbi approach = THANKS!
In
package.json
:"version": "0.0.1" "scripts": { "version": "echo $npm_package_version" }In a terminal:
npm run version
I don't see it mentioned anywhere in this thread, but in case it helps the Windows version of "echo $npm_package_version"
is "echo %npm_package_version%"
.
@tsulli Instead of making scripts that are OS dependant you can just use the fact that any version of NPM >= 7.20 can do this without any hackery: npm pkg get
will get any part of the structure you want, from root and down. No args, meaning the whole tree. npm pkg get version
will get you the version.
No need for
sed
orgrep
here. I solved the issue in a deploy script with
awk '/version/{gsub(/("|",)/,"",$2);print $2};' package.json
This actually captures EVERY version number in the file.
npx -c 'echo "$npm_package_version"'
unfortunately doesn't work in Windows.
I only could use npx -c 'node -p "process.env.npm_package_version"'
or
npm run get:version --silent
where "get:version": "node -p \"process.env.npm_package_version\""
npm run works a bit faster than npx.
Also I do not support to call script version
, because it will trigger also preversion and postversion scripts which many projects have
@fatso83 That npm pkg get version
command is unreliable, strangely dependent on whatever the current folder name is.
I have a folder named desk-app
the same as the name
field in my package.json
and it reports:
{
"desk-app": "1.0.4220"
}
Now if I rename the current folder to desk-app2
and run the same command (npm pkg get version
), I get:
"1.0.4220"
which is what I want here.
Not only does the first version introduce uncertainty in the process, but it actually changes the name of the field to the name of the app, instead of "version". This makes it usable to me. I'm still looking for a cross-platform that also works on windows.
For anyone else looking for a cross-platform solution (not reliant on Unix shell commands like grep/awk/sed) and local (without external dependencies), since it can be assumed that Node.js is installed, and it's already cross-platform for this, I just created a make_version.js
file with:
const PACKAGE_VERSION = require("./package.json").version;
console.log(`export const PACKAGE_VERSION = "${PACKAGE_VERSION}";`);
console.error("package.json version:", PACKAGE_VERSION);
and added a version
command to package.json
:
scripts: {
"version": "node make_version.js > src/version.js",
and then added:
"prebuild": "npm run version",
"prestart": "npm run version",
and it creates a new src/versions.js
on every start
or build
. Of course this can be easily tuned in the version
script to be a different location, or in the make_version.js
file to output different syntax and constant name, etc.
cat package.json | jq -r '.version'
works on github actions
cat package.json | jq -r '.version'
works on github actions
This is the best solution!
cat package.json | jq -r '.version'
works on github actionsThis is the best solution!
Not the best IMO because you need to install additional software for it to work (jq)
I'm with @bmerigan, jq
is not cross-platform or installed by default (and not available on Windows). This is why I ended up using that 3-line Node.js script, because it can be assumed that Node.js is installed here, and is cross-platform.
Well you're right, I should have been more precise: this is the best solution for my use case, because I'm using it in GitHub Actions, and jq
is installed by default.
awk -F'"' '/"version": ".+"/{ print $4; exit; }' package.json
This solution is greatest and can be suited for a special situation:
My package.json has more than one key element with "version" string.
any example that we can wrap any of the above solutions in a sh
command?
The goal for me is to extract the package.json version in a jenkinsfile.
@cmario92 my simple solution only had a dependency on Node.
It's easy to change the output node make_version.js > src/version.js
to be a different language or json file or append to a jenkinsfile etc.
@appurist npm pkg get version
will return different results depending on whether the project is configured inside a workspace or not.
Using your example, if the project is not in a workspace:
$ npm pkg get version
"1.0.4220"
If inside a project:
$ npm pkg get version
{
"desk-app": "1.0.4220"
}
You can use --workspaces=false
to turn off this behaviour and return a consistent result.
# If project is inside a workspace
$ npm pkg get version --workspaces=false
"1.0.4220"
Get the unquoted version string
If you're in a *nix-like environment (Linux, OSX, gitbash), then it's possible to use the tr
utility to trim the "
quote characters from the string.
Here the one-liner I use to get the unquoted version:
$ npm pkg get version --workspaces=false | tr -d \"
1.0.4220
You can assign to a variable (e.g. in a shell script):
LIB_VERSION=$(npm pkg get version --workspaces=false | tr -d \")
@appurist Thanks for picking up the typo, that's been updated now.
@Coridyn Thanks! That makes sense. So --workspaces=false
is in fact what I was looking for. In some ways have the small bit of node.js code is simple and more stable for the long term, or at least less likely to ever be a problem unless we change it, but it's great to know how to actually use pkg get version
in a consistent manner too. Thanks for that bit of info. I'll probably switch to that at some point, or at least for future projects.
I've registered the suggestion here for npm pkg get version --raw
npm/cli#5508
npm pkg get version
That returns "0.1.0" unlike "version": "echo $npm_package_version"
You are chastising the answer saying it's OS dependent, but then with npm pkg get version
how would you strip the quotes in an OS independent way?
BTW "version": "echo $npm_package_version"
and then yarn version
works in Linux AND Windows (PowerShell and even CMD)
I combined all the examples mostly here but also elsewhere into one big page, no idea what is best, but if it's useful to someone:
https://gist.github.com/dezren39/d71e381a3c70ce8463a9471cd2983617