Coding Style Guide
Jennifer Marx edited this page Apr 17, 2019
·
118 revisions
- Code is read much more often than it is written
- If possible, always provide a source for recommendations and rules
- Specify exact version numbers for dependencies
- Delete unnecessary code (don't comment it out)
- If implementation is hard to explain, it's probably a bad idea. Usually you can make a hard-to-explain function easier-to-explain via "divide and conquer" -- split it into several functions.
- No HTTP 500 (internal server) errors should be displayed to the users
- Don't use "fetch": standard nomenclature is "get" for code and "retrieve" for comments and log messages
- Aim for Minimum Valuable Product (MVP) with each milestone:
- use only lowercase for URLs and file system paths (to avoid HTTP 404 errors)
- use underscores in Django URL pattern names rather than dashes (Two Scoops 1.6.2)
- dashes in actual URLs are fine (Two Scoops 1.6.2)
- PEP 0008 for Python
- The Puppet Language Style Guide
- line length limits:
- 79 chars for Python (as per PEP 0008)
- 100 chars for JavaScript
- soft limit of 100 chars for HTML/CSS
- 140 characters for Puppet manifests
- all file types and languages
- indent with spaces, not tabs
- 4 for Python code (as per PEP 0008)
- 2 for everything else (JavaScript, JSON, HTML, CSS, etc.)
- naming conventions
- PEP 0008 for Python
- camelCase for JavaScript and JSON
- command line style checking tool
- Hanging indentation and brackets
# preferred
{ 'mouse': 'abc'
'dog': 'cbd' }
# followed-by
{
'mouse': 'abc',
'dog': 'cbd'
}
- Follow The Twelve-Factor App methods:
- One codebase tracked in revision control, many deploys
- Explicitly declare and isolate dependencies
- Store config in the environment
- Treat backing services as attached resources
- Strictly separate build and run stages
- Execute the app as one or more stateless processes
- Export services via port binding
- Scale out via the process model
- Maximize robustness with fast startup and graceful shutdown
- Keep development, staging, and production as similar as possible
- Treat logs as event streams
- Run admin/management tasks as one-off processes
- File structure (Django and JavaScript)
- organize by feature
- keep tests with features
- Puppet
- Parametrize classes
- URLs should include nouns, not verbs.
- Use plural nouns only for consistency (no singular nouns).
- Use HTTP verbs (GET, POST, PUT, DELETE) to operate on the collections and elements.
- You shouldn’t need to go deeper than resource/identifier/resource.
- URL v. header:
- If it changes the logic you write to handle the response, put it in the URL.
- If it doesn’t change the logic for each response, like OAuth info, put it in the header.
- Query params and form data field names should be snake_case
- View set names should be singular
Resources:
- White House Web API Standards
- What about actions that don't fit into the world of CRUD operations?
- Best Practices for Designing a Pragmatic RESTful API
- Nobody Understands REST or HTTP
- PEP 0020 -- The Zen of Python
- What are the “best practices” for using import in a module?
- Module imports should be grouped in the following order with blocks separated by a single blank line:
- imports from
__future__
- standard library imports
- imports from core Django
- imports from third party libraries and apps
- imports from the apps that you created as part of your Django project
- explicit relative imports from the current app
- For example:
from __future__ import absolute_import
from core.views import FoodMixin
from .forms import WaffleConeForm
from .models import WaffleCone
-
Avoid using 'import *'. It can cause name collisions that are tedious to track down.
-
Naming rules:
- Class names:
CamelCase
, and capitalize acronyms:HTTPWriter
, notHttpWriter
. - Variable names:
lower_with_underscores
. - Method and function names:
lower_with_underscores
. - Modules:
lower_with_underscores.py
. (But, prefer names that don't need underscores!) - Constants:
UPPER_WITH_UNDERSCORES
. - Precompiled regular expressions:
name_re
. - Don't be afraid to pick a slightly longer name because it's more descriptive. No one wins any points for shortening "response" to "rsp".
- Class names:
-
Avoid using
print
. Use thelogging
module and in Django management commandsself.stdout
andself.stderr
.
"Value: {}".format(value)
Note: Simple string concatenation can be favorable in some cases when readability isn't affected
logger.info("%s went %s wrong", 42, 'very')
- Pass file objects instead of file paths (for code testability and portability). For example, use
FileStoreItem.get_file_object()
to get a file object. - Use
urlparse.urljoin()
and'/'.join()
to construct URL paths - Exception handling:
- Use
except ValueError as e:
instead ofexcept ValueError, e:
(https://docs.python.org/2/tutorial/errors.html#handling-exceptions) - Do not use bare
except:
clause (https://docs.python.org/2/howto/doanddont.html#except) - Every HTTP request to external services in must be wrapped in a
try
block - Use parens (...) for continuations:
# bad
from itertools import groupby, chain, \
izip, islice
# good
from itertools import (groupby, chain,
izip, islice)
-
Documentation strings in Python:
- write docstrings for all public modules, functions, classes, and methods
- follow PEP 0257 -- Docstring Conventions:
- the
"""
that ends a multiline docstring should be on a line by itself - for one liner docstrings, please keep the closing
"""
on the same line
- the
- If an opening parenthesis or square bracket is at the end of a line then the closing one should be on a line by itself
- List Comprehensions:
- List comprehensions are an elegant way to define and create lists based on existing lists.
- It is generally more compact and faster than normal functions and loops for creating lists.
- We should avoid writing very long list comprehensions in one line to ensure that code is user-friendly and easy to debug.
- Every list comprehension can be rewritten in for loop, but every for loop can’t be rewritten in the form of list comprehension.
- Use components instead of directives whenever possible
- Define 1 component per file, keeps files under 400 lines of code.
- Small functions (single responsibilities), less than 75 lines of code.
- Wrap Angular components in a Immediately Invoked Function Expression (IIFE)
- Ordering Dependencies (alphabetize with groups)
- 3rd parties
- Custom dependencies
module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
return {
//Something
};
});
- Bindable members up top
- Function Declaration to Hide Implementation Details
- Keep ctrls small and focus. Move logic into factories.
- For consistency, use factories instead of services, since they are so similar.
- Factories should have single responsibilities.
- Manipulate DOM in a directive
- Manually identify dependencies
/* recommended */
angular
.module('app')
.controller('DashboardController', DashboardController);
DashboardController.$inject = ['$location', '$routeParams', 'common', 'dataservice'];
function DashboardController($location, $routeParams, common, dataservice) {
}
For code documentation, use [js doc] (http://usejsdoc.org/).
- use strict mode
'use strict';
- avoid global variables
- wrap custom code into an IIFE
(function (window, undefined) { <CODE> })(window);
- In the feature directory, keep all relevant files (partials, controllers, directives, services, etc).
- For filenames, use hyphens for filenames. (example-file-name.js)
- For filenames, use . notation for file types or other identifies which are not the actual name. (example-file-name.spec.js)
- For filenames, refrain from using the .tpls.html notation instead use .html.
- Separate words in ID and class names by a hyphen
- Avoid qualifying ID and class names with type selectors
- When quoting attributes values, use double quotation marks.
- We follow Vincent Driessen's branching model
- Smaller (more fine grained) commits are better than large ones (makes debugging and understanding changes easier)
- Commit messages should always reference issue numbers but do not close issues via commit messages
- Create pull requests to merge feature branches into
develop
branch (merge only after changes were reviewed by at least one other team member) - Merge feature branches back into develop often (they should not exist for longer than a week or two at most)
- Keep pull requests as small as practical, ideally under 100 lines of code (10 tips for better Pull Requests)
- Name feature branches as follows:
<your_github_username>/<feature_branch_name>
- Provide commit message summary under 50 chars (Writing good commit messages)
- Do not create more than one release branch at a time
Step 1: From your project repository, bring in the changes and test.
git fetch origin
git checkout -b <your_github_username>/<feature_branch_name> origin/<your_github_username>/<feature_branch_name>
git merge develop
Step 2: Merge the changes and update on GitHub.
git checkout develop
git merge --no-ff <your_github_username>/<feature_branch_name>
git push origin develop
Remember to delete feature, release and hotfix branches after they are merged - locally and on GitHub.
- The Next milestone should contain issues only temporarily (until the next dev meeting: issues should go into the backlog or the current milestone).
- New issues should never go directly into the current milestone without team approval - only into the Next or the backlog.
- Issues describing bugs or enhancements should contain the following sections: Steps to reproduce, Observed results, Expected results.
- Milestones are named using following this pattern: "Release major.minor.patch" where major.minor.patch is a version number like 1.2.3
- Python Exception Hierarchy: https://docs.python.org/2/library/exceptions.html#exception-hierarchy
- U.S. Digital Services Playbook
- 18F Guides
- Python Code Style
- Google Python Style Guide
- Django Coding Style
- JavaScript Standard Style
- jQuery JavaScript Style Guide
- Google JavaScript Style Guide
- AngularJS Style Guide
- Google HTM/CSS Style Guide
- idiomatic.js: Principles of Writing Consistent, Idiomatic JavaScript
- Pragmatic.js code style guidelines
- Airbnb JavaScript Style Guide
- Node.js Style Guide
- Code Conventions for the JavaScript Programming Language
- Galaxy Software Development Best Practices
- 10 tips for better Pull Requests
- Keep a simple URL structure - Google webmaster guidelines
- Puppet:
- Style guide
- Type reference
- CookBook
- Coding Practices
Administration
- Operations
- Setting Up Galaxy
- Galaxy CloudMan
- Annotating & Importing Refinery Tools
- Batch Import ISA-Tabs
- Backup & Restore
- Google reCAPTCHA v2
Development