path in makefile not working - makefile

Im running the following makefile
which needs to change dir to specific target and run there npm install
The problem is that I was able to see in the output that it print the directory (project/app) to the right directory but the installation (npm install) run on level up (project), why ?
For example
When I run it I see from cd $(DIR)/app
/Users/i03432/go/src/project/app
Now the second command is
npm install
And I got error that id doesn’t find the package json in the project path which is right... it’s only in the app path. Why the cd is not working ?
it try to find it here
/Users/i03432/go/src/project/package.json
and here is the package.json
/Users/i03432/go/src/project/app/package.json
The makefile is
module:
DIR=$(PWD)
#echo $(DIR)
cd $(DIR)/app
npm install

Every command in a rule is run in a single process (sub-shell). Every change you perform on the environment is hence tied to that particular line. You want to change your snippet to
cd $(PWD)/app && npm install
This command runs in a single subprocess and should yield the desired result. Note that this problem occurs for the definition of DIR, too, so you might want to move this a few lines up:
DIR = $(PWD)
module:
cd $(DIR) && npm install
This way, you are referring to a variable that make provides, and you don't rely upon subprocesses here.

Related

build command need to be executed inside a specific named directory "./package" from child folder or parent folder script terminal (cd) loop or regex

how to write cd NAME_FOLDER and recursively search for it by name and then go to it if necessary (see below for more details).
the NAME_OF_FOLDER is unique so no worried about that.
but the challenging things are:
that it needs to search from the PARENT to the CHILD,
and if it didn't find it that way, search from CHILD to PARENT.
(or you can use any other logic if you think my logic is slow)
example folder
here is an example image of my folder:
possible scenarios
here are some scenarios:
if I am inside
./package -> don't run cd
./test -> cd ./package
./src -> cd ../ && cd ./package
./lib -> cd ../../ && cd ./package
and so on for every deep folder structure
docs:
../ means go from child to parent
./ means go from parent to child
why do I need it?
I am a javascript developer,
and I am using the sveltekit framework
to create a svelte package library.
and I need to publish that library to npm.
and this is ok.
but since I write a lot the same CLI codes.
I am changing the package.json's scripts object,
so I write only one time npm run build to run 6+ commands
{
...
"build": "
svelte-kit sync
&& svelte-package
&& npm version patch
&& cd ./package # only this I need to solve this (the others are solved)
&& npm publish
&& git commit
"
}
this is in one line, but for making you read it easily the code in multiple lines
here how it is in my code:
what does the build command should do?
the command generates a ./package folder always on the root of the folder
(where we can find package.json, .gitignore, ./src, etc...)
increase the number of versions automatically when we use the build command,
then... TODO:
do the script I need to access the ./package folder from every folder I am in now. (like cd ./package)
npm publish
my os?
windows 11 (but using bash with vscode) or also powershell will be good but prefer bash
any other details, I will tell you. thanks
For testing, I created this structure:
test/
package/
src/
lib/
routes/
Then I created that script:
#!/bin/bash
topdir="test"
while [[ $(basename "$(pwd)") != "$topdir" ]]
do
if [[ -d package ]]
then
cd package
pwd
else
cd ..
pwd
fi
done
if [[ -d package ]]
then
cd package
pwd
fi
This script "climbs" the directories until it finds a "package" directory. It the cd into it.
To use the script, you have to source it. If you execute it, it will change directories while the script is running, but it will not affect your current terminal.
So, lets assume the script is ~/bin/cd_package.bash
You would call it like this: . ~/bin/cd_package.bash
Note the pwd commands are just so you can follow what is going on and can be removed once you are convinced it works.

Which one is executed?

Please, how do I know which one of the available npm is executed when I do npm on cmd ?
e.g: npm init, npm install ...etc.
On windows, I'm executing : where npm and this is the output:
C:\Program Files\nodejs\npm.cmd
C:\Users\Me\AppData\Roaming\npm\npm
C:\Users\Me\AppData\Roaming\npm\npm.cmd
which one is the corresponding file ?
When you execute a command in cmd, the command is searched in the current directory and than in the directories given in the path environment variable. The same is doing the 'where' command if no options are used.
So the first match found by the 'where' command is the one which is actually executed.
If the match is found in the current directory, be aware that the result changes if your current directory changes.

Dynamic target for root or nested directory

My makefile contains a target for node_modules directory, which depends on package.json file:
node_modules: package.json
npm install && touch "$#"
My current project happens to have a "sub-package" with its own set of dependencies. I modify the target above to the following:
%/node_modules: %/package.json
cd $(shell dirname "$<") && npm install && touch node_modules
Now, I can do make path/to/subpackage/node_modules and make runs the expected npm install command. However, I no longer seem to be able to do make node_modules - make exits with status code 0 and message Nothing to be done for 'node_modules'.
This indicates make will now only run the appropriate command for node_modules folders which exist within a subdirectory.
How can I change the target so that it supports both nested and root node_modules directories within the same target?
In other words, I would like to remove the duplicated target definition because the command to make the root's node_modules directory is the same as the command to make the nested path/to/node_modules directory.
As research, I tried to look at the GNU Make tutorial but could not find any relevant information - possibly because I simply do not know what to look for.
It isn't very elegant, but you could use a "canned recipe":
define MAKE_NODE_MODULES
npm install && touch node_modules
endef
node_modules: package.json
$(MAKE_NODE_MODULES)
%/node_modules: %/package.json
cd $* && $(MAKE_NODE_MODULES)

How can I change directories in a homebrew formula?

I am trying to create my own homebrew formula using brew create and brew edit .
As part of the install for this project I need to change into a sub directory and build things there, for example
cd sub/dir/place
make -f makefile otherMakeTarget
I tried adding to my formula.rb
system "cd", "sub/dir/place/"
system "make", "etc"
But it doesn't seem to do the cd correctly. The logfile 01.cd shows the cd and the argument on two separate lines, I'm not sure if that's the problem.
Calling system creates a subshell and any modifications to the working directory go away when that call completes.
You could try using chdir:
Dir.chdir('sub/dir/place')
Another way to do it is to use a chdir block.
chdir "vendor" do
system "make", "install"
end

npm package.json bin won't work on Windows

I am trying to start my cli tool via the package.json bin property.
I have the following:
...
"name": "mycli",
"bin": "./bin/mycli",
...
When I open the cmd in the package path and type: "mycli" it says that the command is not recognized.
Should I run an npm command? or use the scripts property? am I trying to access the bin property incorrectly?
Try to specify the name of your cli tool in the bin property, like:
"bin": {
"mycli": "./bin/mycli" // or "/bin/mycli.js" if it's a .js file
}
Then, run npm link, from inside your project folder, to create a global symbolic link to the current folder.
Don't forget to add the "preferGlobal": "true" property just before the bin property in your package.json file, in order to warn users to install your module globally.
Whenever I was trying to get my app to link, I kept running into problems on Windows where the generated scripts that would execute on path would try to run the *.js file using the default Windows executable (I don't know what that would be). I'm not sure why. I think it might be because it is a JavaScript file. However, I compared the generated scripts to some of the other modules I had installed, and figured out that if I made the bin file referenced by the package.json act as though it were to be executed on a *nix machine, npm would automatically try and add the call to node.
For example:
If my package.json looks like this:
myapp/package.json
"name": "myapp",
"bin": {
"myapp": "./bin/myapp"
}
My referenced bin file looks like this:
myapp/bin/myapp
#!/usr/bin/env node
require("../server.js");
The 2 generated executable files that appear in %APPDATA%\npm show up as follows by running the command npm link from within the myapp directory (which would have package.json in the root):
myapp
#!/bin/sh
basedir=`dirname "$0"`
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/myapp/bin/myapp" "$#"
ret=$?
else
node "$basedir/node_modules/myapp/bin/myapp" "$#"
ret=$?
fi
exit $ret
myapp.cmd
#IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\myapp\bin\myapp" %*
) ELSE (
node "%~dp0\node_modules\myapp\bin\myapp" %*
)
Bear in mind, I didn't need to make the 2 files above explicitly, I just needed to have the file to be executed as the bin file in the package.json. npm did the file creation.
Line Endings
One other thing to note that I ran into while using this method, make absolutely sure that your line endings are correct. I noticed that my bin was erroring with: ": No such file or directory" whenever I installed on *nix machines because there was an incorrect line ending. Thanks to View line-endings in a text file for example of how to print visible line endings.
For example, if you run cat -e PATH_TO_BIN and get something like this:
#!/usr/bin/env node^M$
^M$
require("../index.js");^M$
You're using the wrong line endings. If you get something like this:
#!/usr/bin/env node$
$
require("../index.js");$
Those should be the right line endings.
If you put
#!/usr/bin/env node
in the first line of your script, npm will create the necessary wrapper scripts.
Answer from Rodrigo Medeiros works for me, but only if I have too the shebang line at the .js file.
There I had another issue. I have node.js installed at c:\Program files\nodejs, and this was my shebang line:
#!c:/program files/nodejs/node
This didn't work, because the blank space. This was the correct one:
#!c:/progra~1/nodejs/node

Resources