Replacements for Hugo modules in env variable

I am using Hugo modules for my Hugo theme. It would be convenient if I could set it to use my local copy of the theme instead of the stable published version in an env variable, rather than in the go.mod file that is committed to my git repo. I have replacements working in my go.mod like so:

module www.maximumethics.dev

go 1.15

require git.sr.ht/~skyfaller/maxethics-hugo v0.0.5 // indirect
// To develop locally, uncomment the line below and edit it to point to your local copy
replace git.sr.ht/~skyfaller/maxethics-hugo => /home/nelson/code/maxethics-hugo

However, when I try to set the replacement as an env variable, it doesn’t seem to work. Here’s what I’m doing in fish shell:

~/c/content (master)>
set -Ux HUGO_MODULE_REPLACEMENTS "git.sr.ht/~skyfaller/maxethics-hugo -> /home/nelson/code/maxethics-hugo"
~/c/content (master)> echo $HUGO_MODULE_REPLACEMENTS
git.sr.ht/~skyfaller/maxethics-hugo -> /home/nelson/code/maxethics-hugo

If I comment out the replacement in go.mod after setting that env variable, the site refuses to build because it’s using the stable version of my theme, not the dev version that my local copy is relying on. (I added a new shortcode.) Re-adding the replacement in go.mod makes it work again.

I don’t know where to begin to figure out what I’m doing wrong. Any ideas?

In case it matters, I’m running:
Hugo Static Site Generator v0.78.1/extended linux/amd64 BuildDate: unknown
go version go1.15.3 linux/amd64

If you’re curious about my system:

      ///////*767////////////////         OS: Pop!_OS 20.10 x86_64 
    //////7676767676*//////////////       Host: Thelio thelio-r1 
   /////76767//7676767//////////////      Kernel: 5.9.6-050906-generic 
  /////767676///*76767///////////////     Uptime: 1 day, 15 hours, 55 mins 
 ///////767676///76767.///7676*///////    Packages: 2277 (dpkg), 52 (brew), 57 (flatpak) 
/////////767676//76767///767676////////   Shell: fish 3.1.2 
//////////76767676767////76767/////////   Resolution: 3840x2160 
///////////76767676//////7676//////////   DE: GNOME 
////////////,7676,///////767///////////   WM: Mutter 
/////////////*7676///////76////////////   WM Theme: Pop 
///////////////7676////////////////////   Theme: Pop-dark [GTK2/3] 
 ///////////////7676///767////////////    Icons: Pop [GTK2/3] 
  //////////////////////'////////////     Terminal: gnome-terminal 
   //////.7676767676767676767,//////      CPU: AMD Ryzen 7 3800X (16) @ 3.900GHz 
    /////767676767676767676767/////       GPU: AMD ATI Radeon RX 5600 OEM/5600 XT / 5700/5700 XT 
      ///////////////////////////         Memory: 5259MiB / 32122MiB

Not really an answer to your question, but I’ve approached a similar problem from a different direction.

I use multiple config files:

...
├── config
│   ├── _default
│   │   └── config.toml
│   └── development
│       └── config.toml
├── content
│   └── ...
└── themes
    ├── bar
    └── foo
# config/default/config.toml

theme = [
"github.com/pointyfar/foo",
"github.com/pointyfar/bar"
]
# config/development/config.toml

theme = [
"foo",
"bar"
]

I had been planning to do some testing with go.mod replacement feature, and I’ll update once I have done so.

I have a “release” script that removes the lines, sends the go.mod to the repo and adds them again :wink: But I thought about the way @pointyfar was suggesting. You would have to take care to upload your local changes to the modules of course. This could be done with a call to git porcellain.

My release script (just typed together, not really clean with fallback):

#!/bin/bash

cp bin/go.mod.repo go.mod

hugo mod get -u ./...
hugo mod tidy
rm -rf public
#hugo mod vendor

cp go.mod bin/go.mod.repo

#git add _vendor
git add go.mod
git add go.sum

{
  echo 'replace github.com/davidsneighbour/dnb-hugo-garuda => /home/patrick/Projects/Hugo/dnb-hugo-garuda'
  echo 'replace github.com/davidsneighbour/dnb-hugo/netlification => /home/patrick/Projects/Hugo/dnb-hugo/netlification'
  echo 'replace github.com/davidsneighbour/dnb-hugo/renderhooks => /home/patrick/Projects/Hugo/dnb-hugo/renderhooks'
  echo 'replace github.com/davidsneighbour/dnb-hugo/robots => /home/patrick/Projects/Hugo/dnb-hugo/robots'
  echo 'replace github.com/davidsneighbour/dnb-hugo/favicons => /home/patrick/Projects/Hugo/dnb-hugo/favicons'
  echo 'replace github.com/davidsneighbour/dnb-hugo/shortcodes => /home/patrick/Projects/Hugo/dnb-hugo/shortcodes'
  echo 'replace github.com/davidsneighbour/dnb-hugo-libs/bootstrap4 => /home/patrick/Projects/Hugo/dnb-hugo-libs/bootstrap4'
} >> go.mod

hugo --gc --minify
git add -f public
npm run release

For the record, setting replacements as an env variable still doesn’t work for me. Module replacements via env variable still appear in the documentation: Configure Modules | Hugo So are they working for anyone? Why don’t they work for me?

My setup today:

> hugo version
hugo v0.103.1+extended linux/amd64 BuildDate=unknown

> neofetch
             .',;::::;,'.                nelson@bobbie
         .';:cccccccccccc:;,.            -------------
      .;cccccccccccccccccccccc;.         OS: Fedora Linux 36 (Workstation Edition) x86_64
    .:cccccccccccccccccccccccccc:.       Host: Laptop AA
  .;ccccccccccccc;.:dddl:.;ccccccc;.     Kernel: 5.19.9-200.fc36.x86_64
 .:ccccccccccccc;OWMKOOXMWd;ccccccc:.    Uptime: 3 hours, 9 mins
.:ccccccccccccc;KMMc;cc;xMMc:ccccccc:.   Packages: 2594 (rpm), 35 (brew), 46 (flatpak)
,cccccccccccccc;MMM.;cc;;WW::cccccccc,   Shell: fish 3.5.0
:cccccccccccccc;MMM.;cccccccccccccccc:   Resolution: 2256x1504
:ccccccc;oxOOOo;MMM0OOk.;cccccccccccc:   DE: GNOME 42.5
cccccc:0MMKxdd:;MMMkddc.;cccccccccccc;   WM: Mutter
ccccc:XM0';cccc;MMM.;cccccccccccccccc'   WM Theme: Adwaita
ccccc;MMo;ccccc;MMW.;ccccccccccccccc;    Theme: Adwaita [GTK2/3]
ccccc;0MNc.ccc.xMMd:ccccccccccccccc;     Icons: Adwaita [GTK2/3]
cccccc;dNMWXXXWM0::cccccccccccccc:,      Terminal: alacritty
cccccccc;.:odl:.;cccccccccccccc:,.       Terminal Font: Roboto Mono
:cccccccccccccccccccccccccccc:'.         CPU: 11th Gen Intel i5-1135G7 (8) @ 4.200GHz
.:cccccccccccccccccccccc:;,..            GPU: Intel TigerLake-LP GT2 [Iris Xe Graphics]
  '::cccccccccccccc::;,.                 Memory: 5481MiB / 31885MiB

I’m installing Hugo from Homebrew on Linux.

module replacement from environment variables need to be either absolute paths or relatives to the themes directory (even if you don’t have one). That is the level above the current project root is ../.. not .. .

HTH

Oh, and yes, replacements env variable works for me, keeping that in mind.

In my case, I’m using /home/nelson/code/maxethics-hugo, which is an absolute path. So if absolute paths work, this should work. It works when I do the replacement from my go.mod file.

config.toml

[[module.imports]]
path = "github.com/jmooring/hugo-content"

With Ubuntu 22.04.1 LTS (GNU bash, version 5.1.16) this works as expected:

HUGO_MODULE_REPLACEMENTS="github.com/jmooring/hugo-content -> /home/jmooring/code/hugo-content" hugo server

This also works:

export HUGO_MODULE_REPLACEMENTS="github.com/jmooring/hugo-content -> /home/jmooring/code/hugo-content"
hugo server

So I’m wondering if this is a fish thing, somehow related to the set -Ux command.

What do you get when you open a new terminal and type:

echo $HUGO_MODULE_REPLACEMENTS

As I said in the original post, and it’s still true today, here’s what I get in Fish shell:

> echo $HUGO_MODULE_REPLACEMENTS
git.sr.ht/~skyfaller/maxethics-hugo -> /home/nelson/code/maxethics-hugo

I get the same results if I run it in bash, though:

> bash
[nelson@bobbie maximum-ethics-content]$ echo $HUGO_MODULE_REPLACEMENTS
git.sr.ht/~skyfaller/maxethics-hugo -> /home/nelson/code/maxethics-hugo

Running hugo server from bash displays the same behavior, where the replacement in go.mod works, but the replacement in the env variable does not. So I don’t think it’s fish shell?

This problem has been consistent for me across multiple different computers, across different OSes (both macOS and multiple flavors of Linux), and across years of different versions of Hugo.

Why else might it work for you but not me, if it’s not fish shell?

Just to be sure that there isn’t something different about your module…

config.toml

[[module.imports]]
path = "git.sr.ht/~skyfaller/maxethics-hugo"

Then I cloned maxethics-hugo to my code directory, made some changes to it, then ran:

HUGO_MODULE_REPLACEMENTS="git.sr.ht/~skyfaller/maxethics-hugo -> /home/jmooring/code/maxethics-hugo" hugo server

I can see the changes that I made to templates in /home/jmooring/code/maxethics-hugo.

Not sure what’s happening on your system.

I also installed fish and ran the same test—no problems.

What happens if you use Hugo from GitHub rather than Homebrew?

Also what is your locale? For that matter, any other environment that could possibly be relevant. What filesystem are you on? What character set?

Do you have a minimum reproducible test case. In this case that means starting with the install media (which would be included in the definition of the MRTC), what is the minimum set of packages and personalization that reproduces the problem?

I tried installing both Hugo extended and regular Hugo from GitHub. Same behavior.

> hugo version
hugo v0.104.0-c744dbd6edeeb27288c9dd67e0eb92951f911397+extended linux/amd64 BuildDate=2022-09-23T14:32:56Z VendorInfo=gohugoio
> hugo version
hugo v0.104.0-c744dbd6edeeb27288c9dd67e0eb92951f911397 linux/amd64 BuildDate=2022-09-23T14:32:56Z VendorInfo=gohugoio

Because this has been consistent for me across different computers for years, I’m not sure the variables you mention matter, but here’s my current setup anyway:

> locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
> df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  4.0M     0  4.0M   0% /dev
tmpfs          tmpfs      16G  6.8M   16G   1% /dev/shm
tmpfs          tmpfs     6.3G  2.2M  6.3G   1% /run
/dev/dm-0      btrfs     930G  130G  801G  14% /
tmpfs          tmpfs      16G  532K   16G   1% /tmp
/dev/dm-0      btrfs     930G  130G  801G  14% /home
/dev/nvme0n1p2 ext4      974M  261M  647M  29% /boot
/dev/nvme0n1p1 vfat      599M   14M  585M   3% /boot/efi
tmpfs          tmpfs     3.2G  2.5M  3.2G   1% /run/user/1000

My main drive uses BTRFS right now, in other words.

OK, trying to make a minimum reproducible test case seems reasonable. I’ll take a stab at this some other day.

I look forward to seeing what you come up with.

One more idea; I noticed that your module repo does not have a config.toml (I saw a note somewhere in your commits/code that you generate it). Perhaps that is a factor.

Also, do you have a content repo that exhibits the same behaviour (I presume you haven’t posted your actual content repo for a reason)? Perhaps it is the site part of the equation that causes the issue.

1 Like

Oh, huh, I didn’t know that themes were supposed to have a config.toml, but apparently they should: https://github.com/gohugoio/hugoThemesSiteBuilder/blob/main/README.md#adding-a-theme-to-the-list

Your theme should also have a configuration file (e.g. config.toml) configuring what Hugo versions the theme supports:

I don’t know how to figure out what versions of Hugo my theme supports… any tips for figuring out how far back my theme’s support goes?

As for the content repo, I simply haven’t posted it because I’m planning to eventually fold it into the theme repo as an example site, and therefore haven’t put up a README or done much to make the code look nice. It’s https://git.sr.ht/~skyfaller/maximum-ethics-content

For figuring out support you could use the same binary search algorithm as ‘git bisect’. Basically start with the oldest version you think might be supported. If you are wrong, pick the commit half way between the latest version and the version you tried. If that fails pick the version halfway between that version and the max version. If it succeeds, try the version halfway between the version you just tried and the lower version. Repeat until there are no more versions to test.

1 Like

I think I see the issue: ~skyfaller/maximum-ethics-content: config.toml - sourcehut git

You use theme = "git.sr.ht/~skyfaller/maxethics-hugo" near the top instead of

[[module.imports]]
path = "git.sr.ht/~skyfaller/maxethics-hugo"

at the bottom. I could be wrong (@jmooring ?), but I don’t think replacements works with theme = but does with [[modules.imports]].

2 Likes

@cshoredaniel is correct.

See this comment from bep:

Using HUGO_MODULE_REPLACEMENTS is the same as manually editing the path in your module config in config.toml – which is not the same as a replacement inside go.mod

In your site configuration, change this:

theme = 'git.sr.ht/~skyfaller/maxethics-hugo'

to this:

[[module.imports]]
path = 'git.sr.ht/~skyfaller/maxethics-hugo'
2 Likes

I haven’t read the entire thread, but there is also a recent workspace setting:

I haven’t used that setting myself to any extent, but it would allow you to stay out of go.mod.

2 Likes

Thanks everyone, I can confirm that [[modules.imports]] fixes my problem. Wow that has been bothering me for years, glad we finally sorted that out.

1 Like