Thank you so much for being or becoming a Locutus contributor!
Our main focus is the challenge of completionism, seeing how far we can take it, rainy Sunday afternoon hacking to allow for fun experiments such as running PHP code directly in Node.js
- Contributing Checklist
- Prerequisites
- Clone
- Install
- Code
- Build
- Test
- Commit
- Releasing
- Website Development
Here are a few pointers that could save us from disappointment, we'll try to keep it brief!
- By submitting a Pull Request you are giving Locutus permission to distribute your code under the MIT License.
- Even if you can push to
main
, all code changes should be done via a Pull Request. This way we can peer-review, and also GitHub Actions can check if the code adheres to our policies already before merging it intomain
. - Please adhere to our coding standards. Use
yarn lint
to check. - Locutus is self-contained, we don't use any dependency except for our own development. Hence you will only see
devDependencies
populated, anything else should be corrected. - Use
//
for comments instead of/*
- Please credit yourself in the function's header-comment:
(original by|reimplemented by|improved by|parts by|bugfixed by|revised by|input by): Your Name (https://your.url)
- If you are fixing bad behavior, or introducing new good ones, please add an
example
comment that would fail before your patch, and aresult
comment that passes after your patch, to the function's header-comment. We use these for website documentation, as well as to generate test cases that avoid regression going forward. There should already be a few ones there if you want to see how it's done. - If you are contributing performance upgrades, please provide proof via e.g. https://jsperf.com
- Please keep in mind that some obvious readability improvements are sometimes unwanted for performance reasons. For
example, we sometimes place similar
for
loops insideif
andelse
conditions for performance reasons, even though the code could be half the size if we put the conditions inside a single loop. If we didn't comment this so far, a PR for adding such a comment is very welcome however. - If you are adding a new function, please make sure to:
- include exactly one export with a named function,
module.exports = function functionName (param1, ...) {
- the file can contain more definitions (helper functions, classes, etc.), but is allowed to have only one export
- add header-comments as first thing in function's body. Minimal header-comment should consist of
// discuss at: https://locutus.io/<LANGUAGE>/<FUNCTION NAME>/
// original by: <YOUR NAME>
// example 1: <FUNCTION NAME>("foo")
// returns 1: "bar"
We use Yarn managed by Corepack. It's recommended to alias:
alias yarn="corepack yarn"
Unless you are a Core contributor, it's best to fork Locutus, and then clone your fork. Then you can freely change it, push it to GitHub, and then send us a Pull Request to review. Otherwise you can clone our origin:
# cd ~/code
git clone [email protected]:locutusjs/locutus.git
cd locutus
yarn
yarn website:install
Best start a new branch for your work. For instance
git checkout -b fix-serialize
Then hack in src/
, for example: src/php/var/serialize.js
.
Tip: If you use VSCode, consider starting it like code .vscode/locutus.code-workspace
, so that heavy generated files &
directories are excluded from your file tree and searches.
yarn build
yarn test
This first rewrites mocha test-cases based on example
and result
comments found in the functions' headers. This is
useful if you're changing the tests themselves as well.
If that's not needed as you're iterating purely on the implementation, here's a faster way of singeling out a function
like natsort
which re-uses an already generated Mocha test in Watch mode, so it gets executed as you change the
implementation file in src/
:
./node_modules/.bin/mocha \
--require babel-register \
--reporter spec \
--watch \
test/generated/php/array/test-natsort.js
As of v2.0.30 you can also write custom tests, an example can be found in
src/php/var/serialize.mocha.js
.
Aside from unit tests, you can also run functions inside web browsers, with Watching, via yarn browser:watch
. This
allows you to quickly iterate and see how your functions behave in browsers.
Tests passing? It's time to document your work in the unreleased section of our CHANGELOG.md
, so that you can bundle
it with your PR.
Now it's time to apply linting & formatting fixes, and report on unfixable issues:
yarn fix
Make changes if needed, until there are no more errors. Then commit, push, and send a PR on GitHub.
After PRs have been approved and merged it's time to cut a release.
Any Core contributor can let our GHA CI create an NPM release, by pushing a new version and Git tag, like so:
npm version patch -m "Release v%s" && git push --tags
Locutus does not adhere to Semver, so typically you would just use patch
level upgrades for changes. If we change
something dramatic to how Locutus works across functions (ship ESM, move to TypeScript, etc), that's when we'll involve
minor
and major
levels.
We keep the website in ./website
so it's easy to keep code and website in sync as we iterate. For those reading this
screaming murder, HashiCorp does this for all their
projects, and it's working well for them on a scale more impressive than ours.
Our website is built with Hexo. To install the prerequisites type yarn website:install
.
Even though the website is bundled with this repo, we treat it as a separate project, with its own package.json
. We
also try to avoid dependencies from the website straight to the main code base. Instead, any such dependency shall be
injected by a script.
Here's the flow that takes written functions to the website:
yarn injectweb
runssrc/_util/util.js
'sinjectweb()
methodinjectweb()
iterates over functions and parses them via the_load
and_parse
methods, specifically: the header comments that declare authors, tests, and dependenciesinjectweb()
then writes each function towebsite/source
. The code is written as the content. The other parsed properties are prepended as YAML front matter
Blog posts can be found in website/source/_posts
.
If you want to preview locally type yarn website:start
.
Any change to main
is deployed automatically onto GitHub Pages by CI.