Ver Fonte

More features

Billy Barrow há 10 meses atrás
pai
commit
449925f716

+ 4 - 5
MANIFEST.usm

@@ -8,8 +8,8 @@
     "lib:libusm.so": "lib/libusm.so",
     "inc:usm.h": "lib/usm.h",
     "vapi:usm.vapi": "lib/usm.vapi",
-    "libres:girepository-1.0/usm-1.0.typelib": "lib/usm-1.0.typelib",
-    "res:share/gir-1.0/usm-1.0.gir": "lib/usm-1.0.gir",
+    "typelib:usm-1.0.typelib": "lib/usm-1.0.typelib",
+    "gir:usm-1.0.gir": "lib/usm-1.0.gir",
     "pc:usm.pc": "meson-private/usm.pc"
   },
   "depends": {
@@ -48,8 +48,7 @@
     ]
   },
   "execs": {
-    "install": "scripts/install",
-    "remove": "scripts/remove",
-    "build": "scripts/build.sh"
+    "build": "scripts/build.sh",
+    "acquire": "scripts/acquire.sh"
   }
 }

+ 4 - 0
scripts/acquire.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+
+git clone https://git.sr.ht/~tilo15/usm .

+ 38 - 5
src/cli/Cli.vala

@@ -12,9 +12,8 @@ public static int main(string[] args) {
     }
 
     var verb = args[1];
-    var cwd = Environment.get_current_dir();
 
-    if(verb != "remove") {
+    if(verb != "remove" && verb != "acquire") {
         if(args.length < 3) {
             usage();
             return 255;
@@ -44,13 +43,17 @@ public static int main(string[] args) {
         return install();
     }
 
+    if(verb == "acquire") {
+        return acquire();
+    }
+
 
     usage();
     return 255;
 }
 
 private void usage() {
-    printerr("USAGE:\n\tusm build <build path>\n\tusm rebuild <build path>\n\tusm install <build path>\n\tusm remove\n");
+    printerr("USAGE:\n\tusm build <build path>\n\tusm rebuild <build path>\n\tusm install <build path>\n\tusm remove\nusm acquire\n");
 }
 
 
@@ -138,7 +141,7 @@ private int install() {
         }
         catch(Error e) {
             printerr(@" $(e.message)\n");
-            return 249;
+            return 250;
         }
         printerr(" done\n");
     }
@@ -151,9 +154,39 @@ private int install() {
     }
     catch(Error e) {
         printerr(@"Error running install exec: $(e.message)\n");
-        return 250;
+        return 249;
     }
 
     return 0;
 }
 
+
+private int acquire() {
+    if(manifest.executables.acquire == null) {
+        printerr(@"Manifest does not reference an acquire script\n");
+        return 248;
+    }
+
+    if(manifest.dependencies.acquire != null) {
+        var missing_acquire_deps = manifest.dependencies.manage.where(d => !d.is_satisfied());
+        if(missing_acquire_deps.any()) {
+            foreach (var item in missing_acquire_deps) {
+                printerr(@"Missing acquire dependency \"$item\".\n");
+            }
+            printerr("Could not build manifest, missing dependencies\n");
+            return 247;
+        }
+
+    }
+
+    try {
+        var proc = manifest.run_acquire(SubprocessFlags.INHERIT_FDS);
+        proc.wait_check();
+    }
+    catch(Error e) {
+        printerr(@"Error running build exec: $(e.message)\n");
+        return 251;
+    }
+
+    return 0;
+}

+ 5 - 3
src/lib/Dependencies.vala

@@ -5,12 +5,14 @@ namespace Usm {
         public Set<ResourceRef> runtime { get; set; }
         public Set<ResourceRef> build { get; set; }
         public Set<ResourceRef> manage { get; set; }
+        public Set<ResourceRef>? acquire { get; set; }
 
         public static PropertyMapper<Dependencies> get_mapper() {
             return new PropertyMapperBuilder<Dependencies>()
-                .map_many<string>("runtime", o => o.runtime.select<string>(i => i.to_string()), (o, v) => o.runtime = v.select<ResourceRef>(i => new ResourceRef(i)).to_set())
-                .map_many<string>("build", o => o.build.select<string>(i => i.to_string()), (o, v) => o.build = v.select<ResourceRef>(i => new ResourceRef(i)).to_set())
-                .map_many<string>("manage", o => o.manage.select<string>(i => i.to_string()), (o, v) => o.manage = v.select<ResourceRef>(i => new ResourceRef(i)).to_set())
+                .map_many<string>("runtime", o => o.runtime.select<string>(i => i.to_string()), (o, v) => o.runtime = v.convert<ResourceRef>(i => new ResourceRef(i)).to_set())
+                .map_many<string>("build", o => o.build.select<string>(i => i.to_string()), (o, v) => o.build = v.convert<ResourceRef>(i => new ResourceRef(i)).to_set())
+                .map_many<string>("manage", o => o.manage.select<string>(i => i.to_string()), (o, v) => o.manage = v.convert<ResourceRef>(i => new ResourceRef(i)).to_set())
+                .map_many<string>("acquire", o => o.manage.select<string>(i => i.to_string()), (o, v) => o.manage = v.convert<ResourceRef>(i => new ResourceRef(i)).to_set(), false)
                 .set_constructor(() => new Dependencies())
                 .build();
         }

+ 6 - 4
src/lib/Exectuables.vala

@@ -3,16 +3,18 @@ namespace Usm {
 
     public class Executables {
         public string build { get; set; }
-        public string install { get; set; }
-        public string remove { get; set; }
+        public string? install { get; set; }
+        public string? remove { get; set; }
         public string? rebuild { get; set; }
+        public string? acquire { get; set; }
 
         public static PropertyMapper<Executables> get_mapper() {
             return new PropertyMapperBuilder<Executables>()
                 .map<string>("build", o => o.build, (o, v) => o.build = v)
-                .map<string?>("install", o => o.install, (o, v) => o.remove = v)
-                .map<string?>("remove", o => o.remove, (o, v) => o.remove = v)
                 .map<string?>("rebuild", o => o.rebuild, (o, v) => o.rebuild = v, false)
+                .map<string?>("acquire", o => o.acquire, (o, v) => o.acquire = v, false)
+                .map<string?>("install", o => o.install, (o, v) => o.remove = v, false)
+                .map<string?>("remove", o => o.remove, (o, v) => o.remove = v, false)
                 .set_constructor(() => new Executables())
                 .build();
         }

+ 63 - 0
src/lib/File.vala

@@ -0,0 +1,63 @@
+using Invercargill;
+
+namespace Usm {
+
+    public class ManifestFile {
+
+        public string path { get; set; }
+        public ManifestFileType file_type { get; set; }
+        public string? destination { get; set; }
+        public Vector<RemoveType>? keep_on { get; set; }
+        public Vector<InstallType>? skip_for { get; set; }
+
+        public static PropertyMapper<ManifestFile> get_mapper() {
+            return new PropertyMapperBuilder<ManifestFile>()
+                .map<string>("path", o => o.path, (o, v) => o.path = v)
+                .map<string>("type", o => o.file_type.to_string(), (o, v) => o.file_type = ManifestFileType.from_string(v))
+                .map<string>("dest", o => o.destination, (o, v) => o.destination = v, false)
+                .map_many<string>("keepOn", o => o.keep_on.select<string>(i => i.to_string()), (o, v) => o.keep_on = v.convert<RemoveType>(i => RemoveType.from_string(i)).to_vector(), false)
+                .map_many<string>("skipFor", o => o.skip_for.select<string>(i => i.to_string()), (o, v) => o.skip_for = v.convert<InstallType>(i => InstallType.from_string(i)).to_vector(), false)
+                .set_constructor(() => new ManifestFile())
+                .build();
+        }
+
+        public ManifestFile.from_string(string str) {
+            path = str;
+            file_type = ManifestFileType.REGULAR;
+        }
+        
+    }
+
+    public enum ManifestFileType {
+        REGULAR,
+        DIRECTORY,
+        SYMBOLIC_LINK;
+
+        public string to_string() {
+            switch(this) {
+                case ManifestFileType.REGULAR:
+                    return "reg";
+                case ManifestFileType.DIRECTORY:
+                    return "dir";
+                case ManifestFileType.SYMBOLIC_LINK:
+                    return "lnk";
+                default:
+                    assert_not_reached();
+            }
+        }
+
+        public static ManifestFileType from_string(string str) throws ManifestError {
+            switch(str) {
+                case "reg":
+                    return ManifestFileType.REGULAR;
+                case "dir":
+                    return ManifestFileType.DIRECTORY;
+                case "lnk":
+                    return ManifestFileType.SYMBOLIC_LINK;
+                default:
+                    throw new ManifestError.INVALID_FILE_TYPE(@"Unknown file type \"$str\".");
+            }
+        }
+    }
+
+}

+ 51 - 5
src/lib/Manifest.vala

@@ -7,6 +7,9 @@ namespace Usm {
         INVALID_VERSION,
         INVALID_LICENCE_CATEGORY,
         INVALID_RESOURCE_TYPE,
+        INVALID_FILE_TYPE,
+        INVALID_REMOVE_TYPE,
+        INVALID_INSTALL_TYPE,
     }
 
     public class Manifest {
@@ -14,7 +17,7 @@ namespace Usm {
         public string summary { get; set; }
         public Version version { get; set; }
         public Vector<Licence> licences { get; set; }
-        public Dictionary<ResourceRef, string> provides { get; set; }
+        public Dictionary<ResourceRef, ManifestFile> provides { get; set; }
         public Dependencies dependencies { get; set; }
         public Executables executables { get; set; }
 
@@ -40,23 +43,31 @@ namespace Usm {
                 .map_many<string>("screenshots", o => o.screenshot_paths, (o, v) => o.screenshot_paths = v.to_vector(), false)
                 .map<string>("icon", o => o.icon_path, (o, v) => o.icon_path = v, false)
                 .map<string>("metainfo", o => o.metainfo_path, (o, v) => o.metainfo_path = v, false)
+                .map_with<Git>("git", o => o.git, (o, v) => o.git = v, Git.get_mapper(), false)
                 .map<Properties>("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 ManifestError, ElementError {
-            provides = new Dictionary<ResourceRef, string>();
+        private void build_provides_dict(Properties obj) throws Error {
+            provides = new Dictionary<ResourceRef, ManifestFile>();
+            var mapper = ManifestFile.get_mapper();
             foreach (var pair in obj) {
-                provides[new ResourceRef(pair.key)] = pair.value.as<string>();
+                if(pair.value.assignable_to<string>()) {
+                    provides[new ResourceRef(pair.key)] = new ManifestFile.from_string(pair.value.as<string>());
+                }
+                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<string>(pair.key.to_string(), pair.value);
+                    dict.set_native<Properties>(pair.key.to_string(), mapper.map_from(pair.value));
                 }
                 catch(Error e) {
                     assert_not_reached();
@@ -82,6 +93,15 @@ namespace Usm {
             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;
@@ -122,6 +142,19 @@ namespace Usm {
                     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 {
@@ -141,5 +174,18 @@ namespace Usm {
                     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\".");
+            }
+        }
     }
 }

+ 30 - 13
src/lib/Paths.vala

@@ -2,7 +2,9 @@ namespace Usm {
 
     public class Paths {
 
+        public string destination { get; set; }
         public string prefix { get; set; }
+
         public string bin { get; set; }
         public string include { get; set; }
         public string data { get; set; }
@@ -17,6 +19,7 @@ namespace Usm {
         public string sys_config { get; set; }
 
         public void set_envs() {
+            Environment.set_variable("DESTDIR", destination, true);
             Environment.set_variable("PREFIX", prefix, true);
             Environment.set_variable("BINDIR", bin, true);
             Environment.set_variable("INCLUDEDIR", include, true);
@@ -34,38 +37,51 @@ namespace Usm {
 
         public string get_suggested_path(ResourceRef resource) {
             switch (resource.resource_type) {
+                case ResourceType.ROOT_PATH:
+                    return Path.build_filename(destination, resource.resource);
+                case ResourceType.PATH:
+                    return Path.build_filename(destination, prefix, resource.resource);
+                case ResourceType.OPTIONAL:
+                    return Path.build_filename(destination, "opt", resource.resource);
                 case Usm.ResourceType.RESOURCE:
-                    return resource.resource;
+                    return Path.build_filename(destination, prefix, "share", resource.resource);
+                case ResourceType.CONFIGURATION:
+                    return Path.build_filename(destination, "etc", resource.resource);
                 case Usm.ResourceType.BINARY:
-                    return Path.build_filename(prefix, bin, resource.resource);
+                    return Path.build_filename(destination, prefix, bin, resource.resource);
                 case Usm.ResourceType.SUPER_BINARY:
-                    return Path.build_filename(prefix, sbin, resource.resource);
+                    return Path.build_filename(destination, prefix, sbin, resource.resource);
                 case Usm.ResourceType.LIBRARY:
-                    return Path.build_filename(prefix, lib, resource.resource);
+                    return Path.build_filename(destination, prefix, lib, resource.resource);
                 case Usm.ResourceType.LIBRARY_EXECUTABLE:
-                    return Path.build_filename(prefix, libexec, resource.resource);
+                    return Path.build_filename(destination, prefix, libexec, resource.resource);
                 case Usm.ResourceType.LIBRARY_RESOURCE:
-                    return Path.build_filename(prefix, lib, resource.resource);
+                    return Path.build_filename(destination, prefix, lib, resource.resource);
                 case Usm.ResourceType.INFO_PAGE:
-                    return Path.build_filename(prefix, info, resource.resource);
+                    return Path.build_filename(destination, prefix, info, resource.resource);
                 case Usm.ResourceType.MANUAL_PAGE:
-                    return Path.build_filename(prefix, man, resource.resource);
+                    return Path.build_filename(destination, prefix, man, resource.resource);
                 case Usm.ResourceType.LOCALE:
-                    return Path.build_filename(prefix, locale, resource.resource);
+                    return Path.build_filename(destination, prefix, locale, resource.resource);
                 case Usm.ResourceType.APPLICATION:
-                    return Path.build_filename(prefix, "share", "applications", resource.resource);
+                    return Path.build_filename(destination, prefix, "share", "applications", resource.resource);
                 case Usm.ResourceType.INCLUDE:
-                    return Path.build_filename(prefix, include, resource.resource);
+                    return Path.build_filename(destination, prefix, include, resource.resource);
                 case Usm.ResourceType.PKG_CONFIG:
-                    return Path.build_filename(prefix, lib, "pkgconfig", resource.resource);
+                    return Path.build_filename(destination, prefix, lib, "pkgconfig", resource.resource);
                 case Usm.ResourceType.VALA_API:
-                    return Path.build_filename(prefix, "share", "vala", "vapi", resource.resource);
+                    return Path.build_filename(destination, prefix, "share", "vala", "vapi", resource.resource);
+                case Usm.ResourceType.GOBJECT_IR:
+                    return Path.build_filename(destination, prefix, "share", "gir", resource.resource);
+                case Usm.ResourceType.TYPELIB:
+                    return Path.build_filename(destination, prefix, lib, "girepository-1.0", resource.resource);
                 default:
                     assert_not_reached();
             }
         }
 
         public Paths.defaults() {
+            destination = "/";
             prefix = "/usr";
             bin = "bin";
             include = "include";
@@ -84,6 +100,7 @@ namespace Usm {
         public Paths.usm_environ() {
             var defaults = new Paths.defaults();
             
+            destination = Environment.get_variable("USM_DESTDIR") ?? defaults.destination;
             prefix = Environment.get_variable("USM_PREFIX") ?? defaults.prefix;
             bin = Environment.get_variable("USM_BINDIR") ?? defaults.bin;
             include = Environment.get_variable("USM_INCLUDEDIR") ?? defaults.include;

+ 80 - 2
src/lib/ResourceRef.vala

@@ -3,7 +3,11 @@ using Invercargill.Convert;
 namespace Usm {
 
     public enum ResourceType {
+        ROOT_PATH,
+        PATH,
+        OPTIONAL,
         RESOURCE,
+        CONFIGURATION,
         BINARY,
         SUPER_BINARY,
         LIBRARY,
@@ -15,12 +19,22 @@ namespace Usm {
         APPLICATION,
         INCLUDE,
         PKG_CONFIG,
-        VALA_API;
+        VALA_API,
+        GOBJECT_IR,
+        TYPELIB;
 
         public string to_string() {
             switch (this) {
+                case ResourceType.ROOT_PATH:
+                    return "rootpath";
+                case ResourceType.PATH:
+                    return "path";
+                case ResourceType.OPTIONAL:
+                    return "opt";
                 case ResourceType.RESOURCE:
                     return "res";
+                case ResourceType.CONFIGURATION:
+                    return "cfg";
                 case ResourceType.BINARY:
                     return "bin";
                 case ResourceType.SUPER_BINARY:
@@ -45,6 +59,10 @@ namespace Usm {
                     return "pc";
                 case ResourceType.VALA_API:
                     return "vapi";
+                case ResourceType.GOBJECT_IR:
+                    return "gir";
+                case ResourceType.TYPELIB:
+                    return "typelib";
                 default:
                     assert_not_reached();
             }
@@ -52,8 +70,16 @@ namespace Usm {
 
         public static ResourceType from_string(string str) throws ManifestError {
             switch (str) {
+                case "rootpath":
+                    return ResourceType.ROOT_PATH;
+                case "path":
+                    return ResourceType.PATH;
+                case "opt":
+                    return ResourceType.OPTIONAL;
                 case "res":
                     return ResourceType.RESOURCE;
+                case "cfg":
+                    return ResourceType.CONFIGURATION;
                 case "bin":
                     return ResourceType.BINARY;
                 case "sbin":
@@ -78,6 +104,10 @@ namespace Usm {
                     return ResourceType.PKG_CONFIG;
                 case "vapi":
                     return ResourceType.VALA_API;
+                case "gir":
+                    return ResourceType.GOBJECT_IR;
+                case "typelib":
+                    return ResourceType.TYPELIB;
                 default:
                     throw new ManifestError.INVALID_RESOURCE_TYPE(@"Unknown resource type \"$str\".");
             }
@@ -106,8 +136,16 @@ namespace Usm {
         
         public bool is_satisfied() {
             switch (resource_type) {
+                case ResourceType.ROOT_PATH:
+                    return check_rootpath();
+                case ResourceType.PATH:
+                    return check_path();
+                case ResourceType.OPTIONAL:
+                    return check_opt();
                 case ResourceType.RESOURCE:
                     return check_res();
+                case ResourceType.CONFIGURATION:
+                    return check_cfg();
                 case ResourceType.BINARY:
                     return check_bin();
                 case ResourceType.SUPER_BINARY:
@@ -132,6 +170,10 @@ namespace Usm {
                     return check_pc();
                 case ResourceType.VALA_API:
                     return check_vapi();
+                case ResourceType.GOBJECT_IR:
+                    return check_gir();
+                case ResourceType.TYPELIB:
+                    return check_typelib();
                 default:
                     assert_not_reached();
             }
@@ -169,11 +211,31 @@ namespace Usm {
             return false;
         }
 
-        private bool check_res() {
+        private bool check_path() {
+            var file = File.new_build_filename("/usr", resource);
+            return file.query_exists();
+        }
+
+        private bool check_rootpath() {
             var file = File.new_build_filename("/", resource);
             return file.query_exists();
         }
 
+        private bool check_res() {
+            var file = File.new_build_filename("/usr/share", resource);
+            return file.query_exists();
+        }
+
+        private bool check_opt() {
+            var file = File.new_build_filename("/opt", resource);
+            return file.query_exists();
+        }
+
+        private bool check_cfg() {
+            var file = File.new_build_filename("/etc", resource);
+            return file.query_exists();
+        }
+
         private bool check_libres() {
             var paths = new string[] { "/usr/lib", "/usr/lib64", "/lib", "/lib64" };
             foreach (var path in paths) {
@@ -252,6 +314,22 @@ namespace Usm {
             }
             return false;
         }
+
+        private bool check_gir() {
+            var file = File.new_build_filename("/usr/share/gir", resource);
+            return file.query_exists();
+        }
+
+        private bool check_typelib() {
+            var paths = new string[] { "/usr/lib64/girepository-1.0", "/usr/lib/girepository-1.0", "/lib64/girepository-1.0", "/lib/girepository-1.0"  };
+            foreach (var path in paths) {
+                var file = File.new_build_filename(path, resource);
+                if(file.query_exists()) {
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 
 }

+ 1 - 0
src/lib/meson.build

@@ -4,6 +4,7 @@ add_project_arguments(['--debug', '--disable-warnings', '--enable-checking','--v
 sources = files('Manifest.vala')
 sources += files('Dependencies.vala')
 sources += files('Exectuables.vala')
+sources += files('File.vala')
 sources += files('Git.vala')
 sources += files('Licence.vala')
 sources += files('Paths.vala')