# verl [![Hex Version](https://img.shields.io/hexpm/v/verl.svg)](https://hex.pm/packages/verl) [![GitHub Actions CI](https://github.com/jelly-beam/verl/workflows/build/badge.svg)](https://github.com/jelly-beam/verl ) [![codecov](https://codecov.io/gh/jelly-beam/verl/branch/main/graph/badge.svg)](https://codecov.io/gh/jelly-beam/verl) SemVer 2.0 version and requirements parsing, matching, and comparisons. All parsing of versions and requirements adhere to the [SemVer 2.0 schema](http://semver.org/) - [Build](#build) - [Usage](#usage) * [Comparisons](#comparisons) * [Version, Requirements, and Matching](#version--requirements--and-matching) - [Matching](#matching) - [Compiled requirements for ludicious speed matching](#compiled-requirements-for-ludicious-speed-matching) - [Version parsing](#version-parsing) * [Requirements parsing](#requirements-parsing) - [Credits](#credits) ## Build ```bash $ rebar3 compile ``` ## Test ```bash $ rebar3 test ``` ## Usage Add to you deps configuration in rebar.config for your project : ```erlang {deps, [{verl, "1.1.0"}]}. ``` ### Comparisons ```erlang 1> verl:compare(<<"1.0.0">>, <<"1.0.1">>). lt 2> verl:compare(<<"1.0.0">>, <<"1.0.0">>). eq 3> verl:compare(<<"2.0.0">>, <<"1.0.0">>). gt 4> verl:compare(<<"1.0.0-pre">>, <<"1.0.0">>). lt 5> verl:compare(<<"1.0.0">>, <<"1.0.0-pre">>). gt ``` ### Version, Requirements, and Matching #### Matching ```erlang 1> verl:is_match(<<"1.0.0">>, <<"~> 1.0.0">>). true 2> verl:is_match(<<"1.0.0">>, <<"~> 2.0.0">>). false 3> verl:is_match(<<"3.2.0">>, <<"~> 3.0.0">>). false 4> verl:is_match(<<"3.2.0">>, <<"~> 3.0">>). true ``` #### Compiled requirements for ludicious speed matching ```erlang 1> {ok, Req} = verl:parse_requirement(<<"~> 3.0">>). {ok,#{compiled => false, string => <<"~> 3.0">>, matchspec => [{{'$1','$2','$3','$4','$5'}...}], string => <<"~> 3.0">>}} 2> verl:is_match(<<"3.0.0-dev">>, Req). false 3> verl:is_match(<<"1.2.3">>, Req). false 4> verl:is_match(<<"3.1.0">>, Req). true ``` #### Version parsing ```erlang 1> verl:parse(<<"1.2.3">>). #{build => undefined,major => 1,minor => 2,patch => 3, pre => []} 2> verl:parse(<<"1.2.3+build">>). #{build => <<"build">>,major => 1,minor => 2,patch => 3, pre => []} 3> verl:parse(<<"1.2.3-pre+build">>). #{build => <<"build">>,major => 1,minor => 2,patch => 3, pre => [<<"pre">>]} 4> verl:parse(<<"1">>). {error, invalid_version} 5> verl:parse(<<"2">>). {error, invalid_version} ``` Don't want a map? Use the `verl_parser` module... ```erlang 1> verl_parser:parse_version(<<"1.2.3">>). {ok,{1,2,3,[],[]}} 2> verl_parser:parse_version(<<"1.2.3+build">>). {ok,{1,2,3,[],[<<"build">>]}} 3> verl_parser:parse_version(<<"1.2.3-pre+build">>). {ok,{1,2,3,[<<"pre">>],[<<"build">>]}} 4> verl_parser:parse_version(<<"1">>). {error, invalid_version} ``` ##### Requirements parsing ```erlang 1> verl:parse_requirement(<<"~> 2.1.0-dev">>). {ok,#{compiled => false, string => <<"~> 2.1.0-dev">>, matchspec => [{{'$1','$2','$3','$4','$5'}...] }} 2> verl:parse_requirement(<<"~> 2.1.0-">>). {error,invalid_requirement} ``` Don't want a map? User the `verl_parser` module... ```erlang 1> verl_parser:parse_requirement(<<"~> 2.1.0-dev">>). {ok, [{{'$1','$2','$3','$4','$5'}...]} 2> verl:parse_requirement(<<"~> 2.1.0-">>). {error,invalid_requirement} ``` ## Credits - All credit goes to the Elixir team and contributors to Version and Version.Parser in the Elixir standard lib for the algorithm and original implementation.