@@ -25,36 +25,38 @@ namespace mamba
2525 class Context ;
2626 class ChannelContext ;
2727
28- enum class file_parsing_error_code
28+ enum class lockfile_parsing_error_code
2929 {
30- unknown_failure, // / Something failed while parsing but we can't identify what.
31- unsupported_version, // / The version of the file does not matched supported ver.
32- parsing_failure, // / The content of the file doesnt match the expected format/language
33- // / structure or constraints.
34- invalid_data, // / The structure of the data in the file is fine but some fields have
35- // / invalid values for our purpose.
30+ unknown_failure, // /< Something failed while parsing but we can't identify what.
31+ unsupported_version, // /< The version of the file does not matched supported ver.
32+ parsing_failure, // /< The content of the file doesn't match the expected format/language
33+ // /< structure or constraints.
34+ invalid_data, // /< The structure of the data in the file is fine but some fields have
35+ // /< invalid values for our purpose.
36+ not_env_lockfile // /< The file doesn't seem to be a valid or supported lockfile file
37+ // /< format.
3638 };
3739
38- struct EnvLockFileError
40+ struct EnvLockFileError // TODO: inherit from mamba error
3941 {
40- file_parsing_error_code parsing_error_code = file_parsing_error_code ::unknown_failure;
41- std::optional<std::type_index> yaml_error_type {};
42+ lockfile_parsing_error_code parsing_error_code = lockfile_parsing_error_code ::unknown_failure;
43+ std::optional<std::type_index> error_type {};
4244
43- static const EnvLockFileError& get_details (const mamba_error& error)
45+ static auto get_details (const mamba_error& error) -> const EnvLockFileError&
4446 {
4547 return std::any_cast<const EnvLockFileError&>(error.data ());
4648 }
4749
4850 template <typename StringT>
49- static mamba_error make_error (
50- file_parsing_error_code error_code,
51+ static auto make_error (
52+ lockfile_parsing_error_code error_code,
5153 StringT&& msg,
52- std::optional<std::type_index> yaml_error_type = std::nullopt
53- )
54+ std::optional<std::type_index> error_type = std::nullopt
55+ ) -> mamba_error
5456 {
5557 return mamba_error{ std::forward<StringT>(msg),
5658 mamba_error_code::env_lockfile_parsing_failed,
57- EnvLockFileError{ error_code, yaml_error_type } };
59+ EnvLockFileError{ error_code, error_type } };
5860 }
5961 };
6062
@@ -64,7 +66,8 @@ namespace mamba
6466
6567 struct Channel
6668 {
67- std::string url;
69+ std::string name;
70+ std::vector<std::string> urls;
6871 std::vector<std::string> used_env_vars;
6972 };
7073
@@ -91,18 +94,62 @@ namespace mamba
9194 {
9295 }
9396
94- std::vector<specs::PackageInfo> get_packages_for (
95- std::string_view category,
96- std::string_view platform,
97- std::string_view manager
98- ) const ;
97+ struct PackageFilter
98+ {
99+ std::optional<std::string> category = std::nullopt ;
100+ std::optional<std::string> platform = std::nullopt ;
101+ std::optional<std::string> manager = std::nullopt ;
102+ bool allow_no_platform = false ; // will match empty platform
103+
104+ auto matches (const Package& package) const -> bool
105+ {
106+ bool matches_platform = not platform.has_value () or (package.platform == *platform)
107+ or (package.platform == " noarch" );
108+ if (platform.has_value () and not matches_platform and allow_no_platform)
109+ {
110+ matches_platform = package.platform .empty ();
111+ }
112+
113+ return matches_platform
114+ and (not category.has_value () or (package.category == *category))
115+ and (not manager.has_value () or (package.manager == *manager));
116+ }
117+
118+ auto operator ()(const Package& package) const -> bool
119+ {
120+ return matches (package);
121+ }
122+ };
123+
124+ template <typename F>
125+ requires std::is_invocable_r_v<bool , F, const Package&>
126+ auto get_packages_for (PackageFilter filter, F predicate) const
127+ -> std::vector<specs::PackageInfo>
128+ {
129+ std::vector<specs::PackageInfo> results;
130+
131+ for (const auto & package : m_packages)
132+ {
133+ if (filter.matches (package) and predicate (package))
134+ {
135+ results.push_back (package.info );
136+ }
137+ }
138+
139+ return results;
140+ }
141+
142+ auto get_packages_for (PackageFilter filter) const -> std::vector<specs::PackageInfo>
143+ {
144+ return get_packages_for (std::move (filter), [](const auto &) { return true ; });
145+ }
99146
100- const std::vector<Package>& get_all_packages () const
147+ auto get_all_packages () const -> const std::vector<Package>&
101148 {
102149 return m_packages;
103150 }
104151
105- const Meta& get_metadata () const
152+ auto get_metadata () const -> const Meta&
106153 {
107154 return m_metadata;
108155 }
@@ -113,14 +160,37 @@ namespace mamba
113160 std::vector<Package> m_packages;
114161 };
115162
116- // / Read an environment lock YAML file and returns it's structured content or an error if
163+ // / Describes a format of environment lockfile file supported by this library.
164+ enum class EnvLockfileFormat
165+ {
166+ undefined, // /< We don't know the format of the file.
167+ conda_yaml, // /< conda's yaml-based environment lockfile format.
168+ mambajs_json // /< mambajs's json-based environment lockfile format.
169+ };
170+
171+ // / Read an environment lock-file and returns it's structured content or an error if
117172 // / failed.
118- tl::expected<EnvironmentLockFile, mamba_error>
119- read_environment_lockfile (const mamba::fs::u8path& lockfile_location);
173+ // /
174+ // / @param lockfile_location The filesystem path to the file to open and read.
175+ // / @param file_format The expected file format of the file. If `undefined`, which is the
176+ // / default value, we guess based on the file's extension and content.
177+ auto read_environment_lockfile (
178+ const fs::u8path& lockfile_location,
179+ EnvLockfileFormat file_format = EnvLockfileFormat::undefined
180+ ) -> tl::expected<EnvironmentLockFile, mamba_error>;
181+
120182
183+ // / Returns `true` if the filename matches names of files which should be interpreted as conda
184+ // / or mambajs environment lockfile.
185+ // / NOTE: this does not check if the file exists.
186+ auto is_env_lockfile_name (std::string_view filename) -> bool;
121187
122188 // / Returns `true` if the filename matches names of files which should be interpreted as conda
123- // / environment lockfile. NOTE: this does not check if the file exists.
124- bool is_env_lockfile_name (std::string_view filename);
189+ // / NOTE: this does not check if the file exists.
190+ auto is_conda_env_lockfile_name (std::string_view filename) -> bool;
191+
192+ // / Deduce the environment lockfile format of a file path based on it's filename.
193+ // / TODO: more info?
194+ auto deduce_env_lockfile_format (const fs::u8path& lockfile_location) -> EnvLockfileFormat;
125195}
126196#endif
0 commit comments