|
2801 | 2801 | },
|
2802 | 2802 |
|
2803 | 2803 | package =
|
2804 |
| - let |
| 2804 | + let rec |
2805 | 2805 | # https://semver.org is kind enough to supply this "official" semver regex.
|
2806 |
| - semver_re = m%"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"% in let |
2807 |
| - # An expression representing a range of semver versions, like `<1.2`. |
2808 |
| - # Unlike semver itself, semver range expressions don't seem to have an official standard. |
2809 |
| - semver_main_range_re = m%"(~|=|\^|<|>|<=|>=)?(0|[1-9]\d*)(\.(0|[1-9]\d*))?(\.(0|[1-9]\d*))?"% in let |
2810 |
| - # For requirements with non-empty prereleases, we support exactly two flavors: 0.1.2-pre3 or =0.1.2-pre3. |
2811 |
| - # We could also support inequalities, but we should avoid ^ and ~ because prereleases have no guaranteed |
2812 |
| - # compatibility semantics. |
2813 |
| - semver_prerelease_range_re = m%"=?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)-((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*)"% in let semver_range_re = "(%{semver_main_range_re})|(%{semver_prerelease_range_re})" in |
2814 |
| - let semver_req_re = m%"^(%{semver_range_re}(,\s*%{semver_range_re})*)$"% in |
2815 |
| - { |
| 2806 | + semver_re_unanchored = m%"(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?"%, |
| 2807 | + semver_re = "^%{semver_re_unanchored}$", |
| 2808 | + # Just the major.minor.patch part, with minor and patch being optional. |
| 2809 | + partial_semver_re_unanchored = m%"(0|[1-9]\d*)(\.(0|[1-9]\d*))?(\.(0|[1-9]\d*))?"%, |
| 2810 | + partial_semver_re = "^%{partial_semver_re_unanchored}$", |
| 2811 | + # An exact version constraint. This one is required to have minor and patch versions, and it's allowed to have a prerelease. |
| 2812 | + semver_equals_req_re = m%"^=(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?$"%, |
| 2813 | + semver_req_re = "(%{partial_semver_re})|(%{semver_equals_req_re})", |
| 2814 | + in { |
2816 | 2815 | is_semver_req
|
2817 | 2816 | : String -> Bool
|
2818 | 2817 | | doc m%"
|
2819 |
| - Returns true if a string is a valid semantic version requirement. |
| 2818 | + Returns true if a string is a valid version requirement in Nickel. |
| 2819 | + |
| 2820 | + See the `SemverReq` contract for more details. |
2820 | 2821 | "%
|
2821 | 2822 | = std.string.is_match semver_req_re,
|
2822 | 2823 | is_semver
|
2823 | 2824 | : String -> Bool
|
2824 | 2825 | | doc m%"
|
2825 |
| - Returns true if a string is a valid semantic version identifier. |
| 2826 | + Returns true if a string is a valid semantic version. |
| 2827 | + |
| 2828 | + # Examples |
| 2829 | + |
| 2830 | + ```nickel multiline |
| 2831 | + std.package.is_semver "1.2.0-pre1" |
| 2832 | + # => true |
| 2833 | + |
| 2834 | + std.package.is_semver "1.foo" |
| 2835 | + # => false |
| 2836 | + ``` |
2826 | 2837 | "%
|
2827 | 2838 | = std.string.is_match semver_re,
|
| 2839 | + is_semver_prefix |
| 2840 | + : String -> Bool |
| 2841 | + | doc m%" |
| 2842 | + Returns true if a string is a valid semantic version prefix, |
| 2843 | + containing a major version and then optional minor and patch versions. |
| 2844 | + |
| 2845 | + # Examples |
| 2846 | + |
| 2847 | + ```nickel multiline |
| 2848 | + std.package.is_semver_prefix "1.2" |
| 2849 | + # => true |
| 2850 | + |
| 2851 | + std.package.is_semver_prefix "1.foo" |
| 2852 | + # => false |
| 2853 | + ``` |
| 2854 | + "% |
| 2855 | + = std.string.is_match partial_semver_re, |
2828 | 2856 | Semver
|
2829 | 2857 | | doc m%"
|
2830 | 2858 | A contract for semantic version ("semver") identifiers.
|
2831 | 2859 |
|
2832 | 2860 | # Examples
|
2833 | 2861 |
|
2834 |
| - ```nickel |
| 2862 | + ```nickel multiline |
2835 | 2863 | "1.2.0-pre1" | std.package.Semver
|
2836 |
| - => "1.2.0-pre1" |
| 2864 | + # => "1.2.0-pre1" |
2837 | 2865 |
|
2838 | 2866 | "1.foo" | std.package.Semver
|
2839 |
| - => error: contract broken by a value |
| 2867 | + # => error: contract broken by a value |
2840 | 2868 | ```
|
2841 | 2869 | "%
|
2842 | 2870 | = std.contract.from_predicate is_semver,
|
| 2871 | + SemverPrefix |
| 2872 | + | doc m%" |
| 2873 | + A contract for semantic version ("semver") prefixes, |
| 2874 | + containing a major version and then optional minor and patch versions. |
| 2875 | + |
| 2876 | + # Examples |
| 2877 | + |
| 2878 | + ```nickel multiline |
| 2879 | + "1.2" | std.package.SemverPrefix |
| 2880 | + # => "1.2" |
| 2881 | + |
| 2882 | + "1.foo" | std.package.SemverPrefix |
| 2883 | + # => error: contract broken by a value |
| 2884 | + ``` |
| 2885 | + "% |
| 2886 | + = std.contract.from_predicate is_semver_prefix, |
2843 | 2887 | SemverReq
|
2844 | 2888 | | doc m%"
|
2845 | 2889 | A contract for semantic version ("semver") requirements.
|
2846 | 2890 |
|
| 2891 | + Nickel supports two kinds of requirements: semver-compatible |
| 2892 | + requirements and exact version requirements. Semver-compatible |
| 2893 | + requirements take the form "major.minor.patch", where minor and patch |
| 2894 | + are optional. Their semantics are: |
| 2895 | + |
| 2896 | + - "1.2.3" will match all versions having major version 1, minor version 2, |
| 2897 | + and patch version at least 3. |
| 2898 | + - "1.2" will match all versions having major version 1 and minor version |
| 2899 | + at least 2. |
| 2900 | + - "1" will match all versions having major version 1. |
| 2901 | + - a semver-compatible requirement will never match a prerelease version. |
| 2902 | + |
| 2903 | + Exact version requirements take the form "=major.minor.patch-pre", where |
| 2904 | + the prerelease tag is optional, but major, minor, and patch are all required. |
| 2905 | + |
2847 | 2906 | # Examples
|
2848 | 2907 |
|
2849 |
| - ```nickel |
2850 |
| - "^1.2" | std.package.SemverReq |
2851 |
| - => "^1.2" |
| 2908 | + ```nickel multiline |
| 2909 | + "1.2" | SemverReq |
| 2910 | + # => "1.2" |
2852 | 2911 |
|
2853 |
| - ">=1.2, <1.4" | std.package.SemverReq |
2854 |
| - => ">=1.2, <1.4" |
| 2912 | + "=1.2" | SemverReq |
| 2913 | + # => error: contract broken by a value |
| 2914 | + |
| 2915 | + "1.2.0" | SemverReq |
| 2916 | + # => "1.2.0" |
| 2917 | + |
| 2918 | + "=1.2.0" | SemverReq |
| 2919 | + # => "=1.2.0" |
| 2920 | + |
| 2921 | + "1.2.0-pre1" | SemverReq |
| 2922 | + # => error: contract broken by a value |
| 2923 | + |
| 2924 | + "=1.2.0-pre1" | SemverReq |
| 2925 | + # => "=1.2.0-pre1" |
| 2926 | + ``` |
2855 | 2927 | "%
|
2856 | 2928 | = std.contract.from_predicate is_semver_req,
|
| 2929 | + # TODO: bikeshedding opportunity: which fields should be optional? |
2857 | 2930 | Manifest = {
|
2858 | 2931 | name
|
2859 | 2932 | | String
|
|
2870 | 2943 |
|
2871 | 2944 | nickel_version
|
2872 | 2945 | | String
|
2873 |
| - # TODO: this is too strict, as it requires a full major.minor.patch. We should also allow major.minor |
2874 |
| - | Semver |
| 2946 | + | SemverPrefix |
2875 | 2947 | | doc m%"
|
2876 | 2948 | The minimal nickel version required for this package.
|
2877 | 2949 | "%,
|
2878 | 2950 |
|
| 2951 | + authors |
| 2952 | + | Array String |
| 2953 | + | doc m%" |
| 2954 | + The authors of this package. |
| 2955 | + "%, |
| 2956 | + |
| 2957 | + description |
| 2958 | + | String |
| 2959 | + | doc m%" |
| 2960 | + A description of this package. |
| 2961 | + "%, |
| 2962 | + |
| 2963 | + keywords |
| 2964 | + | Array String |
| 2965 | + | optional |
| 2966 | + | doc m%" |
| 2967 | + A list of keywords to help people find this package. |
| 2968 | + "%, |
| 2969 | + |
| 2970 | + # TODO: maybe restrict this to be a valid SPDX 2.3 license expression? |
| 2971 | + # We can also allow arbitrary strings, but only accept index packages |
| 2972 | + # with clear licenses |
| 2973 | + license |
| 2974 | + | String |
| 2975 | + | optional |
| 2976 | + | doc m%" |
| 2977 | + The name of the license that this package is available under. |
| 2978 | + "%, |
| 2979 | + |
2879 | 2980 | dependencies
|
2880 | 2981 | | {
|
2881 | 2982 | _ : [|
|
|
0 commit comments