Emacs, scripting and anything text oriented.

Installing bleeding edge Hugo + Goorgeous

Kaushal Modi

Outdated post on how to build hugo from source with the latest commit from the goorgeous package.

Update (2017/06/16)

Updated the github source references as per the changes in hugo v0.231. Also made the shell script ShellCheck-passing! 🙌 §


You already got go installed, and that’s why are you reading it.

         If not – Go! Install it!

So.. now that you have go installed, why settle for the release version of hugo! You are reading this blog post generated using the bleeding edge of hugo2.

In addition, Hugo v0.19 onwards supports the org-mode syntax3, which is so much more awesome than markdown, especially if you are using emacs.

This post is about how you can install the latest versions of hugo and the go package that adds the org-mode support – goorgeous.

First time install of hugo #

When any package gets installed using go get, it gets installed inside the $GOPATH/src/ directory. We install hugo using go get for this one-and-only time to get that correct directory structure in there:

go get -u -v github.com/gohugoio/hugo

Installing hugo from master #

Now you should find the hugo source code in $GOPATH/src/github.com/gohugoio/hugo/.

From here on, run all commands in that directory! 4

To get the latest files from the master branch do:

git fetch --all # fetch new branch names if any
git checkout master
# I also do hard reset as I don't develop any code in go
git reset --hard origin/master

Govendor #

Hugo does its package dependency management using govendor, which, not surprisingly, is also a go package. (goorgeous is one of these dependent packages.)

So you would install govendor like any other go package:

go get -u -v github.com/kardianos/govendor

The package dependency database is stored in $GOPATH/src/github.com/gohugoio/hugo/vendor/vendor.json. This JSON file specifies what other go packages need to be installed from which git repo, using which commit.

Govendor makes installing the right versions of the dependent packages easy – Just run the below.

govendor sync

Latest goorgeous #

Note: If you do not wish to update to the latest version of goorgeous, you can skip this step.

The commit hash for goorgeous in that JSON file might not point to its latest version. But we are interested in getting the latest-and-greatest org-mode support for hugo ..

The good news is that govendor allows that:

# Fetch the goorgeous package from its master branch
govendor fetch github.com/chaseadamsio/goorgeous

See the Govendor Quick Start Guide for frequently used commands.

Static Executable #

We want to make the hugo executable a static executable.

That way it is 100% portable — independent of dynamically linked libraries. This is also how the Continuous Integration engines (like the Gitlab CI Runner that generates this blog) can use this custom built hugo binary without any dynamic library dependency issue.

To enable static building of go binaries, these env variables need to be set:

export CGO_ENABLED=0
export GO_EXTLINK_ENABLED=0

Note that above (and the snippet that follows) work in a bash shell. Even if your default shell is not bash, you can run the full bash script at the end of this post.

Building Hugo #

We now finally build hugo, with some customization so that running hugo version prints the Build Date and Commit Hash too.

package="github.com/gohugoio/hugo"
commithash=$(git rev-parse --short HEAD 2>/dev/null)
builddate=$(date +%FT%T%z)
go install -v \
   -ldflags "-X ${package}/hugolib.CommitHash=${commithash} \
             -X ${package}/hugolib.BuildDate=${builddate}" \
   ${package}

This will install the binary as $GOPATH/bin/hugo.

Now don’t forget to add $GOPATH/bin to your $PATH!

Verify that the binary got built as expected by running hugo version.

Hugo Static Site Generator v0.24-DEV-411AC930 linux/amd64 BuildDate: 2017-06-16T11:16:50-04:00

Full Build Script #

Here is the full bash script. You can save it as hugo-build.sh and it will run just fine on any shell (as long as you haven’t removed bash from your system 😄).

#!/usr/bin/env bash

here=$(pwd)

package="github.com/gohugoio/hugo"

export CGO_ENABLED=0
export GO_EXTLINK_ENABLED=0

if ! hash govendor 2>/dev/null
then
    go get -u -v github.com/kardianos/govendor
fi

# Install hugo for the first time so that the ${GOPATH}/src/${package}
# directory gets populated.
if [[ ! -d "${GOPATH}/src/${package}" ]] || ( ! hash hugo 2>/dev/null )
then
    go get -u -v ${package}
fi

# Update to hugo master branch
cd "${GOPATH}/src/${package}" || exit
git fetch --all # fetch new branch names if any
git checkout master
# git fetch --all
# Force update the vendor file in case it got changed
git reset --hard origin/master

# Synchronize all the dependent packages as per the just updated vendor file
govendor sync

# Update the goorgeous package to its master branch
# You can comment out the below line if you do not need to fetch the
# latest version of goorgeous.
govendor fetch github.com/chaseadamsio/goorgeous
# govendor fetch github.com/chaseadamsio/goorgeous@=fixNewlineParagraphs

commithash=$(git rev-parse --short HEAD 2>/dev/null)
builddate=$(date +%FT%T%z)
go install -v \
   -ldflags "-X ${package}/hugolib.CommitHash=${commithash} \
             -X ${package}/hugolib.BuildDate=${builddate}" \
   ${package}

echo "Hugo Version Check:"

cd "${here}" || exit

  1. Hugo v0.23 Release Notes ↩︎

  2. To see the master branch commit of hugo used to build this site, do Ctrl + U in your browser and search for Hugo Commit Hash↩︎

  3. Hugo v0.19 Release Notes ↩︎

  4. You need to be in the ${GOPATH}/src/${package} directory in order to build any go ${package} (unless you are doing a plain go get). ↩︎

Comment by Sam Ask on Wed Mar 8, 2017 12:59 EST

Thank you so much for this tutorial.

Comment by Epo Jemba on Tue Mar 14, 2017 12:02 EDT

I don't understand. Doesn't the "0.19 February 27th 2017" already include the org modification ?
Why the need to rebuild hugo ?

Comment by Kaushal Modi on Tue Mar 14, 2017 12:42 EDT
Replying to comment by Epo Jemba: "I don't understand. Doesn't the …"

The 0.19 release of hugo released with the vendor.json pointing to 72a06e1 commit of goorgeous, which was on Feb 17th. So if you want to build hugo with the newer commits of goorgeous, you'll need to do it as explained here.

Comment by RickCogley on Wed Jun 21, 2017 05:37 EDT

Thanks for the update. I did not realize the repo had moved!