How do I tar node modules in different directories? - unix

I want to cache node modules for each submodule. How can I do so? For example I have the following directory structure:
/test1/node_modules
/test2/node_modules
How do I tar each node module directory under the main directory so that I can then have a zip file with the following structure
/test1/node_modules
/test2/node_modules
edit
What I mean is that I want to get all the node_modules directories under the main directory. node_modules directory can be under directory test1 or test2 or test3. I want to get them all and zip them, maintaining the directory structure. So in the zip file they will be test1/node_modules, test2/node_modules
... but I also want a "catch all" solution... every node_modules dir should be in my tar.

Its not clear where you're blocked. Here is how I would do it:
Use 2 distinct commands, one to create, one to add:
# create my.tar
tar cf my.tar /test1/node_modules/*
# add second directory with tar uf
tar uf my.tar /test2/node_modules/*
If you have more than test1 & test2, but want to have all test dirs:
tar cf my.tar /test*/node_modules/
If you want every node_modules, then use a find command, piped to your tar command
find / -type d -name node_modules | xargs tar cf my.tar

Assume you have these node_modules
➦ tree ./
./
├── pack.js
├── test1
│   └── node_modules
│   └── a
└── test2
└── node_modules
└── b
4 directories, 3 files
You can use node script to pack files. /^test\d+/ means test1 test2 test3 etc.
'use strict';
const fstream = require('fstream');
const zlib = require('zlib');
const tar = require('tar');
const path = require('path');
const dist = path.join(__dirname, 'all.tgz');
fstream.Reader({
path: __dirname,
filter() {
return this.path === __dirname ||
path.relative(__dirname, this.path).match(/^test\d+/);
},
})
.pipe(tar.Pack({ fromBase: true }))
.pipe(zlib.createGzip())
.pipe(fstream.Writer(dist));
Run node pack.js and all node_modules directories will be in one file all.tgz.
vim all.tgz
" tar.vim version v29
" Browsing tarfile
" Select a file with cursor and press ENTER
/
test1/
test1/node_modules/
test1/node_modules/a
test2/
test2/node_modules/
test2/node_modules/b

Related

Deploying firebase functions with local depencies using firebase CLI

Setup
I have a monorepo setup with the following file structure:
├── functions
│ ├── src
│ └── package.json
├── shared
| ├── dist
| ├── src
| └── package.json
├── frontend
| └── ...
└── firebase.json
Approach 1 (failed)
./shared is holding TypeScript classes shared among the ./backend and ./frontend. Ideally, I want to reference the shared lib from the functions/package.json using a symlink to avoid that I have to re-install after every change to my shared code (where most of the functionality resides).
However, this does not work (neither using link:, nor an absolute file: path, nor an relative file: path)
// functions/package.json
...
"dependencies": {
"shared": "file:/home/boern/Desktop/wd/monorepo/shared"
...
}
resulting into an error upon firebase deploy --only functions (error Package "shared" refers to a non-existing file '"home/boern/Desktop/wd/monorepo/shared"'). The library (despite being present in ./functions/node_modules/) was not transferred to the server?
Approach 2 (failed)
Also, setting "functions": {"ignore": []} in firebase.json did not help.
Approach 4 (works, but lacks requirement a) see Goal)
The only thing that DID work, was a proposal by adevine on Github:
// functions/package.json
...
"scripts": {
...
"preinstall": "if [ -d ../shared ]; then npm pack ../shared; fi"
},
"dependencies": {
"shared": "file:./bbshared-1.0.0.tgz"
...
}
Goal
Can someone point out a way to reference a local library in a way that a) ./functions always uses an up-to-date version during development and b) deployment using the stock Firebase CLI succeeds (and not, e.g. using firelink)? Or is this simply not supported yet?
Here's my workaround to make approach 4 work:
rm -rf ./node_modules
yarn cache clean # THIS IS IMPORTANT
yarn install
Run this from the ./functions folder

How to compile multiple simple projects with GNU make

I am trying to implement various project from a programming book. My intention was to have each project exercise in its own folder and then have a makefile that compiles all of them with something like a make all. The folder structure is like this:
.
├── Makefile
├── bin
│   ├── prog1
│ ├── prog2
│ └── prog3
└── src
├── prog1
│ ├── Makefile
│ └── main.c
├── prog2
│ ├── Makefile
│ └── main.c
└── prog3
├── Makefile
└── main.c
I would like to learn how to set up such a structure. In particular the part where the top makefile visit all folders in src calls make there, and then copies and renames the executable into the bin folders.
Your layout schematic shows a makefile for each exercise, plus the top-level makefile that you seem actually to be asking about. It would be best for the top-level makefile to avoid duplicating the behavior of the per-exercise makefiles, as such duplication would create an additional maintenance burden for you. Additionally, it is likely that you will eventually progress to exercises involving multiple source files, and perhaps to some that have multiple artifacts to be built. This is all the more reason for each per-exercise makefile to contain everything necessary to build the exercise with which it is associated (into the exercise-specific directory), and for the top-level makefile to depend on those.
Following that scheme would leave a well-defined role for the top-level makefile: to perform the per-exercise builds (by recursively running make), and to copy the resulting binaries to bin/. This is not the only way to set up a system of cooperating makefiles, but it is fairly easy, and that will allow you to focus on the exercises instead of on the build system.
Let us suppose, then, that each individual exercise can be built by changing to its directory and running make, with the result being an executable in the same directory, with the same name as the directory. That is, from the top-level directory, executing cd src/prog2; make would produce the wanted executable as src/prog2/prog2. In that case, the top-level makefile needs little more than the names of all the exercises, and a couple of rules:
EXERCISES = prog1 prog2 prog3
BINARIES = $(EXERCISES:%=bin/%)
all: $(BINARIES)
$(BINARIES):
make -C src/$$(basename $#)
cp src/$$(basename $#)/$$(basename $#) $#
Note: that uses a feature specific to GNU's implementation of make to compute the names of the wanted binaries from the exercise names. I take that to be acceptable, since you tagged [gnu-make], but in any case, it is a convenience feature, not a necessity.
There are different ways to tackle this, but something like this should work for your example:
PROGS := bin/prog1 bin/prog2 bin/prog3
all: $(PROGS)
$(PROGS):
$(MAKE) -C src/$(#F)
mkdir -p $(#D)
cp src/$(#F)/main $#
.PHONY: clean
clean:
rm -f $(PROGS)
for t in $(PROGS); do make -C src/`basename $$t` clean; done
We define a list of targets (PROGS) we are to build. We say these targets are prerequisites of all and then we go ahead and define how they should be built, that is: we recursively descent into src/ plus filename part of the target to run make there. We create directory of the target to be sure it's there and copy main from the directory we've descended to the path of the target.
For a good measure, there is a clean target as well that removes all the PROGS and runs make clean recursively in src/.

zsh delete subdirectory with wildcard in path

For a directory structure of:
└── bar
├── first
│   └── tmp
└── second
└── tmp
I want to delete all tmp directories.
However,
rm -rf 'bar/*/tmp/'
does not delete the directory
ls bar/*/
still retrurns both tmp directories:
bar/first/:
tmp
bar/second/:
tmp
your problem here is the single quotes
rm -rf 'bar/*/tmp/'
if you remove them you'll be fine.
rm -rf bar/*/tmp
The reason for this is that single quotes in (most, if not all) shell languages indicates that the contained string of characters is to be treated entirely as a string, which ignores the globbing you are trying to do.

How to tar all files in current directory using tar but without inputing names of tar file and all files?

ENV:
macOS Sierra 10.12.6
Raw input(example):
.
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
└── f6.doc
0 directories, 6 files
In a test folder, there are 6 files.
Expected output:
.
├── all.tar
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
└── f6.doc
0 directories, 7 files
Trying and Problem
tar -cvf all.tar f1.md f2.md f3.md f4.txt f5.csv f6.doc
Though I get the result from the above method but I have to inputing all file names and the compressed file name, which is inconvenient. For example , I can select all files and right click, then choose compressed option without inputing all.tar (I don't mind the .tar filenames.)
Hope
command-line method without inputing specific file names.
In case you want all files, including those in the subdirectories (or if you have no subdirectories), you would run:
tar -cvf all.tar *
Then, bash would expand * into the list of all files in the current directory, including subdirectories.
In case you want only those files in the current directory, but NOT in the subdirectories, then you would have to use find, in a more complicated command. Let me know if this is the case for you, and I can take the time to find that combination of commands for you.

How do I write a yocto/bitbake recipe to copy a directory to the target root file system

I have a directory of 'binary' (i.e. not to be compiled) files and just want them to be installed onto my target root file system.
I have looked at several articles, none of which seem to work for me.
The desired functionality of this recipe is:
myRecipe/myFiles/ --> myRootFs/dir/to/install
My current attempt is:
SRC_URI += "file://myDir"
do_install() {
install -d ${D}/path/to/dir/on/fs
install -m ${WORKDIR}/myDir ${D}/path/to/dir/on/fs
}
I can't complain about the Yocto documentation overall, it's really good! Just can't find an example of something like this!
You just have to copy these files into your target rootfs. Do not forget to pakage them if they are not installed in standard locations.
SRC_URI += "file://myDir"
do_install() {
install -d ${D}/path/to/dir/on/fs
cp -r ${WORKDIR}/myDir ${D}/path/to/dir/on/fs
}
FILES_${PN} += "/path/to/dir/on/fs"
Take care that with a simple recursive copy, you will end up having host contamination warnings so you would need to copy with the following parameters:
do_install() {
[...]
cp --preserve=mode,timestamps -R ${S}${anydir}/Data/* ${D}${anyotherdir}/Data
[...]
}
As other recipes in poky do, or just follow the official recommendations to avoid problems with ownership and permissions.
For a recipe folder like this:
.
├── files
│   ├── a.txt
│   ├── b.c
│   └── Makefile
└── myrecipe.bb
You can use the following recipe to install it on a specific folder into your rootfs:
SRC_URI = " file://*"
do_install() {
install -d ${WORKDIR}/my/dir/on/rootfs
install -m 0755 ${S}/* ${WORKDIR}/my/dir/on/rootfs/*
}
FILES_${PN} = "/my/dir/on/rootfs/* "
I think it did not work for you becuase you forgot to add mode value, after "install -m",
see man page of install command:
https://linux.die.net/man/1/install
install -m [mode] src destination

Resources