Wiki/Policies/Development_Best_Practices.md

8.3 KiB

Like all organizations, the AniNIX has a set of coding and development best practices. See HelloWorld for an example project that should implement these recommendations and provide a skeleton to use.

Packages

Each package should have a single, dedicated purpose. Developers should be careful against scope creep -- if additional functionality is needed beyond the purpose of the package, another package should be created to fill the need.

Commenting

All source files should be commented with at least one descriptive comment per operational unit. Ideally, there will be no more than 20 lines between comments, unless so dictated by function. Block comments should be at the beginning of functions summarizing the work the function does, the parameters if any, and the return value if any.

/// <summary>
/// Put the summary here
/// </summary>
/// <param name="xname">A parameter for X</param>
/// <param name="yname">A parameter for Y</param>
/// <returns>The return value</returns>

Source files should also maintain a header block tracking ownership and scope. Some source systems will also require dependency and versioning information in this block. This information is optional; the AniNIX deploys by rolling release, so the PKGBUILD installed into pacman or the Git source repo will have the version. Makefiles and PKGBUILDS will also track dependencies.

/*
 * File:
 *
 * Description:
 *
 * Package:
 * Copyright:
 *
 * Author:
 */

Avoid so-called "code-golfing" in source-code -- source should be easy to read, consistent, and verbose. Comments and other space-consuming elements can be stripped out in compilation for space-conscious projects.

Safe Coding

All inputs should be sanitized to match the developer's expectations during operations. Unlimited reads are unacceptable -- bound the reads with a buffer to contain the memory pressure to a reasonable space and to prevent overflows.

All memory that is allocated should be deallocated before the process exits -- zeroing the memory segment is optional.

Portability

Packages should be reasonably portable to other systems, but there is no expectation of unlimited portability. The network should generally test against ArchLinux -- portable projects should also strive to test against CentOS, Kali Linux, and Windows.

External Standards

AniNIX projects should follow international standards to ease user interaction.

Version Control

Git is the version-control mechanism of choice. Packages being developed by Core admins should be added as a folder immediately under the foundation folder on checkout. Commit messages should be specific, and changes should be attempted in a development branch before being merged to master.

Makefiles

All packages should include a Makefile with at least the following rules.

  • compile: This should include all the steps necessary to compile the package. When this is done, the final executable should be able to run from the same directory as the Makefile.
  • install: This should include all the steps necessary to installed the compiled files to the OS and set appropriate permissions. The compile step should be a dependency.
  • uninstall: the reverse steps from install
  • clean: This should remove any files built by compile.
  • test: this should include the rules needed to run the package without installing.
  • diff: this should compare local build with installed executables or scripts.
  • reverse: this should pull the installed copies of scripts back to the source directory
  • checkperm: make sure permissions are set. Here's a skeleton Makefile to use.
pkgdirname != basename `git config remote.origin.url` | sed 's/.git$$//'

compile:

install: compile

uninstall:

test: compile
    python3 -m pytest

clean:
    @bash -c 'printf "This will reset the repository and lose all work. Confirm? [YES/no]  " ; read answer; [ "$$answer" == "YES" ] && exit 0; exit 1'
    cat .gitignore | xargs rm -Rf

diff:

reverse:

checkperm:

PKGBUILD

Standalone packages like CryptoWorkbench should include a PKGBUILD for the ArchLinux package manager.

Language

Filenames should indicate language using standard extensions.

bash

All OS scripts should be written in bash and include /bin/bash as a dependency. * We don't use CSH/TCSH for reasons. * KSH has other problems. * ZSH is being considered but presently has too low an adoption rate. * Old-school SH is missing features.

A style guide is available.

HTML/CSS/PHP

All Web sites should be written in HTML with minimal inline CSS -- a proper stylesheet should be included. * For web pages expected to compile from server execution, PHP should be the chosen language. We have not been able to convert to Facebook's HHVM yet. * For web pages expected to execute functions on the client browser, Javascript should be the chosen language and the Javascript should live in script file.

C

Low-level applications should be written in C and require /usr/bin/gcc as a dependency. Re-useable functions should be written in linked libraries.

See man pages for documentation.

C#

All large-scale applications should be written in C# and include the /usr/bin/mono and /usr/bin/mcs dependencies on compile. C# has been evaluated to be an industry-standard and portable language with a lesser exploit history, superior typing, and better resource management than Java.

Documentation is available.

Python3

QA and proof-of-concept code should be written in Python3 -- this is a standard among ethical hacking classes, and the programming python3/pdb interfaces make writing code easy.

Documentation is available.

Integration

  • Services that do not need to run as a privileged user (notably Cerberus' main HIDS and Heartbeat) should deprivilege.
1.  Hook for depriviliging
if ! getent passwd raven; then useradd -M -G git,ircd,api -d ${CONFDIR} raven; fi

Configuration and installed files should go to the following locations:

  • Configuration should go into /usr/local/etc/PackageName/
  • Direct executables should go into /usr/local/bin
  • Indirect executables, such as compiled Mono projects, should go into /opt/aninix/PackageName/
  • Logfiles should default to /var/log/PackageName/

Code Reuse

All projects should seek to maximize code re-use. Any source code that could be generalized should go into Uniglot. This repository should be included a dependency in PKGBUILDS and checked by Makefiles.

OS Integration

Process

Design

Projects should be designed with an established scope. This scope should be outlined in the package README.md. The appropriate language should be selected.

Development

Initial development should be done to get the package in a working condition following the above requirements. The appropriate README.md should be updated with development notes, dependencies, and a wishlist as development proceeds.

Peer QA

If working with a group or any available peers, these peers should read through the code. Comments should be submitted in Gitea issues or pull requests -- quick conversation can be had on IRC until all is sorted. Until all peer comments are handled to the group's satisfaction, the process will hang.

QA

All packages should be tested automatically and manually before being released. This should include unit tests for functionality, sanitizing inputs, stability, etc.

Release

Release via Foundation and preferably also Maat. Web view is provided by AniNIX Foundation, and git cloning programs are available for all major distributions.

Bug Reporting and Fixing

Bugs should be announced to the network staff via the IRC system. If the bug is geniune, an issue should be created and published to track the resolution. Bug fixes should trump new enhancements and specific fixes tracked as pull requests.