Proposal can also be read on gist. <https://gist.github.com/benstepp/35d35e09315ca11adad3c7777b516bc0>
--- *Motivation:* We were using System.otp_release() as a part of a cache-key in our build system, and a patch version of an OTP release introduced an ssl handshake bug in a few of our applications. Once we pinned down the problem, and cleared our build cache, we realized we should have been using the full otp version as the cache key, instead of just the major release. *Existing behaviour:* - System.version() returns the full elixir version (ie: "1.14.0"). - System.otp_release() returns the major portion of the otp release (ie. "25"). Note that System.otp_release() just calls :erlang.system_info(:system_version) which only returns "25" because "The exact OTP version in the general case is difficult to determine" source <https://www.erlang.org/doc/man/erlang.html#system_info_otp_release> *Current workarounds:* The current OTP version can be found using the method here <https://www.erlang.org/doc/system_principles/versions.html#retrieving-current-otp-version> . And this workaround can already be found among the community: - hex <https://github.com/hexpm/hex/blob/b2f23089d6c609465c3b570b4fc40c469b57cc1b/lib/hex/utils.ex#L263-L276> - dialyzer <https://github.com/jeremyjh/dialyxir/blob/b78735f75b325238b7db20d9eed22f018cca5f26/lib/dialyxir/project.ex#L221-L238> - elsewhere (github code search) <https://github.com/search?q=Path.join%28%5B%3Acode.root_dir%28%29%2C+%22releases%22%2C+major%2C+%22OTP_VERSION%22%5D%29&type=code> *Solution:* The proposal is to add a better function that can return the full otp version, somewhere in the core library. Here are a few example APIs that do not have any breaking changes, but the final result doesn't have to be one of these: *Example api with options seen in the Version module:* # Return major version (existing behaviour) iex> System.otp_release() "25" # Return up to the major version (same as existing) iex> System.otp_release(:major) "25" # Return up to the minor version iex> System.otp_release(:minor) "25.0" # Return up to the patch version iex> System.otp_release(:patch) "25.0.4" # Return up to the pre-release version iex> System.otp_release(:pre) "25.0-rc3" *Example api with options seen in Date, DateTime, modules:* # Return major version (existing behaviour) iex> System.otp_release() "25" # Return the full version iex> System.otp_release(:extended) "25.0.4" *Example api returning a %Version{} struct instead of a string:* Version implements String.Chars so it's pretty easy to get the string this way. This one is probably my favorite, but it means System.version() and System.otp_version() would have different call signatures, which may not be very ergonomic. # Return major version (existing behaviour) iex> System.otp_release() "25" # Returns the full version iex> v = System.otp_version() %Version{major: 25, minor: 0, patch: 4} iex> to_string(v) "25.0.4" --- I haven't thought too much about how to handle file read/version parsing failures, but falling back to the current behaviour of returning the major version might be acceptable. Also, it may be considered too dangerous to have a file reading and version parsing function like this in the core library, without :ok/:error tuples which I totally understand (There's an existing workaround that works for all of our use cases). Thank you for your time and consideration, and sorry if something similar has been requested before; I tried searching, but "version" "otp" and "release" show up in pretty much every discussion on this mailing list. -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/fd52d094-cbcc-4b2a-9939-41774274c159n%40googlegroups.com.