Skip to content

Commit 5733a83

Browse files
Merge pull request #377 from lorenzwalthert/contributing
- Advice for contributors (#377).
2 parents 2bf7f60 + 7dc42f1 commit 5733a83

File tree

1 file changed

+147
-1
lines changed

1 file changed

+147
-1
lines changed

CONTRIBUTING.md

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,148 @@
1+
## Intro
2+
13
This project follows the contributing recommendations outlined by [saamwerk](https://lorenzwalthert.github.io/saamwerk/).
2-
In particular, issues labelled with `Status: Postponed` are closed even if they are not resolved.
4+
In particular, issues labelled with `Status: Postponed` are closed even if they
5+
are not resolved.
6+
7+
## How to dive in and understanding the source code
8+
9+
Read the vignettes. If you are done, come back here.
10+
11+
`devtools::load_all()`
12+
13+
`debug(style_text)`
14+
15+
`style_text("call(1, 2 + 1)")`
16+
17+
Go broad before you go deep. Before going into the very deep layers of function
18+
calls of `style_text()`, try to understand that `style_text()` consists of a few
19+
function calls only.
20+
Go into each of them and try to understand one layer deep. That is, try to
21+
understand what `make_transformer()` does by reading the names of the functions
22+
that get called, the name of the objects that are created by assigning the output of
23+
these function calls. Before looking into a functions source code, look at the
24+
documentation for that function. All internal important functions
25+
are documented and documentation is available also for unexported objects via
26+
`?` (if you did `devtools::load_all()`.
27+
Then, go into `parse_transform_serialize()` and so on.
28+
29+
To understand the most fundamental operation in styler, the manipulation of the
30+
columns related to spacing and line break information, pick a rule from
31+
`R/rules-*.R`, e.g. `R/rules-spacing`, add a break point to a rule and style a
32+
string where you think this rule will be active. Then, see what happens and how
33+
this rule is applied on each level of nesting.
34+
35+
## Static code analysis
36+
37+
There are multiple packages that can be used to analyze a code base:
38+
39+
* [gitsum](https://github.com/lorenzwalthert/gitsum): Parses and summarises git
40+
repository history.
41+
* [parsesum](https://github.com/lorenzwalthert/parsesum): Analyses source code
42+
through parsing.
43+
44+
Check out the links above to see how the tools listed could help you
45+
understanding styler.
46+
47+
## Project setup
48+
49+
* The package is developed with the devtools suite, which includes roxgen2 for
50+
documentation, testthat for unit testing, pkgdown for html documentation.
51+
* Continuous integration is done with the tic (tasks integrating continuously)
52+
package.
53+
* A key development principle of styler is to separate infrastructure from
54+
style guide. Hence, whenever possible, transformer functions should be
55+
adapted, not the infrastructure should be changed for a specific style guide.
56+
* styler was created in 2017 by Kirill Müller, then turned from a
57+
proof-of-concept into a ready-for-production tool as part of GSOC 2017 with
58+
Kirill Müller and Yihui Xie as mentors and Lorenz Walthert as student.
59+
60+
61+
## File Structure
62+
63+
The source code is organized as follows:
64+
65+
| File | Description |
66+
| -------------: |:-----------------------------------------------------------|
67+
| addins.R | ui and helpers for the Addins of styler. |
68+
| communicate.R | function to communicate to the user via the console. |
69+
| compat-dplyr.R | compatibility functions. Since styler does not depend on dplyr, we define the dplyr functions ourself.|
70+
| compat-tidyr.R | compatibility functions. Since styler does not depend on tidy, we define the tidyr functions ourself.|
71+
| expr-is.R | Functions to check whether an expression matches a predicate (e.g. whether it *is* a function call, a curly brace expression etc.). |
72+
| indent.R | Computation of whether indention is needed (needs_indention()), if so which indices are indented and how indention is it is triggered. |
73+
| initialize.R | initializer called with the visitor at each nest. |
74+
| nest.R | converting from a text representation into a flat and then into a nested parse table representation. |
75+
| nested-to-tree.R | utilities to create a tree representation from text (after text was converted into a nested parse table). |
76+
| parse.R | parse text into parse table, minor token manipulation, verification of parsed objects. |
77+
| reindent.R | Deals with token-dependent indention and re-indention, opposed to indent.R where all indention is token independent (i.e. a brace just adds one level of indention, whereas in function declaration headers (if mutli-line), indention depends on token position of "function"). |
78+
| relevel.R | Reorganizing the nested parse table, namely relocates expressions on both sides of "%>%" to the same nest. |
79+
| rules-line-break.R, rules-other.R, rules-replacement.R, rules-spacing.R | transformer rules |
80+
| serialize.R | converts flattened parse table into text representation. Complement operation to the functions in nest.R |
81+
| set-assert-args.R | Assertion and setting of arguments. |
82+
| style-guides.R | How to create style guide objects from transformers. |
83+
|styler.R | General package information. |
84+
| testing.R | function used for testing. |
85+
| token-create.R | Utilities for creating tokens, mostly to insert braces around mutli-line if statements. |
86+
| token-define.R | Defines which tokens belong to which group. |
87+
| transform-code.R, transform-files.R | Transformation of code for APIs that manipulate files (e.g. style_file()). |
88+
| ui.R | User interaces. Top-level functions for styling. |
89+
| unindent.R | Certain tokens cause unindention, e.g. closing braces. |
90+
| utils.R | low-level general purpose utilities. |
91+
| vertical.R | S3 class for pretty printing of styled code. |
92+
| visit.R | Functions that apply functions to each level of nesting, either inside out or outside in. |
93+
| zzz.R | backport imports. |
94+
95+
96+
## High-level conventions
97+
98+
* The project follows a highly functional approach. This means that
99+
functionality should be capsuled into functions, even if they are only called
100+
once. This makes abstraction from the code easier, reduces the number of lines
101+
for each function declaration considerably and makes it easier for people not
102+
familiar with the code base to dive into it.
103+
* All internal functions (except if they are 100% self-explanatory) are to be
104+
documented.
105+
* New functionality (e.g. in terms of styling rules) needs to be unit tested. If
106+
the new functionality changes how code is to be styled, the infrastructure
107+
with `test_collection()` should be used.
108+
* Cases that are not yet formatted correctly can be labelled with a `FIXME`.
109+
* GitHub is the platform where communication about source code happens. We
110+
refrain from adding extensive in-line code comments. One can use `git blame`
111+
to track when changes were introduced and find the corresponding pull request
112+
and associated issues to understand the thought process that lead to a change
113+
in the source code. This also implies that issues and / or pull request
114+
contain verbose explanation of problems and solutions provided.
115+
116+
## Low-level coventions
117+
118+
This project follows the [tidyverse style guide](http://style.tidyverse.org).
119+
If we refer to specific variables / values etc. in the following sections, you
120+
can use RStudio's full text search to find where
121+
`remove_line_break_before_round_closing_after_curly()` is declared or called.
122+
123+
124+
### Files
125+
126+
* File names only contain alphanumeric characters and dashes.
127+
* Files are named according to topics / contexts, not according to functions
128+
that live in these files.
129+
130+
### Functions
131+
132+
* Function names should be verbs. No abbreviations should be used, we don't
133+
care if function names are particularly long. For example, there is a
134+
function with the name `remove_line_break_before_round_closing_after_curly()`.
135+
* only very low-level functions or functions that don't fit in any other file
136+
go to `utils.R`.
137+
138+
### Boolean Values
139+
140+
Functions that return Boolean values or variables that hold Boolean values are
141+
often prefixed with `is` or `has`. For example, `is_rmd_file(path)` is a
142+
function that returns `TRUE` if `path` is the path to a `.Rmd` file and `FALSE`
143+
otherwise.
144+
145+
### Vectors with indices
146+
147+
Vectors that hold indices are often suffixed with `idx`. `else_idx` for example
148+
indicates for every row in a parse table whether it contains an `else` token.

0 commit comments

Comments
 (0)