Code routines

Organization

A build matrix will show status info for each build platform, target and options for all the projects and publicly available at all times.

There will be no testing or release stage, but instead all commits will be tested, and merged on master if tests passes, having it always a clean, production-ready status. Releases will be published automatically using semantic-release. Nobody will have direct access to master branch except the CI servers, and will only accept fast-forward merges.

Having master branch protected, it doesn't matter if pull-requests come from branches or forks, so we'll allow both. In the future, maybe we restrict main repo branches to oficial ones and dictate all pull-requests come from forks to simplify management.

When master branch gets updated, all pull-requests and branches will be updated and re-checked. This will give to the developer the responsability that his code pass the tests, and also would help to maintain backwards compatibility. In case a backwards compatibility breakage happens, it could be moved to a next-major branch and merge changes there. Change of a major version needs to be discussed, but probably would happens when there's no open other non-breaking pull-requests changes.

Architecture

Architecture will be designed based on the usage of Fat clients, logic will be hosted by the client apps, being used the servers mostly to store data for billing and machine learning algorythms. Comunications with diferent platforms will be done directly by the clients, in case some server is needed for proxying or data conversion it will be powered by serverless services, Node.js PaaS or NodeOS instances.

Interchange and storage format will be based on JSON, and communications will be done using a REST and JSON-RPC APIs, both on HTTP, SSE or WebSockets.

App should try to integrate and use available host system services and data instead of replicate them (specially on mobile platforms), doing the conversion in real time. Being able to replace and integrate all the system communications, it should be able to be configured as the default app for diferent intents and URL schemes handlers, but also check and update the system info in case in some moment the application is not being used. It could also be able in the future to do other tasks like launch system apps (UnifyOS, like Facebook mobile OS layer).

Code style

Code will follow BSD style (i.e. opening brackets on new line, where aplicable), without semi-colons (where aplicable), 80 columns, tabbed to two spaces, one whiteline between methods and functions and two between sections. Otherwise that, code must follow best practices and widely accepted community standards, and in doubts use Python PEP-8 guidelines as reference (when aplicable). This is done this way to improve legibility. Also when possible advanced languages features will be used (for example map(), filter() or reduce() instead of plain for loops if it doesn't affect performance or can allow them to be put on external clossures). Another good style reference is Google Python style.

All files newlines will by in UNIX format (\n).

Design clean APIs

APIs should be minimalist and expose only public methods and attributes, both on the constructor and prototype chain, making inaccessible any internal and/or private state. Tests must be done ONLY against the public API, if some internal state it's needed to be accesible for testing or by some child class, it will be done accesible by using an underscore-leaded non-writable and non-enumerable property, to prevent it of being used by accident on regular production code. In more advances cases where they need to be set (for example, doing dependencies injection to mock internal objects during testing), consider doing so by using optional arguments or an options bag argument object, so they don't need to be explicitly defined for the most basic cases. Don't break previous API usage of the simple and default cases except if some of their required arguments can be considered optional in some other simpler use cases (so they are not the most simple and basic usage anymore).

Modularize everything

Use and create reusable modules and components. Before writting your own one, investigate first if there's some actual library or module that does what you want to achieve with no changes or with minimal improvements, specially if it does a complex task or has good community reputation (high number of stargazers on Github or downloads on npm) or a good code quality.

Clearly identify and isolate what's bussiness model and what can be written and freely distributed and used by others as a generic and standalone project. Don't overdesign on a first take, but if you see something on the source code that can be extracted and refactored in a more generic, reusable and abstract way, also in simple cases like duplicated code, don't hesitate and go for it.

If some internal component needs to be accesed just for debugging purposses, consider about how to publish it on the public API in a more generic way in case it could be useful in some other legit use cases, or better than that, move it to its own module or package making it a lower level public API (and doing so, with its own tests too).

Document everything

README.md file should have a minimal purposse and usage info of the project itself with some examples, like suggested at Feed me readmes. This must have enought info so a project newcomer can be able to install all the project dependencies, build it from scratch and fully testing it without needing to ask for advice. In case someone has doubts on this step, it must be updated to fix and clarify them.

Code should have JsDoc DocStrings for all modules, classes and methods, and code inside a function/method with some own identity should be fenced with whitelines and a comment before it explaining in one or two lines what it's going to do (think of it as the function name or description in case it was written or converted as a standalone function).

In-depth documentation will be written in GitBook format under the /docs folder of each project (both manually written and/or autogenerated) and published on Github Pages by using the Github projects auto-publish feature.

Log everything

Logging needs to be done in a smart way, not just adding traces to know where and how the code is running though and what function is executing at any exact moment that decrease performance and add noise to log files. Instead, log all events and data that comes in and out of the system, so later errors and executions can be reproducible.

For normal execution, stdout must be clean and stderr show only warnings and error messages, and events and log entries stored on .jsonl JSON Lines files having their timestamp, full module/class/method name, module version, arguments, event name and payload.

Errors should clearly identify the problem without ambiguities, and ideally have included debug info for the developer. To don't leak info to final users, give them just only a log file identifier, an error unique UUID, and the hash of the error log entry so it's possible to univoquely identify the logged error entry with the full undisclosed error info.

Javascript errors must be serialized and included with their stacktrace on the error log entry, probably as JSON format. This can't be done by default, so Error objects must be augmented to allow JSON serialization.

Test everything

Don't do TDD except if you are really sure of how some user stories and/or API parts will look like (and related to this, when you don't get your code to fully work as you desired), but instead do some (basic) regression tests after your code is working correctly and before pushing it to the repo. It's acceptable that tests (and fixes) are on their own commits after the ones holding the code of your implementation. In the long term, you should try to achieve 100% branch coverage whenever you can, and be sure percentage never drops, so you can be able to acomplise refactoring without fear. Automated code quality metrics will be added in the short future to check this pitfalls for you.

Update everything

Code must always be updated, with nightly checks for dependencies new versions and ensure they are working correctly. Useful tools for that task can be GreenKeeper and buho. Other checks for style and/or new features would need to be done by hand from time to time, or develop style checkers for them if not available. Once an update makes a nightly to fail, it must be fixed inmediatly, and maybe also notified to the dependency author.

Code should not have regressions, once one is found having a test for it or not, it will have the highest priority and must be fixed before adding new functionality, except if that new functionality would remove it because it's related or would deprecate it anyway.

results matching ""

    No results matching ""