Adding Gradle to a Hugo project
This post will show you how to add Gradle build capabilities to a Hugo project.
The preferred way of using Gradle is through a Gradle Wrapper. I assume you already have Gradle installed in your environment, but, if not, then follow the instructions here. |
Starting the local Hugo server
Create a build.gradle
file in the Hugo project folder, ie alongside the contents
folder.
This file will be read by Gradle, and defines the build tasks, attributes etc. we want to have
in the project.
The first task we will write is going to enable us to start the local Hugo server.
To do that we will create a new Gradle task of type Exec. Add the following to the empty
build.gradle
file.
task hugoLocal(type:Exec) {
workingDir = file('.')
commandLine 'hugo', 'server', '-D'
}
This task sets the working directory to the current directory, and then starts the Hugo server, setting it up to also serve draft pages in the content it is serving.
Building the site
The next Gradle task will allow us generate the Hugo site. By default, Hugo will create the site in the `public`folder of the project. First we create a variable to identify the output directory.
ext {
hugoOutputDir = file("$projectDir/public")
}
and the add a task to allow us to call Hugo to do its work
task hugo(type: Exec) {
workingDir = file('.')
commandLine 'hugo'
}
When we run ./gradlew hugo
the public
folder is created and content is added.
> gw hugo
> Task :hugo
Building sites …
| EN
-------------------+-----
Pages |
. . .
Total in 102 ms
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
Removing old contents
At this point we can create a Hugo site, have it served locally, and create the content we would like to deploy. However, Hugo does not empty the output directory before creating the content, so we risk having old files still in the output directory.
What we we need to do is add a task that will remove the Hugo output in public
. We start by
adding the base
Gradle plugin to our build file
plugins {
id 'base'
}
and add the location of the files Hugo is generating to the task’s outputs
property
hugo.outputs.dir hugoOutputDir
At this point we have 2 choices. The base
plugin will automatically create a clean<TaskName>
task, so cleanHugo
is already available. If you prefer to use the standard Gradle `clean`task,
then we can configure it using
clean {
delete hugo.outputs
}
Finally, we make sure that the hugo
task depends on cleaning the previous output by extending
the task definition
task hugo(type: Exec, dependsOn: 'cleanHugo') { . . . }
Complete build.gradle
The complete build.gradle
file allows us to use Hugo locally and generate the site content we
wish to publish
plugins {
id 'base'
id 'org.hidetake.ssh' version '2.10.1'
}
ext {
hugoOutputDir = fileTree("$projectDir/public").getDir()
sshKeyFile = '~/.ssh/id_sftp_port27'
}
remotes {
one {
host = 'sftp.port27.dk'
user = 'port27.dk'
}
}
ssh.settings {
dryRun = project.hasProperty('dryRun')
identity = new File(sshKeyFile)
knownHosts = allowAnyHosts
// fileTransfer = 'scp'
}
task hugo(type: Exec, dependsOn: 'cleanHugo') {
workingDir = file('.')
commandLine 'hugo'
}
hugo.outputs.dir hugoOutputDir
clean {
delete hugo.outputs
}
task serve(type:Exec) {
workingDir = file(projectDir)
commandLine 'hugo', 'server', '-D'
}
task deploy() {
doLast {
ssh.run {
session(remotes.one) {
put from: "$projectDir/public/about", into: '.'
put from: "$projectDir/public/categories", into: '.'
put from: "$projectDir/public/css", into: '.'
put from: "$projectDir/public/posts", into: '.'
put from: "$projectDir/public/tags", into: '.'
put from: "$projectDir/public/.htaccess", into: '.'
put from: "$projectDir/public/404.html", into: '.'
put from: "$projectDir/public/index.html", into: '.'
put from: "$projectDir/public/index.xml", into: '.'
put from: "$projectDir/public/sitemap.xml", into: '.'
// new File("$projectDir/public").eachFileRecurse {
// println " ${it.absolutePath} -> ./${it.absolutePath - ~/.*\/public\//}"
// put from: it, into: "./${it.absolutePath - ~/.*\/public\//}"
// }
}
}
}
}