aboutsummaryrefslogtreecommitdiff
path: root/guides
diff options
context:
space:
mode:
authorJakob Odersky <jakob@driver.xyz>2018-09-14 17:59:21 -0700
committerJakob Odersky <jakob@driver.xyz>2018-09-14 17:59:21 -0700
commit876fccbbde53e27b3fb820808d2c336ca71aa7e1 (patch)
tree0143fa9b434091470d2466a6d719e9bb37d969d9 /guides
parent07fb4ce6471aef531a1246c8fd9d200f23c119d2 (diff)
downloadbest-practices-876fccbbde53e27b3fb820808d2c336ca71aa7e1.tar.gz
best-practices-876fccbbde53e27b3fb820808d2c336ca71aa7e1.tar.bz2
best-practices-876fccbbde53e27b3fb820808d2c336ca71aa7e1.zip
Make this repo a standalone website
These changes add the ability to generate a full website from individual style guides. The website can be viewed [here](drivergroup.github.io/best-practices). Also included, are the following additions: - Improve recommendations for Scala. - Add more recommendations for Git. - Add recommendations for Shell Script.
Diffstat (limited to 'guides')
-rw-r--r--guides/css.md11
-rw-r--r--guides/git.md29
-rw-r--r--guides/html.md14
-rw-r--r--guides/index.md0
-rw-r--r--guides/javascript.md95
-rw-r--r--guides/scala.md81
-rw-r--r--guides/shell-script.md63
7 files changed, 293 insertions, 0 deletions
diff --git a/guides/css.md b/guides/css.md
new file mode 100644
index 0000000..94555f8
--- /dev/null
+++ b/guides/css.md
@@ -0,0 +1,11 @@
+## CSS
+
+- Prefer Flexbox
+
+- Classes should describe elements and not be generic (`Bigbox` -> `FAQContainer`)
+
+- Mobile: <= 620px
+
+- Tablet: 620px - 1024px
+
+- Desktop: > 1024px
diff --git a/guides/git.md b/guides/git.md
new file mode 100644
index 0000000..c03e447
--- /dev/null
+++ b/guides/git.md
@@ -0,0 +1,29 @@
+## Git
+
+- Use a simple branching model with one master development branch, and
+ create feature and backport branches as required.
+
+ - The master branch should represent the latest development version.
+
+ - Tag all released versions.
+
+ - Backport branches may be spun off tags when they become necessary.
+
+- Proposed changes require at least one sign-off to be accepted into
+ master.
+
+- Large feature branches with multiple collaborators should be
+ *merged* into master.
+
+ Rationale: rewriting history in public branches can break other
+ people's work and should not be done lightly.
+
+- Private feature branches should be *rebased* onto master, prior to
+ merging. *Squashing* is optional, but all intermediate commits
+ should contain meaningful changes and must pass continuous
+ integration tests.
+
+ Rationale: private branches should be considered backups of work on
+ local developer machines and hence should not be relied upon by
+ others. Furthermore, a linear history is easier to reason about than
+ a branched one.
diff --git a/guides/html.md b/guides/html.md
new file mode 100644
index 0000000..e0581ef
--- /dev/null
+++ b/guides/html.md
@@ -0,0 +1,14 @@
+## HTML
+
+- Use svg's over all other image formats when possible.
+
+- All `<img>` tags should have `“alt”` text.
+
+- Only use tables for tabular data (not for layout)
+
+- Make use of html5 elements like `<header>`, `<footer>`, `<nav>`, `<section>`, etc.
+
+### Browsers
+
+- Avoid supporting versions of Internet Explorer before IE11.
+
diff --git a/guides/index.md b/guides/index.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/guides/index.md
diff --git a/guides/javascript.md b/guides/javascript.md
new file mode 100644
index 0000000..bb363ac
--- /dev/null
+++ b/guides/javascript.md
@@ -0,0 +1,95 @@
+## JavaScript
+
+- Type with flow
+
+- Style with [prettier](https://prettier.io/) ([see section below](#prettier))
+
+- Lint with eslint and use `eslint:recommended` at a minimum
+
+- Test with [jest](https://facebook.github.io/jest/) and enzyme
+
+
+- 2 spaces (instead of tabs)
+
+- Promises (not callbacks)
+
+- No [decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841)
+
+- No [mobx](https://mobx.js.org/)
+
+- Place tests alongside the file(s) it tests (not in a separate directory)
+
+- End test files with `.test.js`
+
+### React/Redux
+
+- Lint with [`tslint-react`](https://github.com/palantir/tslint-react) or eslint's [`plugin:react/recommended`](https://github.com/yannickcr/eslint-plugin-react) at a minimum.
+
+- No unnecessary and empty `<div>`’s
+
+- If `this.props.<variable name>` is used more than once, dereference it at the top of `render`.
+
+- Extract variables used in `render()` to the top of `render()`
+
+- API calls should lie in a testable file outside of components.
+
+
+- Components should not wait for promises to resolve, instead listen on props via redux’ `mapStateToProps()`.
+
+- Declare and export components in separate places (otherwise the web inspector cannot name components properly)
+
+### Flowtype
+
+- Any types used in more than one file should be placed in `src/types.js`
+
+- Add flow linting via [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype)
+
+- Disallow "`any`" with [eslint no-weak-types](https://github.com/gajus/eslint-plugin-flowtype#no-weak-types) (use "`Obect`" and "`Function`" to cover complicated use-cases)
+
+
+- In components which use `mapStateToProps`, separate `OwnProps` from `ConnectedProps` into separate types. Join them with `type Props = OwnProps & ConnectedProps`. In addition, if using `mapDispatchToProps`, create a type `DispatchProps` and join that with `Props`.
+
+### 𝓣𝓢 TypeScript 𝓣𝓢
+
+- Lint with [`tslint:recommended`](https://github.com/palantir/tslint) at a minimum.
+
+- No implicit any (type everything that’s not inferable)
+
+- Any variable declared without an initial value should be typed
+
+### Prettier
+
+Add the following to `package.json`:
+
+```json
+ "prettier": {
+ "overrides": [
+ {
+ "files": ["*.js", "*.scss", "*.css", "*.pcss"],
+ "options": {
+ "singleQuote": true,
+ "trailingComma": "all"
+ }
+ }
+ ]
+ }
+```
+
+The following information about prettier is better described on the prettier documentation [here](https://prettier.io/docs/en/precommit.html#option-1-lint-staged-https-githubcom-okonet-lint-staged).
+Use `lint-staged` to auto-call prettier in a `precommit` "`script`":
+
+```json
+ "lint-staged": {
+ "src/**/*.scss": ["prettier --parser scss --write", "git add"],
+ "src/**/*.{js,css}": ["prettier --parser flow --write", "git add"],
+ "nightwatch/**/*.js": ["prettier --write", "git add"]
+ }
+```
+
+### Npm
+
+* Support the following `script`'s in your root `package.json`:
+
+1. `“watch”`: Starts the dev server
+2. `“build”`: Builds static assets (if they exist) "`/src`" -> "`/build`"
+3. `“test”`: Runs all tests (linting first, then unit tests)
diff --git a/guides/scala.md b/guides/scala.md
new file mode 100644
index 0000000..a2009e7
--- /dev/null
+++ b/guides/scala.md
@@ -0,0 +1,81 @@
+## Scala
+
+- First and foremost, follow [the Principle of Least
+ Power](http://www.lihaoyi.com/post/StrategicScalaStylePrincipleofLeastPower.html#philosophy-principle-of-least-power).
+
+ In a nutshell:
+
+ - Keep your code simple and at a level of abstraction dictated by
+ the actual circumstances.
+
+
+ - Don't design an API that will fit all future requirements. Start
+ simple and refactor when the time comes. A good rule of thumb is
+ to assume that you will completely rewrite your code at least once
+ before finding a satisfactory solution.
+
+ Rationale: the article justifies its points thoroughly. In general,
+ Scala makes it easy to design advanced abstractions which can make
+ it harder for an outsider to grasp a codebase. As a codebase grows,
+ sometimes these abstractions become necessary, however they usually
+ aren't in the beginning. Since Scala is a statically typed language,
+ you should not fear refactoring when they do become necessary.
+
+ *Scala's name comes from "scalable language". That refers to large,
+ as well as small!*
+
+- Avoid building libraries in such a way that they require wildcard
+ imports to function.
+
+ I.e. avoid building libraries that use this common pattern: `import
+ foo.bar._`
+
+ Rationale: a developer using a library doesn't want to know how it
+ works, but wants to get his or her job done. Wildcard imports
+ (especially if they bring into scope implicits) obfuscate the origin
+ of types and methods to a reader who is not familiar with the
+ library, and hence make it harder for the reader to edit.
+
+- Choose dependencies on external libraries judiciously, and keep them
+ to a minimum. Avoid depending on multiple libraries that offer
+ similar functionality.
+
+ Prefer reimplementing *small* features in your own code rather than
+ relying on a library.
+
+ For example, assume a web service has a REST API and also offers a
+ Java library that wraps said API. In the case where only a couple of
+ endpoints from the external REST service are required in some code,
+ prefer calling the endpoints with an HTTP client directly, rather
+ than relying on the entire library. This allows you to forego an
+ additional layer of indirection and keeps you in control of which
+ HTTP client to use.
+
+- In public interfaces, expose only types from the Scala standard
+ library. In particular, avoid exposing scalaz or cats types.
+
+- Make use of comments liberally. Describe interesting parts of code,
+ how to use it and why it's there. Don't comment *everything*.
+
+- Organise code in a functionally cohesive manner. Use one parent
+ package to namespace a library, and use nested packages according to
+ functionality.
+
+- Do not use runtime reflection.
+
+ Rationale: runtime reflection circumvents type checking and strongly
+ ties applications to the JVM.
+
+- Use
+ [scalafmt](https://scalameta.org/scalafmt/docs/introduction.html) to
+ format code.
+
+ Rationale: formatting is material for holy wars. If it is enforced
+ by an automatic tool then there is no room for such discussions.
+
+## Other Resources
+
+[Simple Made
+Easy](https://www.infoq.com/presentations/Simple-Made-Easy), by Rich
+Hickey. A great talk about the differences between "Simple",
+"Complex", "Easy" and "Hard", and how to write simple programs.
diff --git a/guides/shell-script.md b/guides/shell-script.md
new file mode 100644
index 0000000..a5770ae
--- /dev/null
+++ b/guides/shell-script.md
@@ -0,0 +1,63 @@
+## Shell Script
+
+- Run the [ShellCheck](https://github.com/koalaman/shellcheck) linter
+ on all scripts.
+
+- Follow Google's [Shell Style
+ Guide](https://google.github.io/styleguide/shell.xml); most notably,
+ the below points.
+
+- Use only Bourne Again SHell (Bash).
+
+ It's acceptable to use features available only in Bash 4 and
+ later. As of this writing, that version was released almost 10 years
+ ago, and developers on any platforms which do not ship the latest
+ version out-of-the box are expected to upgrade.
+
+- Prefer no file name extension for executables, and ".sh" extensions
+ for libraries (scripts that are meant to be "sourced" in other
+ scripts).
+
+ Rationale: an OS can run any executable file, regardless of its
+ content, and as such, it isn't helpful to know that an executable is
+ in fact a shell script. However, it is essential to know that an
+ included library is indeed a shell script.
+
+- Use long names for command-line options rather than short
+ ones. E.g. use `ls --all` instead of `ls -a`.
+
+ Rationale: long names trade off clarity at the expense of
+ brevity. They make it easier for an unfamiliar reader to grasp the
+ meaning of an argument, but require the author to write more
+ characters. Hence they are recommended in all places that are read
+ more often than written.
+
+- Use lower_snake_case for all local environment variables, and
+ UPPER_SNAKE_CASE for exported variables.
+
+- Prefer parsing command line options rather than relying on
+ environment variables for configuration.
+
+- Print status messages to stderr, not stdout.
+
+ Rationale: stdout is often parsed by other utilities (for example in
+ a pipeline) and should hence only contain a program's output, if
+ any.
+
+- Don't make any assumptions about the working directory from which a
+ script is invoked. Specifically, don't require that the script be
+ invoked within the same directory it is located.
+
+ Rationale: scripts should be treated like any other executable and
+ should support indirection via symlinks. Requiring a specific
+ working directory for a program to function is a needless
+ restriction.
+
+ Note that this guide specifically applies to the *working directory*
+ of the caller. The script itself may make assumptions about *its
+ location* and the location of resources. The following snippet is an
+ example mechanism to determine the directory of a script.
+ ```bash
+ # Base directory that this script is located at.
+ dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+ ```