Welcome!
🎉👍 First, thank you for considering contributing to fse-cli
! 🎉👍
Table of Content
- Guidelines
- Roadmap
- Code Overview
- Prerequisites
- Development
We'd like to emphasize these points:
- Be Respectful
- We appreciate contributions to
fse-cli
and we ask you to respect one another.
- We appreciate contributions to
- Be Responsible
- You are responsible for your Pull Request submission.
- Give Credit
- If any submissions or contributions are built upon other work (e.g. research papers, open sourced projects, public code), please cite or attach any information about the original source. People should be credited for the work they've done.
This project is driven by the Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
Before each commit, a static analysis of the code is done with:
- typescript compiler,
- eslint.
Both must pass.
Moreover, even if it's not mandatory, it is expected this analysis will not rise any warning.
The project uses Semantic Versioning 2.0.0.
The changelog file is updated with standard-version using Conventional Commits 1.0.0. See @commitlint/config-conventional
types.
By contributing to fse-cli
, you agree that your contributions will be licensed under its MIT license.
- add other functions from fs-extra
- add functions other than from fs-extra, e.g. tree-cli
- add i18n
This project uses:
- Typescript as far as possible, otherwise ES2018,
- Babel7 as compiler (°).
- ESLint and TSLint as static code analyzers,
- Npm as package manager,
- Docker to run tests locally with specific versions of Node.js.
(°) There are four TypeScript features that do not compile in Babel due to its single-file emit architecture, see §
It's not a perfect marriage
of TypeScript With Babel: A Beautiful Marriage.
Much documentation can be replaced with highly readable code and tests. In a world of evolutionary architecture, however, it's important to record certain design decisions for the benefit of future team members as well as for external oversight. This project uses Architecture Decision Records (ADR) for capturing important architectural decisions along with their context and consequences. They are gathered under folder ./doc/adr
.
Otherwise, below are some broad design rules.
Each main fs-extra
function is wrapped in a task
, each one with a dedicated sub-folder under src/tasks.
When a fse-cli <command>
is launched, only the required task is loaded through a dynamic import.
Aliases are defined in the associative array jobLinks
inside src/config.ts.
⚠️ Don't forget to update the sectionbin
of package.json for any change ofjobLinks
⚠️
Each task
is tested without duplicating fs-extra tests.
At the moment, CI/Build is splitted between:
- NPM publishing driven locally by Husky,
- Github releasing and publishing done with Github Actions.
A code analysis and a full test + build are done before each push on the github repository.
- Git
- Node.js - at least version 12.20
- Npm - comes with Node.js
- Npx - comes with Node.js
- Docker
- nvm - optional
and possibly:
The shell used here is Bash under Linux. However it should be straightforward to work under any other usual OS, see Cross Platform Concerns.
Check prerequisites' status:
npm doctor # show information about git, node, npm... for the current user
git --version
docker --version # check if BuildKit can be used, i.e. with Docker 18.09 or higher
nvm --version # required only if you need to install Node with at least version 12.20 or higher
npm list -g --depth 0 2>&1 | grep fse-cli # (°°)
(°°) replace
2>&1 | grep ...
by its counterpart under Windows, Mac OS, ... Or simply usenpm list -g --depth 0
and check iffse-cli
is present.
node --version ### check Node.js is installed with at least version 12.20
sudo npm uninstall -g @atao60/fse-cli ### if needed; required to avoid any issue with `npm link`, see below
git clone https://github.com/atao60/fse-cli.git atao60-fse-cli
cd atao60-fse-cli
npm install
npm run fullcheck ### Check if the app code is fine (°)
# npm outdated
# npm audit
# npx depcheck ### good to detect missing dependencies,
# but many false errors about unused dependencies such as e.g. runtime ones (tslib, @babel/runtime)
### `cost-of-modules` gives install time required for each package.
# npm run rimraf -- ./node_modules_bak && npx cost-of-modules
(°) The first time the timeout of 2s may not be enough. Just run again the full checking.
The main available scripts are:
npm start
- alias fornpm test
,npm test
- rerun build and test after any code changes and made them available throughnpm link
,npm run build
- create a production ready build,npm run commit
- commit, instead ofgit commit
,npm run release
- run test, lint and build before creating a new release version,npm run cli:publish
- publish on npm and github registries, instead ofnpm publish
,npm run clean
- remove temporary folders as dist, .build, ...npm run refresh
- remove node modules, package-lock.json, dist, ... and re-installs upgraded dependencies,npm run lint
- check of code,npm run fullcheck
- run test and lint,npm run analyse
- check dependencies and publish content.
It's also possible to iterate the tests over each main version of Node.js, using Docker:
./make.sh nodecheckall
.
Libraries such as graceful-fs and cross-spawn have been used to improve Windows support.
All the scripts in package.json are cross-platform, at least under Linux (Bash), Windows and Mac OS X.
To make sure your npm scripts work across different platforms, you cannot rely on environment specific tools. This can be solved by using a task runner to hide the differences. Alternately, you can use a collection of npm packages which expose small CLI interface. The list below contains several of them (src: survivejs.com):
- cross-env - Set environment variables.
- npm-run-all or concurrently - Running npm scripts in series and parallel is problematic as there’s no native support for that and you have to rely on OS level semantics. npm-run-all solves this problem by hiding it behind a small CLI interface. Example: npm-run-all clean build:*.
Not forgetting, of course...:
- cpy-cli - Copy files and folders.
- mkdirp - mkdirp equals to Unix mkdir -p which creates all directories given to it. A normal mkdir would fail if any of the parents are missing. -p stands for --parents.
- rimraf - rimraf equals to rm -rf which in Unix terms removes the given path and its contents without any confirmation. The command is both powerful and dangerous.
A special case here with rimraf: it can't be used under Windows to delete folder
./node_modules
. See the script./scripts/rmdir.js
.
npm start ### will rebuild and test after each code change
To ensure this package @atao60/fse-cli
is compatible with all major versions of Node.js, a Docker(°) image with the last release of each of them is used to run the tests:
./make.sh nodecheckall
The checked releases of Node.js are from 12 to last available one as long as a version compatible with ESM is available(°°).
(°) As soon as Docker is installed, some Bourne shell or compatible one should be available, allowing cross-platform running of
make.sh
.
(°°) Already reached EOL of Node.js' Releases are:
- 10: 30th April 2021,
- 13: 1st of june 2020,
- 15: 1st of june 2021.
As release 15 is compatible with
ESM
, it's not been removed from checking yet.
Don't forget to regularly check and clean up disk space used by Docker:
docker system df
anddocker system prune
are your friends here!
Create a symbol link in npm global installation and watch any changes:
cd <path to @atao60/fse-cli folder>
npm link ### or `npm install --global .`
# [...]
#
# audited 1025 packages in 6.743s
#
# 69 packages are looking for funding
# run `npm fund` for details
#
# found 0 vulnerabilities
#
# ~/.nvm/versions/node/v12.18.3/bin/fse -> ~/.nvm/versions/node/v12.18.3/lib/node_modules/@atao60/fse-cli/bin/fse
# ~/.nvm/versions/node/v12.18.3/bin/fse-cli -> ~/.nvm/versions/node/v12.18.3/lib/node_modules/@atao60/fse-cli/bin/fse
# [...]
# ~/.nvm/versions/node/v12.18.3/bin/fse-cli-move -> ~/.nvm/versions/node/v12.18.3/lib/node_modules/@atao60/fse-cli/bin/fse
# ~/.nvm/versions/node/v12.18.3/lib/node_modules/@atao60/fse-cli -> [...]/atao60-fse-cli
Try it from an other console (°), e.g.:
fse version
# @atao60/fse-cli 0.0.30 (fs-extra 9.0.1)
(°) In fact under any wished location, even under the folder of
atao60-fse-cli
itself.
Or try it as a dependency:
cd <path to the using project folder>
npm link @atao60/fse-cli
# <path to the using project folder>/node_modules/@atao60/fse-cli -> ~/.nvm/versions/node/v12.18.3/lib/node_modules/@atao60/fse-cli -> <path to atao60-fse-cli folder>
npm install -D @atao60/fse-cli ### (°°)
# npm notice created a lockfile as package-lock.json. You should commit this file.
# [...]
#
# audited 126 packages in 7.741s
#
# 72 packages are looking for funding
# run `npm fund` for details
#
# found 0 vulnerabilities
(°°) If the linked package has same version as one published on NPM Registry, then
npm install -D @atao60/fse-cli
will replace the link with a copy of the release undernode_modules
. Not what is expected.
When the link becomes useless, remove it:
cd <path to @atao60/fse-cli folder>
npm unlink ### or `npm uninstall --global .`
To get dependencies tree and packaging details:
npm run analyse
To get only first level production dependencies:
npm run analyse -- --depth=0 --prod
Don't use git commit
but npm run commit
:
- Stage modified files using:
git add .
- Commit the files using git-cz package:
npm run commit
Answer questions:
- Choose the type of the commit (feat, refactor, fix, etc.), see
@commitlint/config-conventional
types. - (Optional) Provide a scope.
- Provide a short description of the commit.
- (Optional) Provide a longer description.
- Determine whether the commit is a BREAKING CHANGES or not (by answering
y
and fill up BREAKING CHANGES descriptions in the CLI). - (Optional) Mention the issues in the issue tracking system, here Github issues, (by answering
y
and fill up the issue descriptions in the CLI).
Any change can be released and published as soon as committed. See below. But any uncommitted changes will prevent a release. On the other hand, a publishing can be done with uncommitted changes, ignoring them.
git branch ### checking if current user is in 'master' branch before creating a new one for pull request
# * master
git checkout -b my-branch
Do here the wanted changes.
git add --all
npm run commit
git push origin my-branch
Lastly open this branch on the Github fork and create a pull request.
Once the pull request merged, delete this branch.
See GitHub Docs - Checking out pull requests locally.
atao60/fse-cli
is published with a embedded npm-shrinkwrap.json expunged from dev deps. This is done through a "shrink" step before publishing. See `./tools/prepublish'.
Each release (i.e. a tag whose label begins with v
) is published on both NPM public registry and Github Packages registry.
To do it, you must be an administrator with access rights for:
- the package on the npm public registry, i.e. @atao60/fse-cli,
- the repository on Github, i.e. atao60/fse-cli,
- the API of Github, i.e. GitHub REST API.
At the moment:
- NPM Registry login is done manually,
- Github access is done automatically (see MS - GCMC below).
npm publish
but npm run cli:publish
Then:
git checkout master
git merge my-branch
npm run release # push a new version in `package.json` and a new tag with this version as label.
npm login
npm run cli:publish
npm logout
git branch -D my-branch
In fact the package on NPM public registry:
cd <your local repository for @atao60/fse-cli>
npm unlink @atao60/fse-cli ### remove existing link
cd <any suitable folder, even your local repository>
npm -g un @atao60/fse-cli ### to force access to the npm registry
npx @atao60/fse-cli version ### or any other fse-cli command
Microsoft Git Credential Manager Core is now available on Windows, Mac OS and Linux.
So @atao60/fse
uses it to hide project's Github secrets. A configuration file ./.gitconfig-gcmc
is provided to help doing it. It must be included either in ./.git/config
or in ~/.gitconfig
.