ParseRef parses a raw flake reference. Nix supports a variety of flake ref formats, and isn't entirely consistent about how it parses them. ParseRef attempts to mimic how Nix parses flake refs on the command line. The raw ref can be one of the following: - Indirect reference such as "nixpkgs" or "n
(ref string)
| 95 | // error indicates an invalid flake ref. Use the "nix flake metadata" command or |
| 96 | // the builtins.parseFlakeRef Nix function to validate a flake ref. |
| 97 | func ParseRef(ref string) (Ref, error) { |
| 98 | if ref == "" { |
| 99 | return Ref{}, redact.Errorf("empty flake reference") |
| 100 | } |
| 101 | |
| 102 | // Handle path-style references first. |
| 103 | parsed := Ref{} |
| 104 | if ref[0] == '.' || ref[0] == '/' { |
| 105 | if strings.ContainsAny(ref, "?#") { |
| 106 | // The Nix CLI does seem to allow paths with a '?' |
| 107 | // (contrary to the manual) but ignores everything that |
| 108 | // comes after it. This is a bit surprising, so we just |
| 109 | // don't allow it at all. |
| 110 | return Ref{}, redact.Errorf("path-style flake reference %q contains a '?' or '#'", ref) |
| 111 | } |
| 112 | parsed.Type = TypePath |
| 113 | parsed.Path = ref |
| 114 | return parsed, nil |
| 115 | } |
| 116 | parsed, fragment, err := parseURLRef(ref) |
| 117 | if fragment != "" { |
| 118 | return Ref{}, redact.Errorf("flake reference %q contains a URL fragment", ref) |
| 119 | } |
| 120 | return parsed, err |
| 121 | } |
| 122 | |
| 123 | func parseURLRef(ref string) (parsed Ref, fragment string, err error) { |
| 124 | // A good way to test how Nix parses a flake reference is to run: |