github.com/lyeb/hugo@v0.47.1/docs/content/en/contribute/development.md (about)

     1  ---
     2  title: Contribute to Hugo Development
     3  linktitle: Development
     4  description: Hugo relies heavily on contributions from the open source community.
     5  date: 2017-02-01
     6  publishdate: 2017-02-01
     7  lastmod: 2017-02-01
     8  categories: [contribute]
     9  keywords: [dev,open source]
    10  authors: [digitalcraftsman]
    11  menu:
    12    docs:
    13      parent: "contribute"
    14      weight: 10
    15  weight: 10
    16  sections_weight: 10
    17  draft: false
    18  aliases: [/contribute/development/]
    19  toc: true
    20  ---
    21  
    22  ## Introduction
    23  
    24  Hugo is an open-source project and lives by the work of its [contributors][]. There are plenty of [open issues][issues], and we need your help to make Hugo even more awesome. You don't need to be a Go guru to contribute to the project's development.
    25  
    26  ## Assumptions
    27  
    28  This contribution guide takes a step-by-step approach in hopes of helping newcomers. Therefore, we only assume the following:
    29  
    30  * You are new to Git or open-source projects in general
    31  * You are a fan of Hugo and enthusiastic about contributing to the project
    32  
    33  {{% note "Additional Questions?" %}}
    34  If you're struggling at any point in this contribution guide, reach out to the Hugo community in [Hugo's Discussion forum](https://discourse.gohugo.io).
    35  {{% /note %}}
    36  
    37  ## Install Go
    38  
    39  The installation of Go should take only a few minutes. You have more than one option to get Go up and running on your machine.
    40  
    41  If you are having trouble following the installation guides for Go, check out [Go Bootcamp, which contains setups for every platform][gobootcamp] or reach out to the Hugo community in the [Hugo Discussion Forums][forums].
    42  
    43  ### Install Go From Source
    44  
    45  [Download the latest stable version of Go][godl] and follow the official [Go installation guide][goinstall].
    46  
    47  Once you're finished installing Go, let's confirm everything is working correctly. Open a terminal---or command line under Windows--and type the following:
    48  
    49  ```
    50  go version
    51  ```
    52  
    53  You should see something similar to the following written to the console. Note that the version here reflects the most recent version of Go as of the last update for this page:
    54  
    55  ```
    56  go version go1.8 darwin/amd64
    57  ```
    58  
    59  Next, make sure that you set up your `GOPATH` [as described in the installation guide][setupgopath].
    60  
    61  You can print the `GOPATH` with `echo $GOPATH`. You should see a non-empty string containing a valid path to your Go workspace; for example:
    62  
    63  ```
    64  /Users/<yourusername>/Code/go
    65  ```
    66  
    67  ### Install Go with Homebrew
    68  
    69  If you are a MacOS user and have [Homebrew](https://brew.sh/) installed on your machine, installing Go is as simple as the following command:
    70  
    71  {{< code file="install-go.sh" >}}
    72  brew install go
    73  {{< /code >}}
    74  
    75  ### Install Go via GVM
    76  
    77  More experienced users can use the [Go Version Manager][gvm] (GVM). GVM allows you to switch between different Go versions *on the same machine*. If you're a beginner, you probably don't need this feature. However, GVM makes it easy to upgrade to a new released Go version with just a few commands.
    78  
    79  GVM comes in especially handy if you follow the development of Hugo over a longer period of time. Future versions of Hugo will usually be compiled with the latest version of Go. Sooner or later, you will have to upgrade if you want to keep up.
    80  
    81  ## Create a GitHub Account
    82  
    83  If you're going to contribute code, you'll need to have an account on GitHub. Go to [www.github.com/join](https://github.com/join) and set up a personal account.
    84  
    85  ## Install Git on Your System
    86  
    87  You will need to have Git installed on your computer to contribute to Hugo development. Teaching Git is outside the scope of the Hugo docs, but if you're looking for an excellent reference to learn the basics of Git, we recommend the [Git book][gitbook] if you are not sure where to begin. We will include short explainations of the Git commands in this document.
    88  
    89  Git is a [version control system](https://en.wikipedia.org/wiki/Version_control) to track the changes of source code. Hugo depends on smaller third-party packages that are used to extend the functionality. We use them because we don't want to reinvent the wheel.
    90  
    91  Go ships with a sub-command called `get` that will download these packages for us when we setup our working environment. The source code of the packages is tracked with Git. `get` will interact with the Git servers of the package hosters in order to fetch all dependencies.
    92  
    93  Move back to the terminal and check if Git is already installed. Type in `git version` and press enter. You can skip the rest of this section if the command returned a version number. Otherwise [download](https://git-scm.com/downloads) the latest version of Git and follow this [installation guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git).
    94  
    95  Finally, check again with `git version` if Git was installed successfully.
    96  
    97  ### Git Graphical Front Ends
    98  
    99  There are several [GUI clients](https://git-scm.com/downloads/guis) that help you to operate Git. Not all are available for all operating systems and maybe differ in their usage. Because of this we will document how to use the command line, since the commands are the same everywhere.
   100  
   101  ### Install Hub on Your System (Optional)
   102  
   103  Hub is a great tool for working with GitHub. The main site for it is [hub.github.com](https://hub.github.com/). Feel free to install this little Git wrapper.
   104  
   105  On a Mac, you can install [Hub](https://github.com/github/hub) using [Homebrew](https://brew.sh):
   106  
   107  ```
   108  brew install hub
   109  ```
   110  
   111  Now we'll create an [alias in Bash](http://tldp.org/LDP/abs/html/aliases.html) so that typing `git` actually runs `Hub`:
   112  
   113  ```
   114  echo "alias git='hub'" >> ~/.bash_profile
   115  ```
   116  
   117  Confirm the installation:
   118  
   119  ```
   120  git version 2.6.3
   121  hub version 2.2.2
   122  ```
   123  
   124  ## Set up your working copy
   125  
   126  You set up the working copy of the repository locally on your computer. Your local copy of the files is what you'll edit, compile, and end up pushing back to GitHub. The main steps are cloning the repository and creating your fork as a remote.
   127  
   128  ### Clone the repository
   129  
   130  We assume that you've set up your `GOPATH` (see the section above if you're unsure about this). You should now copy the Hugo repository down to your computer. You'll hear this called "clone the repo". GitHub's [help pages](https://help.github.com/articles/cloning-a-repository/) give us a short explanation:
   131  
   132  > When you create a repository on GitHub, it exists as a remote repository. You can create a local clone of your repository on your computer and sync between the two locations.
   133  
   134  We're going to clone the [master Hugo repository](https://github.com/gohugoio/hugo). That seems counter-intuitive, since you won't have commit rights on it. But it's required for the Go workflow. You'll work on a copy of the master and push your changes to your own repository on GitHub.
   135  
   136  So, let's clone that master repository:
   137  
   138  ```
   139  go get -v -u github.com/gohugoio/hugo
   140  ```
   141  
   142  Hugo relies on [Testify](https://github.com/stretchr/testify) for testing Go code. If you don't already have it, get the Testify testing tools:
   143  
   144  ```
   145  go get github.com/stretchr/testify
   146  ```
   147  
   148  ### Fork the repository
   149  
   150  If you're not familiar with this term, GitHub's [help pages](https://help.github.com/articles/fork-a-repo/) provide again a simple explanation:
   151  
   152  > A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
   153  
   154  #### Fork by hand
   155  
   156  Open the [Hugo repository](https://github.com/gohugoio/hugo) on GitHub and click on the "Fork" button in the top right.
   157  
   158  ![Fork button](/images/contribute/development/forking-a-repository.png)
   159  
   160  Now open your fork repository on GitHub and copy the remote url of your fork. You can choose between HTTPS and SSH as protocol that Git should use for the following operations. HTTPS works always [if you're not sure](https://help.github.com/articles/which-remote-url-should-i-use/).
   161  
   162  ![Copy remote url](/images/contribute/development/copy-remote-url.png)
   163  
   164  Switch back to the terminal and move into the directory of the cloned master repository from the last step.
   165  
   166  ```
   167  cd $GOPATH/src/github.com/gohugoio/hugo
   168  ```
   169  
   170  Now Git needs to know that our fork exists by adding the copied remote url:
   171  
   172  ```
   173  git remote add <YOUR-GITHUB-USERNAME> <COPIED REMOTE-URL>
   174  ```
   175  
   176  #### Fork with Hub
   177  
   178  Alternatively, you can use the Git wrapper Hub. Hub makes forking a repository easy:
   179  
   180  ```
   181  git fork
   182  ```
   183  
   184  That command will log in to GitHub using your account, create a fork of the repository that you're currently working in, and add it as a remote to your working copy.
   185  
   186  #### Trust, but verify
   187  
   188  Let's check if everything went right by listing all known remotes:
   189  
   190  ```
   191  git remote -v
   192  ```
   193  
   194  The output should look similar:
   195  
   196  ```
   197  digitalcraftsman    git@github.com:digitalcraftsman/hugo.git (fetch)
   198  digitalcraftsman    git@github.com:digitalcraftsman/hugo.git (push)
   199  origin  https://github.com/gohugoio/hugo (fetch)
   200  origin  https://github.com/gohugoio/hugo (push)
   201  ```
   202  
   203  ## The Hugo Git Contribution Workflow
   204  
   205  ### Create a new branch
   206  
   207  You should never develop against the "master" branch. The development team will not accept a pull request against that branch. Instead, create a descriptive named branch and work on it.
   208  
   209  First, you should always pull the latest changes from the master repository:
   210  
   211  ```
   212  git checkout master
   213  git pull
   214  ```
   215  
   216  Now we can create a new branch for your additions:
   217  
   218  ```
   219  git checkout -b <BRANCH-NAME>
   220  ```
   221  
   222  You can check on which branch you are with `git branch`. You should see a list of all local branches. The current branch is indicated with a little asterisk.
   223  
   224  ### Contribute to Documentation
   225  
   226  Perhaps you want to start contributing to the Hugo docs. If so, you can ignore most of the following steps and focus on the `/docs` directory within your newly cloned repository. You can change directories into the Hugo docs using `cd docs`.
   227  
   228  You can start Hugo's built-in server via `hugo server`. Browse the documentation by entering [http://localhost:1313](http://localhost:1313) in the address bar of your browser. The server automatically updates the page whenever you change content.
   229  
   230  We have developed a [separate Hugo documentation contribution guide][docscontrib] for more information on how the Hugo docs are built, organized, and improved by the generosity of people like you.
   231  
   232  ### Build Hugo
   233  
   234  While making changes in the codebase it's a good idea to build the binary to test them:
   235  
   236  ```
   237  go build -o hugo main.go
   238  ```
   239  
   240  ### Test 
   241  Sometimes changes on the codebase can cause unintended side effects. Or they don't work as expected. Most functions have their own test cases. You can find them in files ending with `_test.go`.
   242  
   243  Make sure the commands `go test ./...` passes, and `go build` completes.
   244  
   245  ### Formatting 
   246  The Go code styleguide maybe is opinionated but it ensures that the codebase looks the same, regardless who wrote the code. Go comes with its own formatting tool. Let's apply the styleguide to our addtions:
   247  
   248  ```
   249  go fmt ./...
   250  ```
   251  
   252  Once you made your additions commit your changes. Make sure that you follow our [code contribution guidelines](https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md):
   253  
   254  ```
   255  # Add all changed files
   256  git add --all
   257  git commit --message "YOUR COMMIT MESSAGE"
   258  ```
   259  
   260  The commit message should describe what the commit does (e.g. add feature XYZ), not how it is done.
   261  
   262  ### Modify commits
   263  
   264  You noticed some commit messages don't fulfill the code contribution guidelines or you just forget something to add some files? No problem. Git provides the necessary tools to fix such problems. The next two methods cover all common cases.
   265  
   266  If you are unsure what a command does leave the commit as it is. We can fix your commits later in the pull request.
   267  
   268  #### Modify the last commit
   269  
   270  Let's say you want to modify the last commit message. Run the following command and replace the current message:
   271  
   272  ```
   273  git commit --amend -m"YOUR NEW COMMIT MESSAGE"
   274  ```
   275  
   276  Take a look at the commit log to see the change:
   277  
   278  ```
   279  git log
   280  # Exit with q
   281  ```
   282  
   283  After making the last commit you may have forgot something. There is no need to create a new commit. Just add the latest changes and merge them into the intended commit:
   284  
   285  ```
   286  git add --all
   287  git commit --amend
   288  ```
   289  
   290  #### Modify multiple commits
   291  
   292  {{% warning "Be Careful Modifying Multiple Commits"%}}
   293  Modifications such as those described in this section can have serious unintended consequences. Skip this section if you're not sure!
   294  {{% /warning %}}
   295  
   296  This is a bit more advanced. Git allows you to [rebase](https://git-scm.com/docs/git-rebase) commits interactively. In other words: it allows you to rewrite the commit history.
   297  
   298  ```
   299  git rebase --interactive @~6
   300  ```
   301  
   302  The `6` at the end of the command represents the number of commits that should be modified. An editor should open and present a list of last six commit messages:
   303  
   304  ```
   305  pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
   306  pick aaee038 tpl: Sort the smoke tests
   307  pick f0dbf2c tpl: Add the other test case for hasPrefix
   308  pick 911c35b Add "How to contribute to Hugo" tutorial
   309  pick 33c8973 Begin workflow
   310  pick 3502f2e Refactoring and typo fixes
   311  ```
   312  
   313  In the case above we should merge the last to commits in the commit of this tutorial (`Add "How to contribute to Hugo" tutorial`). You can "squash" commits, i.e. merge two or more commits into a single one.
   314  
   315  All operations are written before the commit message. Replace "pick" with an operation. In this case `squash` or `s` for short:
   316  
   317  ```
   318  pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
   319  pick aaee038 tpl: Sort the smoke tests
   320  pick f0dbf2c tpl: Add the other test case for hasPrefix
   321  pick 911c35b Add "How to contribute to Hugo" tutorial
   322  squash 33c8973 Begin workflow
   323  squash 3502f2e Refactoring and typo fixes
   324  ```
   325  
   326  We also want to rewrite the commits message of the third last commit. We forgot "docs:" as prefix according to the code contribution guidelines. The operation to rewrite a commit is called `reword` (or `r` as shortcut).
   327  
   328  You should end up with a similar setup:
   329  
   330  ```
   331  pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
   332  pick aaee038 tpl: Sort the smoke tests
   333  pick f0dbf2c tpl: Add the other test case for hasPrefix
   334  reword 911c35b Add "How to contribute to Hugo" tutorial
   335  squash 33c8973 Begin workflow
   336  squash 3502f2e Refactoring and typo fixes
   337  ```
   338  
   339  Close the editor. It should open again with a new tab. A text is instructing you to define a new commit message for the last two commits that should be merged (aka "squashed"). Save the file with <kbd>CTRL</kbd>+<kbd>S</kbd> and close the editor again.
   340  
   341  A last time a new tab opens. Enter a new commit message and save again. Your terminal should contain a status message. Hopefully this one:
   342  
   343  ```
   344  Successfully rebased and updated refs/heads/<BRANCHNAME>.
   345  ```
   346  
   347  Check the commit log if everything looks as expected. Should an error occur you can abort this rebase with `git rebase --abort`.
   348  
   349  ### Push commits
   350  
   351  To push our commits to the fork on GitHub we need to specify a destination. A destination is defined by the remote and a branch name. Earlier, the defined that the remote url of our fork is the same as our GitHub handle, in my case `digitalcraftsman`. The branch should have the same as our local one. This makes it easy to identify corresponding branches.
   352  
   353  ```
   354  git push --set-upstream <YOUR-GITHUB-USERNAME> <BRANCHNAME>
   355  ```
   356  
   357  Now Git knows the destination. Next time when you to push commits you just need to enter `git push`.
   358  
   359  If you modified your commit history in the last step GitHub will reject your try to push. This is a safety-feature because the commit history isn't the same and new commits can't be appended as usual. You can enforce this push explicitly with `git push --force`.
   360  
   361  ## Open a pull request
   362  
   363  We made a lot of progress. Good work. In this step we finally open a pull request to submit our additions. Open the [Hugo master repository](https://github.com/gohugoio/hugo/) on GitHub in your browser.
   364  
   365  You should find a green button labeled with "New pull request". But GitHub is clever and probably suggests you a pull request like in the beige box below:
   366  
   367  ![Open a pull request](/images/contribute/development/open-pull-request.png)
   368  
   369  The new page summaries the most important information of your pull request. Scroll down and you find the additions of all your commits. Make sure everything looks as expected and click on "Create pull request".
   370  
   371  ### Accept the contributor license agreement
   372  
   373  Last but not least you should accept the contributor license agreement (CLA). A new comment should be added automatically to your pull request. Click on the yellow badge, accept the agreement and authenticate yourself with your GitHub account. It just takes a few clicks and only needs to be done once.
   374  
   375  ![Accept the CLA](/images/contribute/development/accept-cla.png)
   376  
   377  ### Automatic builds
   378  
   379  We use the [Travis CI loop](https://travis-ci.org/gohugoio/hugo) (Linux and OS&nbsp;X) and [AppVeyor](https://ci.appveyor.com/project/gohugoio/hugo/branch/master) (Windows) to compile Hugo with your additions. This should ensure that everything works as expected before merging your pull request. This in most cases only relevant if you made changes to the codebase of Hugo.
   380  
   381  ![Automic builds and their status](/images/contribute/development/ci-errors.png)
   382  
   383  Above you can see that Travis wasn't able to compile the changes in this pull request. Click on "Details" and try to investigate why the build failed. But it doesn't have to be your fault. Mostly, the `master` branch that we used as foundation for your pull request should build without problems.
   384  
   385  If you have questions, leave a comment in the pull request. We are willing to assist you.
   386  
   387  ## Where to start?
   388  
   389  Thank you for reading through this contribution guide. Hopefully, we will see you again soon on GitHub. There are plenty of [open issues][issues] for you to help with.
   390  
   391  Feel free to [open an issue][newissue] if you think you found a bug or you have a new idea to improve Hugo. We are happy to hear from you.
   392  
   393  ## Additional References for Learning Git and Go
   394  
   395  * [Codecademy's Free "Learn Git" Course][codecademy] (Free)
   396  * [Code School and GitHub's "Try Git" Tutorial][trygit] (Free)
   397  * [The Git Book][gitbook] (Free)
   398  * [Go Bootcamp][gobootcamp]
   399  * [GitHub Pull Request Tutorial, Thinkful][thinkful]
   400  
   401  
   402  [codecademy]: https://www.codecademy.com/learn/learn-git
   403  [contributors]: https://github.com/gohugoio/hugo/graphs/contributors
   404  [docscontrib]: /contribute/documentation/
   405  [forums]: https://discourse.gohugo.io
   406  [gitbook]: https://git-scm.com/
   407  [gobootcamp]: http://www.golangbootcamp.com/book/get_setup
   408  [godl]: https://golang.org/dl/
   409  [goinstall]: https://golang.org/doc/install
   410  [gvm]: https://github.com/moovweb/gvm
   411  [issues]: https://github.com/gohugoio/hugo/issues
   412  [newissue]: https://github.com/gohugoio/hugo/issues/new
   413  [releases]: /getting-started/
   414  [setupgopath]: https://golang.org/doc/code.html#Workspaces
   415  [thinkful]: https://www.thinkful.com/learn/github-pull-request-tutorial/
   416  [trygit]: https://try.github.io/levels/1/challenges/1