4
4
[ ![ codecov] ( https://codecov.io/gh/ffloyd/flows/branch/master/graph/badge.svg )] ( https://codecov.io/gh/ffloyd/flows )
5
5
[ ![ Gem Version] ( https://badge.fury.io/rb/flows.svg )] ( https://badge.fury.io/rb/flows )
6
6
7
- ** Right now library is under heavy development. Version 0.4.0 will be the first stable API candidate. And version 1.0.0 is coming after.**
8
-
9
7
Small and fast ruby framework for implementing railway-like operations.
10
- By design it is close to [ Trailblazer::Operation] ( http://trailblazer.to/gems/operation/2.0/ ) and [ Dry::Transaction] ( https://dry-rb.org/gems/dry-transaction/ ) ,
11
- but has simpler and flexible DSL for defining operations and matching results. Also ` flows ` is faster.
8
+ By design it is close to
9
+ [ Trailblazer::Operation] ( http://trailblazer.to/gems/operation/2.0/ ) ,
10
+ [ Dry::Transaction] ( https://dry-rb.org/gems/dry-transaction/ ) and Rust control
11
+ flow style.
12
+ Flows has simple and flexible DSL for defining operations and matching results.
13
+ Also ` flows ` is faster than Ruby's alternatives.
12
14
13
15
` flows ` has no production dependencies so it can be used with any framework.
14
16
@@ -17,7 +19,7 @@ but has simpler and flexible DSL for defining operations and matching results. A
17
19
Add this line to your application's Gemfile:
18
20
19
21
``` ruby
20
- gem ' flows'
22
+ gem ' flows' , ' ~> 0.4 '
21
23
```
22
24
23
25
And then execute:
@@ -32,7 +34,173 @@ Or install it yourself as:
32
34
gem install flows
33
35
```
34
36
35
- _ Rest of documentation will be here when v0.4.0 be ready._ Stay tuned.
37
+ ## Usage & Documentation
38
+
39
+ * [ YARD documentation] ( https://rubydoc.info/github/ffloyd/flows/master ) - this
40
+ link is for master branch. You can also find YARD documentation for any released
41
+ version after ` v0.4.0 ` . This documentation has a lot of examples, describes
42
+ motivation behind each abstraction, but lacks some guides and defined conventions.
43
+ * [ Guides] ( https://ffloyd.github.io/flows/#/ ) - guides, conventions, integration
44
+ and migration notes. Will be done before ` v1.0.0 ` release. Right now is under development.
45
+
46
+ ## Development
47
+
48
+ ` Flows ` is designed to be framework for your business logic. It is a big
49
+ responsibility. That's why ` flows ` has near to be sadistic development
50
+ conventions and linter setup.
51
+
52
+ ### Anyone can make Flows even better
53
+
54
+ If you see some typos or unclear things in documentation or code - feel free to open
55
+ an issue. Even if you don't have plans to implement a solution - a problem reporting
56
+ will help development much. We cannot fix what we don't know.
57
+
58
+ ### [ Lefthook] ( https://github.com/Arkweid/lefthook ) as a git hook manager
59
+
60
+ Installation on MacOS via Homebrew:
61
+
62
+ ``` sh
63
+ brew install Arkweid/lefthook/lefthook
64
+ ```
65
+
66
+ Activation (in the root of the repo):
67
+
68
+ ``` sh
69
+ lefthook install
70
+ ```
71
+
72
+ Run hook manually:
73
+
74
+ ``` sh
75
+ lefthook run pre-commit
76
+ ```
77
+
78
+ Please, never turn off pre-commit hook.
79
+
80
+ ### Rubocop as the first linter
81
+
82
+ [ Rubocop] ( https://docs.rubocop.org/en/stable/ ) in this setup is responsible for:
83
+
84
+ * defining code style (indentation, etc.)
85
+ * suggest performance improvements ([ rubocop-performance] ( https://docs.rubocop.org/projects/performance/en/stable/ ) )
86
+ * forces all that stuff (with some exceptions) to snippets in Markdown files ([ rubocop-md] ( https://github.com/rubocop-hq/rubocop-md ) )
87
+ * forces unit-testing best practices ([ rubocop-rspec] ( https://docs.rubocop.org/projects/rspec/en/latest/ ) )
88
+
89
+ Rubocop config for library and RSpec files should be close to standard one only
90
+ with minor amount of exceptions.
91
+
92
+ Code in Markdown snippets and ` /bin ` folder can ignore more rules. ` /bin ` folder
93
+ contains only development-related scripts and tools so it's ok to ease linter requirements.
94
+
95
+ Rubocop Metrics (ABC-size, method/class length, etc) must not be eased
96
+ globally. Never.
97
+
98
+ ### Reek as the second linter
99
+
100
+ [ Ruby Reek] ( https://github.com/troessner/reek ) is a very aggressive linter that
101
+ forces you to do a clean OOP design.
102
+
103
+ You will be tempted to just shut up this linter many times. But believe me, in 9
104
+ of 10 cases it worth to refactor. And after each such refactoring you will
105
+ understand OOP design better and better.
106
+
107
+ ### Rest of the linters
108
+
109
+ * [ MDL] ( https://github.com/markdownlint/markdownlint ) - for consistent format of Markdown files
110
+ * [ forspell] ( https://github.com/kkuprikov/forspell ) - for spellchecking in comments and markdown files
111
+ * [ inch] ( http://rrrene.org/inch/ ) - for documentation coverage suggestions (the
112
+ only optional linter)
113
+
114
+ ### Default Rake task and CI
115
+
116
+ Default rake task (` bundle exec rake ` ) executes the following checks:
117
+
118
+ * Rubocop
119
+ * Ruby Reek
120
+ * RSpec
121
+ * Spellcheck (forspell)
122
+ * MarkdownLint (mdl)
123
+
124
+ CI is also performing default Rake task. So, if you want to reproduce CI error
125
+ locally - just run ` bundle exec rake ` .
126
+
127
+ Default Rake task is also executed as a pre-push git hook.
128
+
129
+ ### Error reporting
130
+
131
+ I hope no one will argue that clear errors makes development noticeably faster.
132
+ That's why _ each_ exception in ` flows ` should be clear and easy to read.
133
+
134
+ This cannot be tested automatically: you only can test correctness
135
+ automatically, convenience can only be tested manually. That's why when you
136
+ introduce any new ` raise ` you have to:
137
+
138
+ * make an error message clear and descriptive
139
+ * add this error to __ errors demo CLI_ (` bin/errors ` )
140
+ * add this errors to __ all the errors demo_ (` bin/all_the_errors ` )
141
+ * make sure that error is displayed correctly and follows a style of the rest
142
+ of implemented errors
143
+
144
+ ` bin/errors ` is done using [ GLI] ( https://davetron5000.github.io/gli/ ) library,
145
+ run ` bin/errors -h ` to explore possibilities.
146
+
147
+ ### Performance
148
+
149
+ Ruby is slow. Moreover, Ruby is very slow. Yes, again. In the past time we had
150
+ to compare Ruby with Python. Python was faster and that's why people started to
151
+ complain about Ruby performance. That was fixed. But is Ruby fast nowadays? No.
152
+ Because languages like Clojure, Go, Rust, Elixir appeared and in comparison
153
+ with any of these languages Ruby is very very slow.
154
+
155
+ That's why you ** must** be extra careful with performance. Some business
156
+ operations can be executed hundreds or even thousands times per request. Each
157
+ line of code in your abstraction will slow down such request a bit. That's why
158
+ you should think about each line performance.
159
+
160
+ Also, it's nearly impossible to make zero-cost abstractions in Ruby. The best
161
+ thing you can do - to offload calculations to a class loading or initialization
162
+ step. Sacrifice some warm-up time to make runtime performance better.
163
+
164
+ And to compare performance overhead between different ` flows ` abstractions
165
+ and another libraries alternatives a benchmarking CLI was done: ` bin/benchmark ` .
166
+
167
+ This CLI is done using GLI, run ` bin/benchmark -h ` to explore possibilities.
168
+
169
+ So far, ` flows ` offers the best performance among alternatives. And this CLI
170
+ is made to simplify comparison with alternatives and keep ` flows ` the fastest solution.
171
+
172
+ ### Documentation
173
+
174
+ Each public API method or module ** must** be properly documented with examples
175
+ and motivation behind.
176
+
177
+ To run documentation server locally run ` bin/docserver ` .
178
+
179
+ Respect ` @since ` YARD documentation tag. When some module, class or method has any
180
+ API change - you have to provide correct ` @since ` tag value to the documentation.
181
+
182
+ ### Unit test
183
+
184
+ Each public API method or module ** must** be properly tested. Internal modules
185
+ can be tested indirectly through public API.
186
+
187
+ ### Commit naming
188
+
189
+ You ** must** follow [ Conventional Commits] ( https://www.conventionalcommits.org/en/v1.0.0/ ) .
190
+
191
+ ### Changelog
192
+
193
+ Starting from ` v0.4.0 ` [ keep a changelog] ( https://keepachangelog.com/en/1.0.0/ )
194
+ guideline must be met.
195
+
196
+ If you adding something - provide some lines to the unreleased section of the ` CHANGELOG.md ` .
197
+
198
+ ### Versioning
199
+
200
+ The project strictly follows [ SemVer] ( https://semver.org/spec/v2.0.0.html ) .
201
+
202
+ After ` v1.0.0 ` even smallest backward incompatible change will bump major
203
+ version. _ No exceptions._
36
204
37
205
## Readme TODO: list of tasks to accomplish before
38
206
0 commit comments