13

I've got a bare repository from which we start new projects. Inside this repository is another repository that has to be updated seperately. Every project starts with these two repositories, but sometimes during the project they should not both be updated.

I'm trying to create an Npm script that clones the parent repository, after that it opens the folder and clones the child repository.

The script has a variable that represents the project and thus folder name.

Based on this answer, I came up with the following:

"new_project": "git clone x:/parent_repo $PROJECT & cd $PROJECT & git clone x:/child_repo"

I run the command like so: PROJECT=new_project_name npm run new_project Have also tried PROJECT="new_project_name" npm run new_project

Unfortunately this creates a folder named $PROJECT in stead of actualy reading the variable.

Also tried:

"new_project": "git clone x:/parent_repo $PROJECT & cd $PROJECT & git clone x:/child_repo"

npm run new_project --PROJECT new_project_name

or run with

npm run new_project -- --PROJECT=new_project

Same result.

Most of these sollutions seem to work on linux machines but not for Windows.

It appears the variables in the string are not being read as such. I tried

"git clone x:/parent_repo "+$PROJECT+" & cd "+$PROJECT+" & git clone x:/child_repo" 

But that just gave me syntax errors.

How do I succesfully pass a variable from the command line that I can use in my npm script?

The command has to be a single line.

I'm using Git bash on windows as cli

npm version: 2.14.20

Community
  • 1
  • 1
timo
  • 2,119
  • 1
  • 24
  • 40

3 Answers3

11

So, the answer I linked which was not working, seemed to fail on my machine because of a difference in operating systems.

This works on Linux:

"new_project": "git clone x:/parent_repo $PROJECT & cd $PROJECT & git clone x:/child_repo"

PROJECT=new_project_name npm run new_project

To get this to work on Windows, you need to escape the variable with % % in stead of $. Also you need to specificaly SET the variable on the windows cli. To combine with the script, you need to link the script and the set variable command with &&.

So the above on Windows becomes:

"new_project": "git clone x:/parent_repo %PROJECT% & cd %PROJECT% & git clone x:/child_repo"

SET PROJECT=new_project_name && npm run new_project

Also note, if you want to refer to the config variables you have to escape that variable in the same way. So $npm_package_config_yourvariable becomes %npm_package_config_yourvariable% on Windows.

Community
  • 1
  • 1
timo
  • 2,119
  • 1
  • 24
  • 40
  • 1
    In Windows it seems `SET` to use a variable, but how I can use this variable... This simple code doesn't work: `SET APPVERSION=%npm_package_version% && echo App Version = $APPVERSION`. I tried with $APPVERSION and %APPVERSION% and no one works. – Gabrielizalo Dec 29 '19 at 01:21
  • @Gabrielizalo is should be `%APPVERSION%` but I'm not sure if you can set a variable with another variable i.e. `%npm_package_version%` – timo Dec 30 '19 at 10:24
  • in npm version >6 this has stopped working. not sure why, or how to resolve variables in npm-scripts on windows now... :( – Superole Jul 06 '22 at 11:09
5

You can use the package.json config.

{
    "name" : "myapp",
    "config" : { "folder": "myfolder" },
    "scripts" : {
        "new_project": "git clone x:/parent_repo $npm_package_config_folder & cd $npm_package_config_folder & git clone x:/child_repo"
    }
}

Then :

npm config set myapp:folder mynewfolder

npm run newproject

But in my opinion, the better way is to use an external NodeJS custom script and run it with a npm script.

Maxime Gélinas
  • 2,202
  • 2
  • 18
  • 35
  • 1
    I came across this as well. But having a single command for this action is mandatory. Could you elaborate on how you would use an external NodeJS custom script for this functionality? – timo Sep 30 '16 at 14:56
  • Like that `npm config set myapp:folder mynewfolder && npm run newproject`? What do you want to do exactly? With more info I could elaborate a better solution for you. – Maxime Gélinas Sep 30 '16 at 16:29
  • I'm trying to clone a repository into a folder with a custom folder name, after that process is completed I want to open that folder and clone another repository inside the cloned repository folder. This second repository does not require a custom folder name. I'm want to achieve this with a single command. Your sollution works, but requires two seperate commands. – timo Oct 03 '16 at 12:24
  • 1
    I think git submodule can be a better solution for you. The second repo will be cloned automatically in the first one when you will clone the first one. So one command. The submodules are the official way to clone a repo inside another. – Maxime Gélinas Oct 03 '16 at 16:11
  • 1
    Actualy, your original solution does not appear to work either. This seems to be Windows specific. `$npm_package_config_folder` is interpreted as string on Windows. – timo Oct 04 '16 at 13:54
  • Nice idea, but OS specific as well. – barfuin Nov 19 '18 at 11:11
  • If you do the node script suggestion, you can import package.json. This works on windows: ``const pk = require("./package.json"); const folder = pk.config.folder;``. Just run the git clone as a execSync. – JonShipman Jul 02 '21 at 19:43
2

If you look at the following page: https://github.com/npm/npm/pull/5518 (it's on the answer you linked to)

"new_project": "git clone x:/parent_repo $PROJECT & cd $PROJECT & git clone x:/child_repo"

Then:

npm run --PROJECT new_project_name
zerohero
  • 593
  • 4
  • 15
  • 1
    That would be `npm run new_project --PROJECT new_project_name` and yields the same results. – timo Sep 30 '16 at 14:28
  • This appears to work on linux, but I don't know how to escape the variable on Windows. `$PROJECT` is interpreted as string on windows machines. – timo Oct 05 '16 at 07:39