|
1 | | -Contributing to GRDB |
2 | | -==================== |
| 1 | +How you can Contribute |
| 2 | +====================== |
3 | 3 |
|
4 | | -**Thank you for coming!** |
| 4 | +- [Contribute to the GRDB codebase] |
| 5 | +- [Answer issues and contribute to discussions] |
| 6 | +- [Financial support and sponsoring] |
5 | 7 |
|
6 | | -This guide is a set of tips and guidelines for contributing to the GitHub repository [groue/GRDB.swift](https://github.com/groue/GRDB.swift). |
| 8 | +## Contribute to the GRDB codebase |
7 | 9 |
|
8 | | -- [Report Bugs] |
9 | | -- [Ask Questions] |
10 | | -- [Suggest an Enhancement] |
11 | | -- [Submit a Pull Request] |
12 | | -- [Sponsoring and Professional Support] |
13 | | -- [Suggested Contributions] |
14 | | -- [Non-Goals] |
| 10 | +1. **Install** the following tools: |
15 | 11 |
|
| 12 | + - For running tests: |
| 13 | + - Ruby |
| 14 | + - [CocoaPods](https://cocoapods.org) (gem) |
| 15 | + - [xcpretty](https://github.com/xcpretty/xcpretty) (gem) |
| 16 | + - For contributing code: |
| 17 | + - [Swiftlint](https://github.com/realm/SwiftLint) (present in the `$PATH` or in `/opt/homebrew/bin/`) |
| 18 | + - For generating documentation: |
| 19 | + - [Jazzy](https://github.com/realm/jazzy) (gem) |
16 | 20 |
|
17 | | -### Report Bugs |
| 21 | +2. **Clone the `development` branch on your machine.** |
18 | 22 |
|
19 | | -Please make sure the bug is not already reported by searching existing [issues](https://github.com/groue/GRDB.swift/issues). |
| 23 | +3. **Run `make SQLiteCustom` in the terminal**, at the root of the repository. |
| 24 | + |
| 25 | + This step is not strictly necessary if you do not plan to work on custom SQLite builds. But it will avoid a lot of warnings in Xcode. |
20 | 26 |
|
21 | | -If you're unable to find an existing issue addressing the problem, [open a new one](https://github.com/groue/GRDB.swift/issues/new). Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring. |
| 27 | +4. **Open `GRDB.xcworkspace`.** This workspace contains six projects: |
| 28 | + |
| 29 | + - `GRDB.xcodeproj`: the project which contains the GRDB framework and test targets. The sources are organized in two groups: |
| 30 | + - `GRDB`: GRDB sources |
| 31 | + - `Tests`: GRDB tests |
| 32 | + - `GRDBCustom.xcodeproj`: the project which builds GRDB with a custom SQLite build. |
| 33 | + - `GRDBProfiling.xcodeproj`: a project which helps profiling GRDB with Instruments. No code here is really precious. |
| 34 | + - `GRDBDemoiOS.xcodeproj`, `GRDBCombineDemo.xcodeproj`, `GRDBAsyncDemo.xcodeproj`: the demo apps. |
| 35 | + |
| 36 | + To work with `GRDBCustom.xcodeproj`: |
| 37 | + |
| 38 | + - Make sure Xcode is installed in `/Applications`. |
| 39 | + - Run `make SQLiteCustom` in the terminal so that SQLite sources are present. |
22 | 40 |
|
| 41 | +5. **Run tests** |
| 42 | + |
| 43 | + You can run tests from `GRDB.xcworkspace`, after selecting your target (GRDBOSX, GRDBiOS, GRDBtvOS, from `GRDB.xcodeproj` or `GRDBCustom.xcodeproj`). |
| 44 | + |
| 45 | + Other tests are available in the terminal: |
| 46 | + |
| 47 | + ```sh |
| 48 | + # Run the full test suite with the current Xcode version (this takes time). |
| 49 | + make test |
| 50 | + |
| 51 | + # Run only a few tests (this takes less time). |
| 52 | + make smokeTest |
| 53 | + ``` |
23 | 54 |
|
24 | | -### Ask Questions |
| 55 | +6. **Please respect the existing coding style** |
| 56 | + |
| 57 | + - Get familiar with the [Swift API Design Guidelines](https://www.swift.org/documentation/api-design-guidelines/). |
| 58 | + - Spaces, not tabs. |
| 59 | + - Whitespace-only lines are not trimmed. |
| 60 | + - Documentation comments are hard-wrapped at column 80 (Xcode > Preferences > Text Editing > Display > [X] Page guide at column: 80). |
| 61 | + - No Swiftlint warning after a build. |
25 | 62 |
|
26 | | -The information you are looking for is maybe already available. Check out: |
27 | 63 |
|
28 | | -- the [FAQ](README.md#faq) |
29 | | -- the [general documentation](README.md#documentation) |
30 | | -- the [answered questions](https://github.com/groue/GRDB.swift/issues?utf8=✓&q=label%3Aquestion+) |
| 64 | +7. **Please provide documentation for your changes** |
31 | 65 |
|
32 | | -If not, your questions are welcome in the [GRDB forums](https://forums.swift.org/c/related-projects/grdb), or in a new [GitHub issue](https://github.com/groue/GRDB.swift/issues/new). |
| 66 | + GRDB documentation is provided as reference (inline doc comments starting with `///`, see [Documentation Comment Syntax](https://github.com/apple/swift/blob/main/docs/DocumentationComments.md)), and guides ([README.md](README.md) and the [Documentation](Documentation) folder). |
| 67 | + |
| 68 | + GRDB is "documentation-driven", which means that nothing ships until it is supported by documentation that makes sense. Documentation makes sense when someone who is not you is able to figure out what is the purpose of your contribution, how to use it, and what are its eventual caveats and corner cases. When the documentation is hard to write, or reveals too many caveats, it is the sign that the api needs to be fixed. |
| 69 | + |
| 70 | +8. **Open a pull request with your changes!** |
33 | 71 |
|
| 72 | +9. **If you are granted a push access to the repository**, check [ReleaseProcess.md](Documentation/ReleaseProcess.md) in order to publish a new GRDB version. |
34 | 73 |
|
35 | | -### Suggest an Enhancement |
36 | 74 |
|
37 | | -Your idea may already be listed in [Suggested Contributions], waiting for someone to pick it up. |
| 75 | +## Answer issues and contribute to discussions |
38 | 76 |
|
39 | | -If not, contact [@groue](http://twitter.com/groue) on Twitter, or [open a new issue](https://github.com/groue/GRDB.swift/issues/new). |
| 77 | +Answering [issues](https://github.com/groue/GRDB.swift/issues), participating in [discussions](https://github.com/groue/GRDB.swift/discussions) and in the [forum](https://forums.swift.org/c/related-projects/grdb/36) is a great way to help, get familiar with the library, and shape its direction. |
40 | 78 |
|
41 | 79 |
|
42 | | -### Submit a Pull Request |
| 80 | +## Financial support and sponsoring |
43 | 81 |
|
44 | | -Discuss your idea first, so that your changes have a good chance of being merged in. |
| 82 | +GRDB is free, and openly developed by its contributors, on their free time, according to their will, needs, and availability. It is not controlled by any company. |
45 | 83 |
|
46 | | -Submit your pull request against the `development` branch. |
| 84 | +Support is free as well, as long as it happens publicly, and is available to everyone as well as internet search engines. This excludes the private channels of social networks, closed environments such as Slack, etc. |
47 | 85 |
|
48 | | -Pull requests that include tests for modified and new functionalities, inline documentation, and relevant updates to the main README.md are merged faster, because you won't have to wait for somebody else to complete your contribution. |
| 86 | +When you have specific development or support needs, please send an email to [Gwendal Roué](mailto:gr@pierlis.com) so that we can enter a regular business relationship through the [Pierlis](http://pierlis.com/) company, based in Paris, France. |
49 | 87 |
|
| 88 | +You can also [sponsor @groue via GitHub](https://github.com/sponsors/groue). |
50 | 89 |
|
51 | | -### Sponsoring and Professional Support |
52 | 90 |
|
53 | | -GRDB is free. It is openly developed by its contributors, on their free time, according to their will, needs, and availability. It is not controlled by any company. |
54 | | - |
55 | | -When you have specific development or support needs, and are willing to financially contribute to GRDB, please send an email to [Gwendal Roué](mailto:gr@pierlis.com) so that we can enter a regular business relationship through the [Pierlis](http://pierlis.com/) company, based in Paris, France. |
56 | | - |
57 | | - |
58 | | -## Suggested Contributions |
59 | | - |
60 | | -You'll find below various ideas for enhancing and extending GRDB, in various areas. Your ideas can be added to this list: [Suggest an Enhancement]. |
61 | | - |
62 | | -Legend: |
63 | | - |
64 | | -- :baby: **Starter Task**: get familiar with GRDB internals |
65 | | -- :muscle: **Hard**: there are implementation challenges |
66 | | -- :pencil: **Documentation** |
67 | | -- :fire: **Experimental**: let's invent the future! |
68 | | -- :bowtie: **Public API Challenge**: we'll need a very good public API |
69 | | -- :hammer: **Tooling**: GRDB and its environment |
70 | | -- :question: **Unknown Difficulty** |
71 | | - |
72 | | -The ideas, in alphabetical order: |
73 | | - |
74 | | -- [Associations] |
75 | | -- [CloudKit] |
76 | | -- [Concurrency] |
77 | | -- [Custom FTS5 Auxiliary Functions] |
78 | | -- [Date and Time Functions] |
79 | | -- [Decode NSDecimalNumber from Text Columns] |
80 | | -- [Documentation] |
81 | | -- [Full Text Search Demo Application] |
82 | | -- [JSON] |
83 | | -- [Linux] |
84 | | -- [More SQL Generation] |
85 | | -- [SQL Console in the Debugger] |
86 | | -- [SQLCipher in a Shared App Container] |
87 | | -- [Typed Expressions] |
88 | | - |
89 | | - |
90 | | -### Associations |
91 | | - |
92 | | -:bowtie: Public API Challenge :muscle: Hard :fire: Experimental |
93 | | - |
94 | | -Associations can be enhanced in several ways. See the "Known Issues" chapter of the [Associations Guide](Documentation/AssociationsBasics.md) |
95 | | - |
96 | | - |
97 | | -### CloudKit |
98 | | - |
99 | | -:bowtie: Public API Challenge :question: Unknown Difficulty :fire: Experimental |
100 | | - |
101 | | -Integration with [CloudKit](https://developer.apple.com/icloud/cloudkit/) is a rich, interesting, and useful topic. |
102 | | - |
103 | | -It is likely that CloudKit support would exist in a separate companion library. |
104 | | - |
105 | | -Starting points: |
106 | | - |
107 | | -- [caiyue1993/IceCream](https://github.com/caiyue1993/IceCream) |
108 | | -- [mentrena/SyncKit](https://github.com/mentrena/SyncKit) |
109 | | -- [nofelmahmood/Seam](https://github.com/nofelmahmood/Seam) |
110 | | -- [Sorix/CloudCore](https://github.com/Sorix/CloudCore) |
111 | | -- [Synchronizing data with CloudKit](https://medium.com/@guilhermerambo/synchronizing-data-with-cloudkit-94c6246a3fda) |
112 | | -- WWDC CloudKit sessions, including [CloudKit Best Practices](https://developer.apple.com/videos/play/wwdc2016/231/) |
113 | | - |
114 | | - |
115 | | -### Concurrency |
116 | | - |
117 | | -:bowtie: Public API Challenge :muscle: Hard :pencil: Documentation |
118 | | - |
119 | | -GRDB has a strong focus on safe concurrency. Not only safe as "does not crash", but safe as "actively protects your application data". The topic is discussed in (too) many places: |
120 | | - |
121 | | -- [Concurrency Guide](Documentation/Concurrency.md) |
122 | | -- [Why Adopt GRDB?](https://github.com/groue/GRDB.swift/blob/master/Documentation/WhyAdoptGRDB.md#strong-and-clear-multi-threading-guarantees) |
123 | | -- [Four different ways to handle SQLite concurrency](https://medium.com/@gwendal.roue/four-different-ways-to-handle-sqlite-concurrency-db3bcc74d00e) |
124 | | -- [Good Practices for Designing Record Types](https://github.com/groue/GRDB.swift/blob/master/Documentation/GoodPracticesForDesigningRecordTypes.md#fetch-in-time) |
125 | | -- [Comparison between GRDB and Core Data concurrency](https://github.com/groue/GRDB.swift/issues/405) |
126 | | - |
127 | | -Despite this abundant documention, I regularly meet developers who don't think about eventual multi-threading gotchas, and don't design their application against them. |
128 | | - |
129 | | -This can be explained: |
130 | | - |
131 | | -- Some developers disregard potential multi-threading bugs such as data races, even if the fix is "easy". Such bugs may never happen during the development of an application. They may only impact a few users in production. It is always easier not to think about them. |
132 | | - |
133 | | -- Databases are often seen as plain CRUD tools, and some developers are not familiar with topics like isolation or transactions. This is especially true for developers who have experience in a managed ORM such as Core Data or Realm, or web frameworks like Rails or Django: switching to an unmanaged relational database is not an easy task. |
134 | | - |
135 | | -- Not all applications need to be multi-threaded. |
136 | | - |
137 | | -And this creates improvement opportunities: |
138 | | - |
139 | | -- Better documentation of GRDB concurrency |
140 | | - |
141 | | -- The introduction of an "ultra-safe" concurrency mode. Maybe something that restricts all database accesses to the main thread, like [FCModel](https://github.com/marcoarment/FCModel). Maybe in a separate companion library. |
142 | | - |
143 | | - |
144 | | -### Custom FTS5 Auxiliary Functions |
145 | | - |
146 | | -:question: Unknown Difficulty |
147 | | - |
148 | | -The SQLite documentation provides [this description](https://www.sqlite.org/fts5.html) of FTS5 auxiliary functions: |
149 | | - |
150 | | -> An application may use FTS5 auxiliary functions to retrieve extra information regarding the matched row. For example, an auxiliary function may be used to retrieve a copy of a column value for a matched row with all instances of the matched term surrounded by html <b></b> tags. |
151 | | -
|
152 | | -Applications can define their own [custom FTS5 auxiliary functions](https://www.sqlite.org/fts5.html#custom_auxiliary_functions) with SQLite, but GRDB does not yet provide any Swift API for that. |
153 | | - |
154 | | -See issue [#421](https://github.com/groue/GRDB.swift/issues/421) for more information. |
155 | | - |
156 | | - |
157 | | -### Date and Time Functions |
158 | | - |
159 | | -:baby: Starter Task |
160 | | - |
161 | | -Believe it or not, no one has ever asked support for SQLite [Date And Time Functions](https://www.sqlite.org/lang_datefunc.html). There is surely room for a nice Swift API that makes them available. |
162 | | - |
163 | | -For more ideas, see: |
164 | | - |
165 | | -- [SQLite Core Functions](https://www.sqlite.org/lang_corefunc.html) |
166 | | -- [SQLite Aggregate Functions](https://www.sqlite.org/lang_aggfunc.html) |
167 | | -- [SQLite JSON functions](https://www.sqlite.org/json1.html) and [JSON], below. |
168 | | - |
169 | | -Functions are defined in [GRDB/QueryInterface/Support/SQLFunctions.swift](https://github.com/groue/GRDB.swift/blob/master/GRDB/QueryInterface/Support/SQLFunctions.swift). |
170 | | - |
171 | | - |
172 | | -### Decode NSDecimalNumber from Text Columns |
173 | | - |
174 | | -:baby: Starter Task |
175 | | - |
176 | | -NSDecimalNumber currently only decodes integer and float decimal values. It would be nice if NSDecimalNumber would decode text values as well: |
177 | | - |
178 | | -```swift |
179 | | -let number = try NSDecimalNumber.fetchOne(db, "SELECT '12.3'")! |
180 | | -print(number) // prints 12.3 |
181 | | -``` |
182 | | - |
183 | | -NSNumber and NSDecimalNumber support is found in [GRDB/Core/Support/Foundation/NSNumber.swift](https://github.com/groue/GRDB.swift/blob/master/GRDB/Core/Support/Foundation/NSNumber.swift) |
184 | | - |
185 | | - |
186 | | -### Documentation |
187 | | - |
188 | | -:baby: Starter Task :pencil: Documentation |
189 | | - |
190 | | -General documentation can always be improved so that it reaches its goal: helping developers building applications. |
191 | | - |
192 | | -- English: the documentation has mostly been written by [@groue](http://github.com/groue) who is not a native English speaker. |
193 | | -- Clarity: any chapter that is not crystal clear should be enhanced. |
194 | | -- Audience: documentation should talk to several populations of developers, from beginners who need positive guidance, to SQLite experts who need to build trust. |
195 | | -- Typos |
196 | | -- Inaccuracies |
197 | | -- etc. |
198 | | - |
199 | | -Inline documentation, the one which is embedded right into the source code and is displayed by Xcode when one alt-clicks an identifier, deserves the same care. |
200 | | - |
201 | | -If you are a good writer, your help will be very warmly welcomed. |
202 | | - |
203 | | - |
204 | | -### Full Text Search Demo Application |
205 | | - |
206 | | -:baby: Starter Task :pencil: Documentation |
207 | | - |
208 | | -There exists a GRDB demo app for the FTS5 full-text engine: [WWDCCompanion](https://github.com/groue/WWDCCompanion). |
209 | | - |
210 | | -This application downloads the transcripts of WWDC sessions, and lets its user type keywords and find matching sessions, sorted by relevance. |
211 | | - |
212 | | -The problem is that this demo app breaks every year :sweat_smile: |
213 | | - |
214 | | -We'd need instead to index a stable corpus, in order to ease the maintenance of this demo app. |
215 | | - |
216 | | - |
217 | | -### JSON |
218 | | - |
219 | | -:bowtie: Public API Challenge :baby: Starter Task |
220 | | - |
221 | | -[Codable Records] are granted with automatic JSON encoding and decoding of their complex properties. But there is still room for improvements. For example, could we put the [SQLite JSON1 extension](https://www.sqlite.org/json1.html) to some good use? |
222 | | - |
223 | | - |
224 | | -### Linux |
225 | | - |
226 | | -:muscle: Hard :hammer: Tooling |
227 | | - |
228 | | -Swift on Linux is currently focused on the server (Vapor, Perfect, Kitura). While general server support is a [non-goal](#non-goals) of GRDB, there exists read-only servers, and Linux GUI applications, too. Linux is thus a desired platform. |
229 | | - |
230 | | - |
231 | | -### More SQL Generation |
232 | | - |
233 | | -:bowtie: Public API Challenge :question: Unknown Difficulty |
234 | | - |
235 | | -There are several SQLite features that GRDB could natively support: |
236 | | - |
237 | | -- [ALTER TABLE ... RENAME COLUMN ... TO ...](https://www.sqlite.org/lang_altertable.html) |
238 | | -- [ATTACH DATABASE](https://www.sqlite.org/lang_attach.html) |
239 | | -- [UPSERT](https://www.sqlite.org/lang_UPSERT.html) |
240 | | -- [INSERT INTO ... SELECT ...](https://www.sqlite.org/lang_insert.html) |
241 | | -- [WITH RECURSIVE ...](https://www.sqlite.org/lang_with.html) |
242 | | -- [RTree](https://sqlite.org/rtree.html) |
243 | | -- [Windows Functions](https://www.sqlite.org/windowfunctions.html) |
244 | | -- [More ideas](https://www.sqlite.org/lang.html) |
245 | | - |
246 | | -See [issue #575](https://github.com/groue/GRDB.swift/issues/575) for more information and guidance about the implementation of extra table alterations. |
247 | | - |
248 | | - |
249 | | -### SQL Console in the Debugger |
250 | | - |
251 | | -:question: Unknown Difficulty :hammer: Tooling |
252 | | - |
253 | | -Sometimes one needs, in lldb, a console similar to the [Command Line Shell For SQLite](https://www.sqlite.org/cli.html). |
254 | | - |
255 | | - |
256 | | -### SQLCipher in a Shared App Container |
257 | | - |
258 | | -:question: Unknown Difficulty |
259 | | - |
260 | | -See issue [#302](https://github.com/groue/GRDB.swift/issues/302). |
261 | | - |
262 | | - |
263 | | -### Typed Expressions |
264 | | - |
265 | | -:bowtie: Public API Challenge :muscle: Hard :fire: Experimental |
266 | | - |
267 | | -The compiler currently does not spot type mistakes in query interface requests: |
268 | | - |
269 | | -```swift |
270 | | -Player.filter(Column("name") == "Arthur") // OK |
271 | | -Player.filter(Column("name") == 1) // Sure |
272 | | -Player.filter(Column("name") == Date()) // Legit |
273 | | -``` |
274 | | - |
275 | | -This weak typing also prevents natural-looking Swift code from producing the expected results: |
276 | | - |
277 | | -```swift |
278 | | -// Performs arithmetic additions instead of string concatenation |
279 | | -Player.select(Column("firstName") + " " + Column("lastName")) |
280 | | -``` |
281 | | - |
282 | | -It would be interesting to see what typed expressions could bring to GRDB. |
283 | | - |
284 | | - |
285 | | -## Non-Goals |
286 | | - |
287 | | -GRDB is a "toolkit for SQLite databases, with a focus on application development". |
288 | | - |
289 | | -This definition is the reason why GRDB can provide key features such as sharp multi-threading, database observation, and first-class support for raw SQL. |
290 | | - |
291 | | -Features that blur this focus are non-goals: |
292 | | - |
293 | | -- Support for MySQL, PostgreSQL, or other database engines |
294 | | -- Support for Servers |
295 | | - |
296 | | - |
297 | | -[Ask Questions]: #ask-questions |
298 | | -[Associations]: #associations |
299 | | -[CloudKit]: #cloudkit |
300 | | -[Codable Records]: README.md#codable-records |
301 | | -[Custom FTS5 Auxiliary Functions]: #custom-fts5-auxiliary-functions |
302 | | -[Database Observation]: #database-observation |
303 | | -[Date and Time Functions]: #date-and-time-functions |
304 | | -[Decode NSDecimalNumber from Text Columns]: #decode-nsdecimalnumber-from-text-columns |
305 | | -[Documentation]: #documentation |
306 | | -[Full Text Search Demo Application]: #full-text-search-demo-application |
307 | | -[How is the Library Organized?]: Documentation/LibraryOrganization.md |
308 | | -[How is the Repository Organized?]: Documentation/RepositoryOrganization.md |
309 | | -[JSON]: #json |
310 | | -[Linux]: #linux |
311 | | -[More SQL Generation]: #more-sql-generation |
312 | | -[Records: Splitting Database Encoding from Ability to Write in the Database]: #records-splitting-database-encoding-from-ability-to-write-in-the-database |
313 | | -[Non-Goals]: #non-goals |
314 | | -[Report Bugs]: #report-bugs |
315 | | -[RxGRDB]: http://github.com/RxSwiftCommunity/RxGRDB |
316 | | -[Concurrency]: Documentation/Concurrency.md |
317 | | -[Sponsoring and Professional Support]: #sponsoring-and-professional-support |
318 | | -[SQL Console in the Debugger]: #sql-console-in-the-debugger |
319 | | -[SQLCipher in a Shared App Container]: #sqlcipher-in-a-shared-app-container |
320 | | -[Submit a Pull Request]: #submit-a-pull-request |
321 | | -[Suggest an Enhancement]: #suggest-an-enhancement |
322 | | -[Suggested Contributions]: #suggested-contributions |
323 | | -[Typed Expressions]: #typed-expressions |
324 | | -[persistence methods]: README.md#persistence-methods |
325 | | -[PersistableRecord]: README.md#persistablerecord-protocol |
326 | | -[Record Comparison]: README.md#record-comparison |
327 | | -[Requesting Associated Records]: Documentation/AssociationsBasics.md#requesting-associated-records |
328 | | -[ValueObservation]: README.md#valueobservation |
| 91 | +[Contribute to the GRDB codebase]: #contribute-to-the-grdb-codebase |
| 92 | +[Answer issues and contribute to discussions]: #answer-issues-and-contribute-to-discussions |
| 93 | +[Financial support and sponsoring]: #financial-support-and-sponsoring |
0 commit comments