Turning a theme (with dependencies) into a module while maintaining compatibility

I’m currently working on a theme which is in widespread use.
Users use this theme inside their sites with a traditional structure like:

user-site
│
└───themes
│   │
│   └───mytheme (github.com/me/mytheme)
│       │
│       └───config.toml
│       │
│       └───assets
│           │
│           └───vendor
│               │
│               └───theme_dep (as_submodule, github.com/project/theme_dep)
│
└───config.toml

My theme has a dependency theme_dep that currently resides into a submodule (assets/vendor/theme_dep).

Now I want to convert my theme to a hugo module so that the dependency is pulled in automatically. So I initialized my theme as module and added the dependency:

module github.com/me/mytheme
go 1.12

require (
    github.com/project/theme_dep v2.0.0
)

Then I added to the config.toml of my theme:

[[module.imports]]
  path = "github.com/maintainer/themedep"
[[module.imports.mounts]]
  source = "scss"
  target = "assets/vendor/dep_as_submodule/scss"

After this change, my users can intialize their sites as module and declare mytheme as a dependency inside the go.mod of their site:

module user-site
go 1.12

require github.com/me/mytheme v1.0.0

Now my users can run their site with hugo serve and mytheme (and the transitive dependency theme_dep) are pulled in automatically. So far so good, everthing works great.

The problem I have: my theme is in widespread use, and some users of my theme are hesitant to initialize/convert their site as module, (for whatever reason, go is not installed, …). They want keep their current site structure and use the theme the way they are used to. They also want to receive updates of my theme. But there is now a problem: once they pull in the latest changes to my theme, they are also pulling in the module import of my dependency, which cannot be satisfied in their exisiting setting. So converting my them to a module that pulls in a dependency essentially breaks existing sites that stick to the traditional setup (which is unwanted, of course).

I thought about this and found a partial solution. Inside the config.toml of the user site, existing users can declare a replacement for the dependency, pointing to an empty directory. This is the solution I came up with and it works:

[module]
replacements = "github.com/project/theme_dep -> ."
[[module.imports]]
path = "mytheme"

This is good, but still users have to identify theme = "mytheme" inside their config.toml and replace it with the the module section with the replacements directive listed above.

My question: Is there a way to get rid of this step, enabling users to pull in theme updates without touching their existing config.toml?

I thought about putting the replacements directive into the config.toml of my theme, something like

[module]
replacements = "github.com/project/theme_dep -> ."
[[module.imports]]
  path = "github.com/maintainer/themedep"
[[module.imports.mounts]]
  source = "scss"
  target = "assets/vendor/dep_as_submodule/scss"

This didn’t work however, the replacement directive isn’t propagated through to the site (at least as far as I can see). Is this supposed to work? Am I doing anything wrong here? Any ideas on how to make this work?

Or are other totally different aprroaches or any other ideas how to solve the problem mentioned? Thanks for your input!

My question: Is there a way to get rid of this step, enabling users to pull in theme updates without touching their existing config.toml ?

I am not sure if I understand your needs fully, but my update procedure is this:

  • I create a new tag with semver numbering
  • I run hugo mod get -u ./... on my websites

That updates modules and themes that are modules. What you could do is creating a server script that first runs the mod-get-update and then hugo server and let your users use that to start the server. Hugo itself is checking for updates every now and then, not every time.

You should also have your theme running this command before you create a new tag, so that the newest versions are required. Best to run hugo mod tidy afterwards to keep go.sum… tidy.