Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version File Instead of Mix.exs #16

Open
asummers opened this issue Jul 6, 2019 · 9 comments
Open

Version File Instead of Mix.exs #16

asummers opened this issue Jul 6, 2019 · 9 comments

Comments

@asummers
Copy link
Collaborator

asummers commented Jul 6, 2019

So inside a mix.exs file, you can read files from priv, 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 is mix.exs.

@zachdaniel
Copy link
Owner

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

@asummers
Copy link
Collaborator Author

asummers commented Jul 9, 2019

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?

@zachdaniel
Copy link
Owner

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"]}

@asummers
Copy link
Collaborator Author

asummers commented Jul 9, 2019

Got it. That seems like it would do what we need.

@simpers
Copy link

simpers commented Apr 4, 2022

Was there anything done on this? I have need of this too so might pick this one up

@zachdaniel
Copy link
Owner

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", ...]

@simpers
Copy link

simpers commented Jun 30, 2023

@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?

@zachdaniel
Copy link
Owner

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 😄

@simpers
Copy link

simpers commented Jul 3, 2023

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? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants