using Invercargill; namespace Usm { public errordomain ManifestError { MISSING_FIELD, INVALID_VERSION, INVALID_LICENCE_CATEGORY, INVALID_RESOURCE_TYPE, INVALID_FILE_TYPE, INVALID_REMOVE_TYPE, INVALID_INSTALL_TYPE, } public class Manifest { public string name { get; set; } public string summary { get; set; } public Version version { get; set; } public Vector licences { get; set; } public Dictionary provides { get; set; } public Dependencies dependencies { get; set; } public Executables executables { get; set; } public string? markdown_path { get; set; } public string? url { get; set; } public Vector? screenshot_paths { get; set; } public string? icon_path { get; set; } public string? metainfo_path { get; set; } public Git? git { get; set; } public Properties? extra_properties { get; set; } public static PropertyMapper get_mapper() { return new PropertyMapperBuilder() .map("name", o => o.name, (o, v) => o.name = v) .map("version", o => o.version.to_string(), (o, v) => o.version = new Version.from_string(v)) .map("summary", o => o.summary, (o, v) => o.summary = v) .map_many_with("licences", o => o.licences, (o, v) => o.licences = v.to_vector(), Licence.get_mapper()) .map("provides", o => o.map_from_provides_dict(), (o, v) => o.build_provides_dict(v)) .map_with("depends", o => o.dependencies, (o, v) => o.dependencies = v, Dependencies.get_mapper()) .map_with("execs", o => o.executables, (o, v) => o.executables = v, Executables.get_mapper()) .map("md", o => o.markdown_path, (o, v) => o.markdown_path = v, false) .map("url", o => o.url, (o, v) => o.url = v, false) .map_many("screenshots", o => o.screenshot_paths, (o, v) => o.screenshot_paths = v.to_vector(), false) .map("icon", o => o.icon_path, (o, v) => o.icon_path = v, false) .map("metainfo", o => o.metainfo_path, (o, v) => o.metainfo_path = v, false) .map_with("git", o => o.git, (o, v) => o.git = v, Git.get_mapper(), false) .map("extras", o => o.extra_properties, (o, v) => o.extra_properties = v, false) .set_constructor(() => new Manifest()) .build(); } private void build_provides_dict(Properties obj) throws Error { provides = new Dictionary(); var mapper = ManifestFile.get_mapper(); foreach (var pair in obj) { if(pair.value.assignable_to()) { provides[new ResourceRef(pair.key)] = new ManifestFile.from_string(pair.value.as()); } else { provides[new ResourceRef(pair.key)] = mapper.materialise(obj); } } } private Properties map_from_provides_dict() { var dict = new PropertiesDictionary(); var mapper = ManifestFile.get_mapper(); foreach (var pair in provides) { try { dict.set_native(pair.key.to_string(), mapper.map_from(pair.value)); } catch(Error e) { assert_not_reached(); } } return dict; } public Subprocess run_build(string build_path, Paths paths, SubprocessFlags flags) throws Error { var path = Path.build_filename(Environment.get_current_dir(), executables.build); paths.set_envs(); var proc = new Subprocess.newv(new string[] { path, build_path }, flags); return proc; } public Subprocess? run_rebuild(string build_path, SubprocessFlags flags) throws Error { if(executables.rebuild == null) { return null; } var path = Path.build_filename(Environment.get_current_dir(), executables.rebuild); var proc = new Subprocess.newv(new string[] { path, build_path }, flags); return proc; } public Subprocess? run_acquire(SubprocessFlags flags) throws Error { if(executables.acquire == null) { return null; } var path = Path.build_filename(Environment.get_current_dir(), executables.acquire); var proc = new Subprocess.newv(new string[] { path }, flags); return proc; } public Subprocess? run_install(string build_path, InstallType type, SubprocessFlags flags) throws Error { if(executables.install == null) { return null; } var path = Path.build_filename(Environment.get_current_dir(), executables.install); var proc = new Subprocess.newv(new string[] { path, build_path, type.to_string() }, flags); return proc; } public Subprocess? run_remove(string build_path, RemoveType type, SubprocessFlags flags) throws Error { if(executables.remove == null) { return null; } var path = Path.build_filename(Environment.get_current_dir(), executables.remove); var proc = new Subprocess.newv(new string[] { path, build_path, type.to_string() }, flags); return proc; } } public enum InstallType { FRESH, UPGRADE, DOWNGRADE; public string to_string() { switch (this) { case InstallType.FRESH: return "fresh"; case InstallType.UPGRADE: return "upgrade"; case InstallType.DOWNGRADE: return "downgrade"; default: assert_not_reached(); } } public static InstallType from_string(string str) throws ManifestError { switch (str) { case "fresh": return InstallType.FRESH; case "upgrade": return InstallType.UPGRADE; case "downgrade": return InstallType.DOWNGRADE; default: throw new ManifestError.INVALID_REMOVE_TYPE(@"Unknown install type \"$str\"."); } } } public enum RemoveType { FINAL, UPGRADE, DOWNGRADE; public string to_string() { switch (this) { case RemoveType.FINAL: return "final"; case RemoveType.UPGRADE: return "upgrade"; case RemoveType.DOWNGRADE: return "downgrade"; default: assert_not_reached(); } } public static RemoveType from_string(string str) throws ManifestError { switch (str) { case "final": return RemoveType.FINAL; case "upgrade": return RemoveType.UPGRADE; case "downgrade": return RemoveType.DOWNGRADE; default: throw new ManifestError.INVALID_REMOVE_TYPE(@"Unknown remove type \"$str\"."); } } } }