Skip to content

Commit 36491db

Browse files
author
Dan Croak
committed
Create style guide
Latest version culled from internal thoughtbot development handbook and style guides from America's Test Kitchen, LevelUp, OwnerAide, Github, Copycopter, Bozhidar Batsov, and Christian Neukirchen.
0 parents  commit 36491db

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed

Diff for: README.md

+290
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
Style Guide
2+
===========
3+
4+
A guide for programming in style.
5+
6+
Workflow
7+
--------
8+
9+
Start a [Trajectory](https://www.apptrajectory.com) story.
10+
11+
Create a local feature branch off of master for development.
12+
13+
git checkout master
14+
git pull
15+
git checkout -b feature-xyz
16+
17+
Do work in your feature branch and commit the changes.
18+
19+
git add -A
20+
git status
21+
git commit
22+
23+
Write a [good commit message](http://goo.gl/w11us).
24+
25+
Present-tense summary under 50 characters
26+
27+
* More information about commit (under 72 characters)
28+
* More information about commit (under 72 characters)
29+
30+
Make sure tests pass. Share your feature branch
31+
32+
git push origin [branch]
33+
34+
Submit a [Github pull request](http://goo.gl/Kmdee).
35+
36+
Ask for a code review in Campfire. At least one person other than the author
37+
reviews the code before it is merged.
38+
39+
Rebase frequently to incorporate upstream changes.
40+
41+
git checkout master
42+
git pull
43+
git checkout [branch]
44+
git rebase master
45+
<resolve conflicts>
46+
47+
Interactive rebase (squash) your commits (if necessary).
48+
49+
git rebase -i master
50+
51+
Make sure tests pass. Merge your branch back to master and push your changes.
52+
53+
git checkout master
54+
git diff --stat master [branch]
55+
git merge [branch] --ff-only
56+
git push origin master
57+
58+
Delete your remote feature branch.
59+
60+
git push origin :[branch]
61+
62+
Delete your local feature branch.
63+
64+
git branch -d [branch]
65+
66+
Merge master into the staging branch:
67+
68+
git checkout staging
69+
git reset --hard origin/staging
70+
git log staging..master (view list of new commits)
71+
git diff --stat staging master (view changed files)
72+
git merge master
73+
git push origin staging
74+
75+
Deploy to [Heroku](https://devcenter.heroku.com/articles/quickstart):
76+
77+
git push <app> staging:master
78+
79+
Run migrations (if necessary):
80+
81+
heroku rake db:migrate --app <app>
82+
83+
Restart the dynos if migrations were run:
84+
85+
heroku restart --app <app>
86+
87+
[Introspect](http://goo.gl/tTgVF) to make sure everything's ok:
88+
89+
watch heroku ps --app <app>
90+
91+
Smoke test in browser. Write acceptance criteria on the Trajectory story.
92+
93+
Deliver story in Trajectory.
94+
95+
Another team member reviews feature on staging based on acceptance criteria.
96+
97+
When a batch (including a batch of one) of features have been accepted on
98+
staging, deploy to production using the same git workflow as staging.
99+
100+
Formatting
101+
----------
102+
103+
* Delete trailing whitespace.
104+
* Don't include spaces after `(`, `[` or before `]`, `)`.
105+
* Don't vertically align tokens on consecutive lines.
106+
* Include spaces around infix method invocations like `+` and `-`.
107+
* Indent continued lines two spaces.
108+
* Indent private methods equal to public methods.
109+
* Limit lines to a maximum of 80 characters.
110+
* Order methods and attributes alphabetically where possible.
111+
* Use 2 space indentation (no tabs) unless otherwise noted.
112+
* Use an empty line between methods, blocks and conditionals.
113+
* Use spaces around operators, after commas, colons and semicolons, around `{`
114+
and before `}`.
115+
* Use Unix-style line endings (`\n`).
116+
117+
Naming
118+
------
119+
120+
* Avoid abbreviations.
121+
* Avoid Hungarian notiation (`szName`).
122+
* Avoid types in names (`user_array`).
123+
* Name the enumeration parameter the singular of the collection.
124+
* Name variables, methods, and classes with intention-revealing names..
125+
* Treat acronyms as words in names (`XmlHttpRequest` not `XMLHTTPRequest`),
126+
even if the acronym is the entire name (`class Html` not `class HTML`).
127+
128+
Design
129+
------
130+
131+
* Aggressively DRY code during development.
132+
* Avoid comments.
133+
* Avoid global variables.
134+
* Avoid long parameter lists.
135+
* Be consistent.
136+
* Consider extracting `private` methods to their own object.
137+
* Don't duplicate the functionality of a built-in library.
138+
* Don't program defensively.
139+
* Don't swallow exceptions or "fail silently."
140+
* Don't write code that guesses at future functionality.
141+
* [Exceptions should be exceptional](http://rdd.me/yichhgvu).
142+
* [Keep the code simple](http://www.readability.com/articles/ko2aqda2).
143+
* Limit the number of collaborators of an object.
144+
* Prefer composition over inheritance.
145+
* Prefer small methods. One line is best.
146+
* Prefer small objects with a single, well-defined responsibility.
147+
* [Tell, don't ask](http://robots.thoughtbot.com/post/27572137956/tell-dont-ask).
148+
149+
Ruby
150+
----
151+
152+
* Avoid `%q`, `%Q`, `%x`, `%s`, and `%W`.
153+
* Avoid conditional modifiers (lines that end with conditionals).
154+
* Avoid hashes as optional parameters. Does the method do too much?
155+
* Avoid including code and gems in source control that are specific to your
156+
development machine or process. Examples: `.rvmrc`, file watchers, debuggers.
157+
* Avoid meta-programming.
158+
* Avoid monkey-patching core classes.
159+
* Avoid `return` unless required.
160+
* Avoid superfluous parentheses when calling methods, but keep them when you
161+
assign the return value.
162+
x = Math.sin(y)
163+
array.delete e
164+
* Avoid ternary operators (`boolean ? true : false`). Use multi-line `if`
165+
instead to emphasize code branches.
166+
* Define the version of Ruby the project uses in the Gemfile.
167+
* Don't use `unless`.
168+
* Prefer classes to modules when designing functionality that is shared by
169+
multiple models.
170+
* Prefer `detect` over `find` and `select` over `find_all` to avoid confusion
171+
with ActiveRecord and keep `select`/`reject` symmetry.
172+
* Prefer `map` over `collect` and `reduce` over `inject` due to symmetry and
173+
familarity with mapping and reducing in other technologies.
174+
* Use `_` for unused block parameters.
175+
hash.map { |_, v| v + 1 }
176+
* Use `%{}` for single-line strings needing interpolation and double-quotes.
177+
* Use `%w()` over `['', '']` for an array of words.
178+
* Use `&&` and `||` for boolean expressions.
179+
* Use `||=` freely.
180+
* Use `{...}` over `do..end` for single-line blocks.
181+
* Use `!` suffix for dangerous methods (modifies `self`).
182+
* Use `?` suffix for predicate methods (return a boolean).
183+
* Use `CamelCase` for classes and modules, `snake_case` for variables and
184+
methods, `SCREAMING_SNAKE_CASE` for constants.
185+
* Use `def` with parentheses when there are arguments.
186+
* Use `do..end` over `{...}` for multi-line blocks.
187+
* Use `each`, not `for`, for iteration.
188+
* Use heredocs for multi-line strings.
189+
* Use `/(?:first|second)/` over `/(first|second)/` when you don't need the
190+
captured group.
191+
* Use `private` over `protected` to indicate scope.
192+
* Use `def self.method` over `def Class.method` or `class << self`.
193+
* Use `Set` over `Array` for arrays with unique elements. The lookup is faster.
194+
* Use single-quotes for strings unless interpolating.
195+
* Use `unless boolean?` instead of `if !boolean?`.
196+
* Use [Factory Girl](https://github.com/thoughtbot/factory_girl) for setting up
197+
complicated test data.
198+
199+
Rails
200+
-----
201+
202+
* Avoid the `:except` option in routes.
203+
* Avoid `member` and `collection` routes.
204+
* Avoid Single Table Inheritance.
205+
* Deploy to [Heroku](http://heroku.com).
206+
* Don't invoke a model's class directly from a view.
207+
* Don't use SQL or SQL fragments (`where('inviter_id is not null')`) outside of
208+
models.
209+
* Set `config.action_mailer.raise_delivery_errors = true` in the development
210+
environment.
211+
* Keep the `db/schema.rb` under version control.
212+
* Limit the number of instance variables shared between controller and view.
213+
* Name initializers for their gem name. Example: `paperclip.rb`
214+
* Order controller contents: filters, public methods, private methods.
215+
* Order model contents: constants, attributes, associations, nested attributes,
216+
named scopes, validations, callbacks, public methods, private methods.
217+
* Prefer presenters (Ruby objects responsible for presentation) over view
218+
helpers.
219+
* Put all copy text in models, views, controllers, and mailers in
220+
`config/locales`.
221+
* Set `config.action_mailer.delivery_method = :test` in the test environment.
222+
* Use `_path` over `_url` for named routes everywhere except mailer views.
223+
* Use `def self.method` over the `named_scope :method` DSL.
224+
* Use [Foreman](https://github.com/ddollar/foreman) to run Rails apps in
225+
development mode.
226+
* Use `I18n.t 'dot.separated.key'` over
227+
`I18n.t :key, :scope => [:dot, :separated]`.
228+
* Use [Haml](http://haml-lang.com) for view templates.
229+
* Use `has_and_belongs_to_many` if all you need is a join table. Start simple.
230+
* Use namespaced locale lookup in the views by prefixing a period: `t '.title'`.
231+
* Use nested routes to express `belongs_to` relationships between resources.
232+
* Use one `ActionMailer` for the app. Name it `Mailer`.
233+
* Use [single recipient SMTP](https://gist.github.com/2042496) in the staging
234+
environment.
235+
* Use the default `render 'partial'` syntax over `render :partial => 'partial'`.
236+
* Use the `:only` option to explicitly state exposed routes.
237+
238+
Database
239+
--------
240+
241+
* Create [indexes concurrently](https://gist.github.com/3186117) to avoid table
242+
locks and [reduced performance](http://goo.gl/fi5ER) during deploys.
243+
* Consider a [partial index](http://goo.gl/YC8Jt) for queries on booleans.
244+
* Constrain most columns as [`NOT NULL`](http://goo.gl/0GeBr).
245+
* Create a read-only [Heroku Follower](http://goo.gl/xWDMx) for your
246+
production database. If a Heroku database outage occurs, Heroku can use the
247+
follower to get your app back up and running faster.
248+
* Use the Heroku Follower database for analytics to limit reads on the primary
249+
database.
250+
251+
Javascript
252+
----------
253+
254+
* Define functions that operate on `window` or DOM in scope of `window`.
255+
* Initialize arrays using `[]`.
256+
* Initialize empty objects and hashes using `{}`.
257+
* Use `CamelCase` for prototypes, `mixedCase` for variables and functions,
258+
`SCREAMING_SNAKE_CASE` for constants, `_single_leading_underscore` for
259+
private variables and functions.
260+
* Use `data-` attributes to bind event handlers.
261+
* Use the [module pattern](http://yuiblog.com/blog/2007/06/12/module-pattern)
262+
to control method visibility.
263+
264+
Testing
265+
-------
266+
267+
* Avoid `its`, `let`, `let!`, `specify`, `subject`, and other DSLs. Prefer
268+
explicitness and consistency.
269+
* Disable real HTTP requests to external services.
270+
* Don't prefix `it` blocks with 'should'.
271+
* Name outer `describe` blocks after the method under test. Use `.method`
272+
for class methods and `#method` for instance methods.
273+
* Order factories.rb: sequences, traits, factory definitions.
274+
* Order factory definitions alphabetically by factory name.
275+
* Order factory attributes: implicit attributes, newline, explicit attributes,
276+
child factory definitions. Each section's attributes are alphabetical.
277+
* Prefix `context` blocks names with 'given' when receiving input. Prefix with
278+
'when' in most other cases.
279+
* Run specs with `--format documentation`.
280+
* Use a `context` block for each execution path through the method.
281+
* Use a [Fake](http://robots.thoughtbot.com/post/219216005/fake-it) to stub
282+
requests to external services.
283+
* Use `before` blocks to clearly define the 'setup' phase of the
284+
[Four Phase Test](http://xunitpatterns.com/Four%20Phase%20Test.html).
285+
* Use integration tests to execute the entire app.
286+
* Use literal strings or non-[SUT](http://xunitpatterns.com/SUT.html) methods
287+
in test expectations when possible.
288+
* Use one expection per `it` block.
289+
* Use stubs and spies (not mocks) in isolated tests to test only the object
290+
under test.

0 commit comments

Comments
 (0)