Get path to first called/started module by node command - node.js

How to get path to directory where 'first called module' is?
For example we have bash file called startnode.sh in /bin/ folder
node ~/path/to/file/index.js
now in index.js we have complex code with requiring other files like:
var myMoudle = require("./module.js");
etc. Now we are in random folder: /qpa/dir/ then going to start our node process by bash file:
startnode
and in our module.js we going to get working directory:
console.log(process.cwd());
suprise! process.cwd() return /qpa/dir/ instead of ~/path/to/file/
why?
I need the directory where node process begin, directory to first called module.

Use env variables:
consider following structure:
test
├── bin.sh
└── test
└── hello.js
in bin.sh:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" node BASE_PATH/test/test/hello.js
in hello.js:
console.log(__dirname); // BASE_PATH/test/test
console.log(process.env.DIR); // BASE_PATH/test
console.log(process.cwd()); // BASE_PATH
note: you need to replace BASE_PATH with your path (~/path/to/file/)

Related

How to run FZF in vim in a directory where the directory path comes from a function?

I'd like to run fzf file finder (inside vim) on a custom directory, but the directory name varies at runtime.
For e.g., say, vim is started at the root of project directory. The subdirectories look like:
$ tree -ad
.
├── docs
├── .notes
│   ├── issue_a
│   └── new_feature
├── README
├── src
└── tests
Every time I create a branch, I also create a directory in .notes/BRANCH_NAME where I store notes, tests results, etc. The .notes directory itself is ignored by git.
I'd like to run FZF on the .notes/BRANCH_NAME directory. The branch name will come from a function (say using https://github.com/itchyny/vim-gitbranch).
I am able to run fzf on the .notes directory by :FZF .notes, but I don't know how to run it on the branch directory within .notes.
Thanks!
Edit: Added what I'd tried:
I tried saving the output of gitbranch#name() to a variable and then use it to call fzf#run(), but didn't quite work:
function! NotesDir()
let branch=gitbranch#name()
let ndir=".notes/" . branch
call fzf#run({'source': ndir})
endfunction
command! NotesDir call NotesDir()
When I run :NotesDir while on branch issue_a, I see fzf window with an error:
> < [Command failed: .notes/issue_a]
.notes/issue_a indicates that ndir variable has the correct notes directory path, but I couldn't figure out how to pass it to fzf.
Looking at the documentation for fzf#run(), it looks like source could be either a string, interpreted as a shell command to execute, or a list, used as-is to populate the plugin's window.
So your mistake was passing a path as source, which was interpreted as an external command, instead of either an external command or a list of paths.
It also says that you should at least provide a sink but some examples don't have it so YMMV.
If I am reading that section correctly, the following approaches should work:
" with a string as external command
call fzf#run({'source': 'find ' .. ndir, 'sink': 'e'})
" with a list
let list = globpath('.', ndir, O, 1)
\ ->map({ _, val -> val->fnamemodify(':.')})
call fzf#run({'source': list, 'sink': 'e'})
NOTE: I don't use that plugin so this is not tested.

How to unzip archive directly into target folder without creating a subfolder with the archive name (7zip, command line)?

I'm using the 7zip command line interface to extract archives, like so:
7za.exe x -y {path_to_zipfile} -o{path_to_target_folder}
If my zipfile is named my_archive.7z, then I get the following filestructure in the target folder:
🗁 target_folder
└─ 🗁 my_archive
├─ 🗋 foo.png
├─ 🗁 bar
│ ├─ 🗋 baz.txt
│ └─ 🗋 qux.txt
...
However, I don't want the subfolder 🗁 my_archive. I'm looking for flags to apply on the 7zip command such that everything extracts directly in the target folder, without creating the 🗁 my_archive subfolder.
NOTES
I can't replace x with e because the filestructure shouldn't be lost (the e flag pushes all files to the toplevel).
I'm working on a Windows 10 computer, but the solution must also work on Linux.
I'm using the following version: 7-Zip (a) 19.00 (x64)
Some background info: I'm calling 7zip from a Python program, like so:
# Variables:
# 'sevenzip_abspath': absolute path to 7za executable
# 'zipfile_abspath': absolute path to zipped file (`.7z` format)
# 'targetdir_abspath': absolute path to target directory
commandlist = [
sevenzip_abspath,
'x',
'-y',
zipfile_abspath,
f'-o{targetdir_abspath}',
]
output = subprocess.Popen(
commandlist,
stdout=subprocess.PIPE,
shell=False,
).communicate()[0]
if output is not None:
print(output.decode('utf-8'))
I know I could do all kinds of things in Python after the unzipping has finished (move/rename directories, etc etc), but that's for plan B. First I want to check if there is an elegant solution.
I'd like to stick to 7zip for reasons that would lead us too far here.
You can rename the top level folder to match the target folder before extracting the archive.
7za rn {path_to_zipfile} my_archive target_folder
This will permanently change the archive. If you don't want that, take a copy first.

os.path.exists() return False for filename with directory path which is created by ln(Ubuntu)

I have one filename with directory name which is solflink to another directory. os.path.exists(file) return False.
What's the right way to check if file exists?
If the directory structure looks like this:
.
├── bar -> ./foo/
└── foo
└── test.txt
os.path.exists returns True, as expected.
import os
print(os.path.exists('./bar/test.txt'))
# True
It seems you are confirming a directory's exist, not file. I think subprocess module can help you.
import subprocess
command = 'ls {}'.format(your_path)
print(subprocess.call(command, shell=True))
This will run ls command on linux and get returncode, if returncode is 0 means run command sucessfully which means your ln file exist.

npm glob pattern not matching subdirectories

In my package.json, I have a scripts block that uses **/*Test.js to match files. When run via npm, they do not match sub-directories more than one level. When executed on the command line directly, they work as expected.
Can anyone explain what is happening, and provide a workaround or solution?
package.json
{
"name": "immutable-ts",
"scripts": {
"test": "echo mocha dist/**/*Test.js",
}
}
Execution
% npm run test
> immutable-ts#0.0.0 test:unit .../immutable-ts
> echo mocha dist/**/*Test.js
mocha dist/queue/QueueTest.js dist/stack/StackTest.js
% echo mocha dist/**/*Test.js
mocha dist/queue/QueueTest.js dist/stack/StackTest.js dist/tree/binary/BinaryTreeTest.js
% ls dist/**/*
dist/collections.js dist/queue/QueueTest.js dist/tree/binary/BinaryTree.js dist/immutable.js.map dist/stack/Stack.js.map dist/tree/binary/BinaryTreeTest.js.map
dist/immutable.js dist/stack/Stack.js dist/tree/binary/BinaryTreeTest.js dist/queue/Queue.js.map dist/stack/StackTest.js.map
dist/queue/Queue.js dist/stack/StackTest.js dist/collections.js.map dist/queue/QueueTest.js.map dist/tree/binary/BinaryTree.js.map
Solution
Change your scripts so that what you pass to Mocha is protected from expansion by the shell:
"scripts": {
"test": "mocha 'dist/**/*Test.js'",
}
Note the single quotes around the parameter given to mocha.
Explanation
This issue is fixable without resorting to external tools. The root cause of your problem is that by npm uses sh as the shell that will run your script commands.
It is overwhelmingly the case that when a *nix process starts a shell it will start sh unless there is something telling it to do otherwise. The shell preference you set for logins does not constitute a way to "tell it otherwise". So if you have, say, zsh as your login shell, it does not entail that npm will use zsh.
Those implementations of sh that do not include any extensions beyond what sh should provide do not understand the ** glob in the way you want it to. As far as I can tell, it is interpreted as *. However, Mocha interprets the paths passed to it using its a JavaScript implementation of globs. So you can work around the issue by protecting your globs from being interpreted by sh. Consider the following package.json:
{
"name": "immutable-ts",
"scripts": {
"bad": "mocha test/**/*a.js",
"good": "mocha 'test/**/*a.js'",
"shell": "echo $0"
}
}
The shell script is just so that we can check what shell is running the script. If you run it, you should see sh.
Now, given the following tree:
test/
├── a.js
├── b.js
├── x
│   ├── a
│   │   ├── a.js
│   │   └── b.js
│   ├── a.js
│   └── b
│   └── a.js
└── y
├── a.js
└── q
With all a.js and b.js files containing it(__filename);. You get the following results:
$ npm run bad
> immutable-ts# bad /tmp/t2
> mocha test/**/*a.js
- /tmp/t2/test/x/a.js
- /tmp/t2/test/y/a.js
0 passing (6ms)
2 pending
$ npm run good
> immutable-ts# good /tmp/t2
> mocha 'test/**/*a.js'
- /tmp/t2/test/a.js
- /tmp/t2/test/x/a.js
- /tmp/t2/test/x/a/a.js
- /tmp/t2/test/x/b/a.js
- /tmp/t2/test/y/a.js
0 passing (5ms)
5 pending
You can inline the find command with the -name option in your scripts to replace the extended globbing syntax provided by zsh.
In your case, the command would be:
mocha `find dist -type f -name '*Test.js'`
You can realistically omit the -type f part if you're confident that you won't ever put "Test.js" in a directory name. (A safe assumption, most likely, but I included it for completeness sake)
The glob expansion is actually done by your shell and that's why it works from the command line.
You can do mocha --recursive and point at your test directory.

autoconf: use AS_INIT_GENERATED to generate a script in a subdirectory

How can I use AS_INIT_GENERATE to generate a script that is not in the same directory as the configure script, in particular so that VPATH builds will be honoured?
For example, for a configure.ac file containing
AC_PREREQ([2.68])
AC_INIT([example],[0.1])
AS_INIT_GENERATED([src/file.sh]) || AS_EXIT
AC_OUTPUT
running the commands
~ $ autoreconf .
~ $ mkdir build && cd build
~/build $ ../configure
results in the error message
../configure: line 1648: src/file.sh: No such file or directory
../configure: line 1655: src/file.sh: No such file or directory
I guess I'd have to make sure that the src directory exists before I call AS_INIT_GENERATE to create src/file.sh, or maybe I'm doing it all wrong?
Try something like this:
AC_PREREQ([2.68])
AC_INIT([example],[0.1])
test -d src || AS_MKDIR_P([src]) dnl <----- Create 'src' if it doesn't exist.
AS_INIT_GENERATED([src/file.sh]) || AS_EXIT
AC_OUTPUT

Resources