-
-
Save jeffweiss/9df547a4e472e3cf5bd3 to your computer and use it in GitHub Desktop.
| defmodule MyApp.Mixfile do | |
| use Mix.Project | |
| def project do | |
| [app: :my_app, | |
| version: get_version, | |
| elixir: "~> 1.0", | |
| elixirc_paths: elixirc_paths(Mix.env), | |
| compilers: Mix.compilers, | |
| build_embedded: Mix.env == :prod, | |
| start_permanent: Mix.env == :prod, | |
| deps: deps] | |
| end | |
| # Configuration for the OTP application | |
| # | |
| # Type `mix help compile.app` for more information | |
| def application do | |
| [mod: {MyApp, []}, | |
| applications: [:logger]] | |
| end | |
| defp get_version do | |
| version_from_file | |
| |> handle_file_version | |
| |> String.split("-") | |
| |> case do | |
| [tag] -> tag | |
| [tag, _num_commits, commit] -> "#{tag}-#{commit}" | |
| end | |
| end | |
| defp version_from_file(file \\ "VERSION") do | |
| File.read(file) | |
| end | |
| defp handle_file_version({:ok, content}) do | |
| content | |
| end | |
| defp handle_file_version({:error, _}) do | |
| retrieve_version_from_git | |
| end | |
| defp retrieve_version_from_git do | |
| require Logger | |
| Logger.warn "Calling out to `git describe` for the version number. This is slow! You should think about a hook to set the VERSION file" | |
| System.cmd("git", ["describe", "--always", "--tags"]) | |
| |> Tuple.to_list | |
| |> List.first | |
| |> String.strip | |
| end | |
| # Specifies which paths to compile per environment | |
| defp elixirc_paths(:test), do: ["lib", "web", "test/support"] | |
| defp elixirc_paths(_), do: ["lib", "web"] | |
| # Specifies your project dependencies | |
| # | |
| # Type `mix help deps` for examples and options | |
| defp deps do | |
| [ | |
| ] | |
| end | |
| end |
| #!/bin/bash | |
| # installed to .git/hooks/post-checkout | |
| `git describe --always --tags > VERSION` |
| #!/bin/bash | |
| # installed to .git/hooks/post-commit | |
| `git describe --always --tags > VERSION` |
Wow--that is a very handy idea.
Please, please, please don't do it. PLEASE. You are now adding a system call via ports every time we need to load the dependency metadata. The Ruby/Rails community relied so heavily on it that it would add multiple seconds when booting Rails applications. Please don't do this.
@josevalim I updated with
- VERSION file set by git hooks
- warning about how slow it is if a VERSION file isn't there
Thoughts?
Thanks for this. I think @josevalim's point is valid, but your workaround here seems like a good approach. The one problem I see is with CI systems, which won't have the git hooks installed already. I wonder if anyone else has come up with a different solution to this? It seems like versioning based off git tags makes a lot of sense.
You could also change this:
System.cmd("git", ["describe", "--always", "--tags"])
|> Tuple.to_list
|> List.first
|> String.stripto this:
System.cmd("git", ["describe", "--always", "--tags"])
|> elem(0)
|> String.stripI merged the recommendations above, fixed the warnings about missing ()'s, removed 'v' and only changed one '-' to '.', so tags in the form vN.N work well with mix's SemVer check.
Given a tag like v2.3 then it will produce version "2.3", then after 5 extra commits produce "2.3.5-gitsha", optionally adding -dirty if there where uncommitted files (Officially this makes it a pre-release of 2.3.5, but since each commit increments the patch version, it isn't an issue).
defp get_version do
version_from_file()
|> handle_file_version()
|> String.replace_leading("v", "")
|> String.replace("-", ".", global: false)
end
defp version_from_file(file \\ "VERSION") do
File.read(file)
end
defp handle_file_version({:ok, content}) do
content
end
defp handle_file_version({:error, _}) do
retrieve_version_from_git()
end
defp retrieve_version_from_git do
require Logger
Logger.warn "Calling out to `git describe` for the version number. This is slow! You should think about a hook to set the VERSION file"
System.cmd("git", ~w{describe --dirty --always --tags --first-parent})
|> elem(0)
|> String.trim
end
git describe --dirty --abbrev=7 --tags --always --first-parentis also useful BTW:e.g.
1.6.1-4-g95cb436-dirty