github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/DEVELOPERS.md (about)

     1  # Developing Qri
     2  
     3  * [Development Setup](#setup)
     4  * [Coding Rules](#rules)
     5  * [Commit Message Guidelines](#commits)
     6  * [Troubleshooting](#troubleshooting)
     7  
     8  ## <a name="setup"></a> Development Setup
     9  
    10  This document describes how to set up your development environment to build and test Qri, and
    11  explains the basic mechanics of using `git`, `golint` and `go test`.
    12  
    13  ### Installing Dependencies
    14  
    15  Before you can build Qri, you must install and configure the following dependencies on your
    16  machine:
    17  
    18  * [Git](http://git-scm.com/): The [Github Guide to
    19    Installing Git][git-setup] is a good source of information.
    20  
    21  * [The Go Programming Language](https://golang.org): see golang.org to get started
    22  
    23  * [golint](https://github.com/golang/lint): Golint is a linter for Go source code
    24  
    25  
    26  ### Forking Qri on Github
    27  
    28  To contribute code to Qri, you must have a GitHub account so you can push code to your own
    29  fork of Qri and open Pull Requests in the [GitHub Repository][github].
    30  
    31  To create a Github account, follow the instructions [here](https://github.com/signup/free).
    32  Afterwards, go ahead and [fork](http://help.github.com/forking) the
    33  [Qri frontend repository][github].
    34  
    35  
    36  ### Building Qri
    37  
    38  
    39  Check out this documentation on [how to build Qri from source](https://github.com/qri-io/qri/README.md#building-from-source)
    40  
    41  
    42  ## <a name="rules"></a> Coding Rules
    43  
    44  When you push your branch to github and open up a pull request, it will automatically trigger  [CircleCI](https://circleci.com/about/) to lint and test your code.
    45  
    46  In order to catch linting and testing errors before pushing the code to github, be sure to run `golint` and `go test`.
    47  
    48  ##### `golint`
    49  
    50  Use `golint` to lint your code. Using `./...` indicates to `golint` that you want to lint each file in the current directory, and each file in each sub-directory you must be in the top level directory of the project in order to lint every file in the project:
    51  ```shell
    52  $ golint ./...
    53  ```
    54  
    55  No output indicates everything is styled correctly. Otherwise, the output will point you to which files/lines need to be changed in order to meet the go linting format.
    56  
    57  ##### `go test`
    58  
    59  Use the built in `go test` command to test your code. Like the above, you can use `./...` to run each test file, if you are in the top most directory of the project:
    60  
    61  ```shell
    62  $ go test ./...
    63  ?     github.com/qri-io/qri [no test files]
    64  ok    github.com/qri-io/qri/actions 1.180s
    65  ok    github.com/qri-io/qri/api 0.702s
    66  ok    github.com/qri-io/qri/base  (cached)
    67  ok    github.com/qri-io/qri/cmd 17.557s
    68  ?     github.com/qri-io/qri/cmd/generate  [no test files]
    69  ok    github.com/qri-io/qri/config  (cached)
    70  ?     github.com/qri-io/qri/config/test [no test files]
    71  ?     github.com/qri-io/qri/docs  [no test files]
    72  ok    github.com/qri-io/qri/lib 1.064s
    73  ok    github.com/qri-io/qri/p2p (cached)
    74  ok    github.com/qri-io/qri/p2p/test  (cached)
    75  ok    github.com/qri-io/qri/repo  (cached)
    76  ok    github.com/qri-io/qri/repo/fs (cached)
    77  ok    github.com/qri-io/qri/profile  (cached)
    78  ok    github.com/qri-io/qri/repo/test (cached)
    79  ok    github.com/qri-io/qri/rev (cached)
    80  ```
    81  
    82  Depending on what work you are doing and what has changed, tests may take up to a minute.
    83  
    84  If everything is marked "ok", you are in the clear. Any extended output is a sign that a test has failed. Be sure to fix any bugs that are indicated or tests that no longer pass.
    85  
    86  You may run just the tests for a specific package by running the `go test` command from that directory. You may also target specific tests to run based off a regex match of the test's name. For example, running `go test --run TestSetup` will execute any test that has the TestSetup prefix (tests named TestsSetupOne, TestSetup, and TestSetupWithAnotherName would all run). To see a verbose printout of all tests regardless of pass/skip/fail status, you may add the `-v` flag.
    87  
    88  #### CLI Help Style
    89  
    90  When creating or editing CLI commands, we try and follow a few style rules to keep things consistent:
    91  
    92  - Make sure to mention all the positional arguments in the `Use` string. Choose descriptive names in all capital letters, and put optional arguments in square brackets.
    93  
    94  - Always include a `Short` description. It should be a phrase, not a sentence: it starts with a lower-case letter and ends without a period.
    95  
    96  - Long descriptions should be full sentences and start with a captial letter unless the first word is the name of a command or special word that should never be upper-case.
    97  
    98  - Examples should be…
    99      - Indented with two spaces.
   100      - Example descriptions start with `#`.
   101      - Lines that should be typed start with `$`.
   102  
   103  - Long text fields should not have leading or trailing blank lines.
   104  
   105  - Try to use active, rather than passive, voice wherever possible.
   106  
   107  - Use the `Args` field for limiting the number of arguments (or even better, for doing more detailed validation). Cobra has [some nice built-ins for this](https://github.com/spf13/cobra/#positional-and-custom-arguments).
   108  
   109  Example:
   110  
   111  ```go
   112  	cmd := &cobra.Command{
   113  		Use:   "add DATASET [DATASET...]",
   114  		Short: "add datasets from other peers",
   115  		Long: `Add retrieves datasets owned by other peers and adds them to your repo. 
   116  The reference names of the datasets will remain the same, including
   117  the name of the peer that originally added the dataset. You must have 
   118  ` + "`qri connect`" + ` running in another terminal to use this command.`,
   119  		Example: `  # Add a dataset named their_data, owned by other_peer:
   120    $ qri add other_peer/their_data`,
   121  		Annotations: map[string]string{
   122  			"group": "dataset",
   123  		},
   124  		RunE: func(cmd *cobra.Command, args []string) error {
   125  			if err := o.Complete(f); err != nil {
   126  				return err
   127  			}
   128  			return o.Run(args)
   129  		},
   130  	}
   131  ```
   132  
   133  
   134  ## <a name="commits"></a> Git Commit Guidelines
   135  
   136  We have very precise rules over how our git commit messages can be formatted.  This leads to **more
   137  readable messages** that are easy to follow when looking through the **project history**.  But also,
   138  we use the git commit messages to **generate the Qri change log**.
   139  
   140  ### Commit Message Format
   141  Each commit message consists of a **header**, a **body** and a **footer**.  The header has a special
   142  format that includes a **type**, a **scope** and a **subject**:
   143  
   144  ```
   145  <type>(<scope>): <subject>
   146  <BLANK LINE>
   147  <body>
   148  <BLANK LINE>
   149  <footer>
   150  ```
   151  
   152  The **header** is mandatory and the **scope** of the header is optional.
   153  
   154  Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
   155  to read on GitHub as well as in various git tools.
   156  
   157  ### Revert
   158  If the commit reverts a previous commit, it should begin with `revert: `, followed by the header
   159  of the reverted commit.
   160  In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit
   161  being reverted.
   162  A commit with this format is automatically created by the [`git revert`][git-revert] command.
   163  
   164  ### Type
   165  Must be one of the following:
   166  
   167  * **feat**: A new feature
   168  * **fix**: A bug fix
   169  * **docs**: Documentation only changes
   170  * **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
   171    semi-colons, etc)
   172  * **refactor**: A code change that neither fixes a bug nor adds a feature
   173  * **perf**: A code change that improves performance
   174  * **test**: Adding missing or correcting existing tests
   175  * **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
   176    generation
   177  
   178  ### Scope
   179  The scope could be anything specifying place of the commit change. For example, if I am refactoring something in the `api` package, I may start my commit with "refactor(api)". If it's something more specific, like the ListHandler, I may write "refactor(api/ListHandler)", or something similar. As long as it gets the point across on the scope of the refactor.
   180  
   181  You can use `*` when the change affects more than a single scope.
   182  
   183  ### Subject
   184  The subject contains succinct description of the change:
   185  
   186  * use the imperative, present tense: "change" not "changed" nor "changes"
   187  * don't capitalize first letter
   188  * no dot (.) at the end
   189  
   190  ### Body
   191  Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
   192  The body should include the motivation for the change and contrast this with previous behavior.
   193  
   194  ### Footer
   195  The footer should contain any information about **Breaking Changes** and is also the place to
   196  [reference GitHub issues that this commit closes][closing-issues].
   197  
   198  **Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
   199  The rest of the commit message is then used for this.
   200  
   201  A detailed explanation can be found in this [document][commit-message-format].
   202  
   203  
   204  [closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
   205  [commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
   206  [git-revert]: https://git-scm.com/docs/git-revert
   207  [git-setup]: https://help.github.com/articles/set-up-git
   208  [github]: https://github.com/qri-io/frontend
   209  [style]: https://standardjs.com
   210  [yarn-install]: https://yarnpkg.com/en/docs/install
   211  
   212  
   213  ## <a name="troubleshooting"> Troubleshooting
   214  
   215  #### "Too Many Open Files" on MacOS
   216  
   217  If, while running the test suite, you get failing tests with "too many open files", you may need to adjust the number of files your shell process is willing to open. This is particularly common with the `p2p` and `cmd` pacakges. Both rely heavily on interacting temporary directories on the file system to run tests.
   218  
   219  Often this is caused by having too low a file limit for your shell. You can use the [`ulimit` command](https://ss64.com/osx/ulimit.html) to check out or change the limits. Try the following command to set the shell limit to 1000 open files:
   220  
   221  ```
   222  ulimit -S -n 1000
   223  ```
   224  
   225  We recommend a ulimit value of at least 1000; feel free to go higher if you need. Some other software require values as high as 10000 to avoid the max open file issue.
   226  
   227  ###### This documentation has been adapted from the [Data Together](https://github.com/datatogether/datatogether), [Hyper](https://github.com/zeit/hyper), and [AngularJS](https://github.com/angular/angularJS) documentation, all of which are projects we :heart: