diff options
-rw-r--r-- | bdep/project.cxx | 34 | ||||
-rw-r--r-- | bdep/release.cxx | 120 |
2 files changed, 106 insertions, 48 deletions
diff --git a/bdep/project.cxx b/bdep/project.cxx index cf79e41..4d93d53 100644 --- a/bdep/project.cxx +++ b/bdep/project.cxx @@ -6,6 +6,7 @@ #include <bdep/project-odb.hxx> #include <libbutl/b.mxx> +#include <libbutl/manifest-parser.mxx> #include <libbpkg/manifest.hxx> @@ -245,15 +246,38 @@ namespace bdep static void load_package_names (const dir_path& prj, package_locations& pls) { - // Load each package's manifest and obtain its name (name is normally the - // first value so we could optimize this, if necessary). + // Load each package's manifest and obtain its name and project (they are + // normally at the beginning of the manifest so we could optimize this, if + // necessary). // for (package_location& pl: pls) { path f (prj / pl.path / manifest_file); - auto m (parse_manifest<bpkg::package_manifest> (f, "package")); - pl.name = move (m.name); - pl.project = move (m.project); + + if (!exists (f)) + fail << "package manifest file " << f << " does not exist"; + + try + { + ifdstream is (f); + manifest_parser p (is, f.string ()); + + bpkg::package_manifest m (p, + false /* ignore_unknown */, + false /* complete_depends */); + + pl.name = move (m.name); + pl.project = move (m.project); + } + catch (const manifest_parsing& e) + { + fail << "invalid package manifest: " << f << ':' + << e.line << ':' << e.column << ": " << e.description << endf; + } + catch (const io_error& e) + { + fail << "unable to read " << f << ": " << e << endf; + } } } diff --git a/bdep/release.cxx b/bdep/release.cxx index cf9438d..3c4a7e7 100644 --- a/bdep/release.cxx +++ b/bdep/release.cxx @@ -6,7 +6,7 @@ #include <iostream> // cout -#include <libbutl/manifest-types.mxx> // manifest_name_value +#include <libbutl/manifest-parser.mxx> #include <libbutl/manifest-rewriter.mxx> #include <libbpkg/manifest.hxx> @@ -525,53 +525,87 @@ namespace bdep // ensure the repository will not be broken, similar to how we do it in // publish. // - auto parse_manifest = [] (const path& f) + auto parse_manifest = [&o] (const path& f) { - manifest_name_value r; + using bpkg::version; + using bpkg::package_manifest; - auto m (bdep::parse_manifest<bpkg::package_manifest> ( - f, - "package", - false /* ignore_unknown */, - [&r] (manifest_name_value& nv) - { - if (nv.name == "version") - r = nv; + if (!exists (f)) + fail << "package manifest file " << f << " does not exist"; - return true; - })); + manifest_name_value r; - // - // Validate the *-file manifest values expansion. - // - // Note: not forcible. Allowing releasing broken packages we are just - // asking for trouble and long mailing list threads. - // - m.load_files ([&f] (const string& n, const path& p) + try { - path vf (f.directory () / p); - - try - { - ifdstream is (vf); - string s (is.read_text ()); - - if (s.empty ()) - fail << n << " manifest value in " << f << " references empty " - << "file " << vf; - - return s; - } - catch (const io_error& e) - { - fail << "unable to read " << vf << " referenced by " << n - << " manifest value in " << f << ": " << e << endf; - } - }); - - assert (!r.empty ()); - r.value = m.version.string (); // For good measure. - return r; + ifdstream is (f); + manifest_parser p (is, + f.string (), + [&r] (manifest_name_value& nv) + { + if (nv.name == "version") + r = nv; + + return true; + }); + + dir_path d (f.directory ()); + + // Parse the package manifest populating the version snapshot + // information and completing dependency constraints. Save the + // original version into the result. + // + // Note that the dependency constraint parsing may fail if the + // dependent version it refers to is a latest snapshot (see + // dependency_constraint for details). That's why the version + // translation is required. + // + package_manifest m (p, + [&o, &d, &r] (version& v) + { + r.value = v.string (); // For good measure. + v = version (package_version (o, d).string ()); + }); + + // Validate the *-file manifest values expansion. + // + // Note: not forcible. Allowing releasing broken packages we are just + // asking for trouble and long mailing list threads. + // + m.load_files ([&f, &d] (const string& n, const path& p) + { + path vf (d / p); + + try + { + ifdstream is (vf); + string s (is.read_text ()); + + if (s.empty ()) + fail << n << " manifest value in " << f + << " references empty " << "file " << vf; + + return s; + } + catch (const io_error& e) + { + fail << "unable to read " << vf << " referenced by " + << n << " manifest value in " << f << ": " << e + << endf; + } + }); + + assert (!r.empty ()); + return r; + } + catch (const manifest_parsing& e) + { + fail << "invalid package manifest: " << f << ':' + << e.line << ':' << e.column << ": " << e.description << endf; + } + catch (const io_error& e) + { + fail << "unable to read " << f << ": " << e << endf; + } }; // Collect project/package information. |