Open asummers opened 5 years ago
I think a behaviour like the following would be the cleanest:
defmodule GitOps.VersionStorage do
@callback read_version() :: {:ok, String.t()} | {:error, String.t()}
@callback write_version() :: {:ok, String.t()} | {:error, String.t()}
end
I have no problem with that, but then I guess the question becomes - do we by always have the version in the source somewhere? Or would it bifurcate on @version
being String.t() | module()
? Can you even reference a module in mix.exs
?
You can reference a module anywhere, but I wouldn't do it there. We'd provide one called GitOps.VersionStorage.MixModuleAttribute
, and one called GitOps.VersionStorage.File
. They would put it in their application config which one they wanted to use, like
config :git_ops,
version_storage: MixModuleAttribute
# OR
config :git_ops,
version_storage: {MixModuleFile, [path: "priv/VERSION.txt"]}
Got it. That seems like it would do what we need.
Was there anything done on this? I have need of this too so might pick this one up
Nothing explicitly was done for this, but I have just recently pushed an addition (but not released it yet, because its untested and I still want to try it out) that allows you to manage multiple "readme" files, which may also help with what you're needing. e.g you can say manage_readme_version: ["README.md", "foo.md", ...]
@zachdaniel is this README managing feature merged? If so I could take a stab at this. Currently I calculate my project's version using this function:
def version() do
version =
Path.join(__DIR__, "VERSION")
|> File.read!()
|> String.trim()
git =
System.cmd("git", ["rev-parse", "--short", "HEAD"])
|> elem(0)
|> String.trim()
[version, git]
|> Enum.reject(&(is_nil(&1) or &1 == ""))
|> Enum.join("-")
end
If :git_ops
could handle the VERSION
file I would lift out the git part of this function and add it to my CI instead (by echo-ing the -<git short sha>
part into the file before building the release) and just rely on git_ops for managing the main part of it.
I'd imagine that what I'd need to do would be to read the VERSION
file as early as possible, so that the new version can be calculated before any other steps, and then write it back to disk when all steps have succeeded. Otherwise if any of the steps fail, and you rerun the command, it would keep bumping for each failure. Thoughts?
It kind of is, but it looks for ~>
in front of the version it replaces. I think we should add manage_version_file
as its own feature/option. Should be able to copy the logic for managing the readmes but just look for a single file by name and replace the contents exactly. PRs on that front welcome 😄
I'll see if I can get one done this week! :)
I already started a little bit, but looking at the code so far I realise that maybe one would want to point out where to source the version explicitly, rather than have options such as :manage_mix_version?
and :manage_version_file?
at the same time. What would setting both mean?
Instead – with backwards compatibility – one could have :version_source
that could default to nil
, keeping the original behaviour, but for new projects it could default to :mix_module
. And possible values could be: [:mix_module, :version_file]
for now. Thoughts? 🤔
So inside a
mix.exs
file, you can read files frompriv
, and in order to play nicely with different tools that interact with version files, it might be nice to be able read from e.g./priv/VERSION.txt
or something along those lines. Would it be possible to add the ability to specify the location of the version? The@version
tag would then@version File.read!("/priv/VERSION.txt")
in that case.One concern I have is that then
:manage_mix_version?
becomes weird, so it may need to be broken our to (e.g.):manages_version?
and:version_location
with special behavior based on if that ismix.exs
.