Selaa lähdekoodia

Add ability to read manifest from USMC packages. Add usm info command

Billy Barrow 7 kuukautta sitten
vanhempi
sitoutus
66f405e522
4 muutettua tiedostoa jossa 93 lisäystä ja 1 poistoa
  1. 3 1
      README.md
  2. 52 0
      src/cli/Cli.vala
  3. 37 0
      src/lib/Manifest.vala
  4. 1 0
      src/lib/meson.build

+ 3 - 1
README.md

@@ -77,7 +77,9 @@
 {
   "name": "my-repo",
   "summary": "My software repository",
-  "url": "https://my.software/repository",
+  "uris": [
+    "https://my.software/repository",
+  ],
   "key": "EDXLsUvOZEne+xcv+huvSaqNBs8TTldCv6hd69GdmYw="
 }
 ```

+ 52 - 0
src/cli/Cli.vala

@@ -16,6 +16,9 @@ public static int main(string[] args) {
         m_args.remove(1);
         return manifest_main(m_args.to_array());
     }
+    if(command == "info") {
+        return info(args);
+    }
 
 
     usage();
@@ -25,3 +28,52 @@ public static int main(string[] args) {
 private void usage() {
     printerr("USAGE:\n\tusm manifest\n");
 }
+
+
+private int info(string[] args) throws Error {
+
+    if(args.length != 3) {
+        printerr("USAGE:\n\tusm info <path>\n");
+        return 255;
+    }
+
+    var path = args[2];
+
+    var file = File.new_build_filename(path);
+    if(!File.new_build_filename(path).query_exists()) {
+        print("The specified path does not exist\n");
+        return 200;
+    }
+
+    var type = "Unknown";
+    var file_info = file.query_info("*", FileQueryInfoFlags.NONE);
+    Usm.Manifest manifest = null;
+    if(file_info.get_file_type() == FileType.DIRECTORY) {
+        type = "Directory Structure";
+
+        var manifest_path = Path.build_filename(path, "MANIFEST.usm");
+        if(!File.new_build_filename(manifest_path).query_exists()) {
+            print("The directory contains no USM manifest file.\n");
+            return 201;
+        }
+
+        manifest = new Usm.Manifest.from_file(manifest_path);
+    }
+    else {
+        type = "USMC Package";
+        manifest = new Usm.Manifest.from_package(path);
+    }
+
+    print(@"                Info for: \"$path\"\n");
+    print(@"                    Type: $type\n");
+    print(@"                    Name: $(manifest.name)\n");
+    print(@"                 Summary: $(manifest.summary)\n");
+    print(@"                 Version: $(manifest.version)\n");
+    print(@"Overall Licence Category: $(manifest.licences.min(l => l.category).category)\n");
+    
+    foreach (var licence in manifest.licences.with_positions()) {
+        print(@"               Licence $(licence.position): $(licence.item.name) ($(licence.item.category))\n");
+    }
+
+    return 0;
+}

+ 37 - 0
src/lib/Manifest.vala

@@ -10,6 +10,7 @@ namespace Usm {
         INVALID_FILE_TYPE,
         INVALID_REMOVE_TYPE,
         INVALID_INSTALL_TYPE,
+        INVALID_PACKAGE
     }
 
     public class Manifest {
@@ -49,6 +50,42 @@ namespace Usm {
             });
         }
 
+        public Manifest.from_file(string path) throws Error {
+            var element = new InvercargillJson.JsonElement.from_file(path);
+            Manifest.get_mapper().map_into(this, element.as<Invercargill.Properties>());
+        }
+
+        public Manifest.from_package(string path) throws Error {
+            var archive = new Archive.Read();
+            archive.support_format_tar();
+            archive.support_filter_xz();
+            var result = archive.open_filename(path, 10240);
+            if(result != Archive.Result.OK) {
+                throw new ManifestError.INVALID_PACKAGE("Could not read archive");
+            }
+
+            unowned Archive.Entry entry;
+            while(archive.next_header(out entry) == Archive.Result.OK) {
+                var path_name = entry.pathname();
+                if(path_name != "./MANIFEST.usm") {
+                    continue;
+                }
+
+                var manifest_blob = new BinaryData();
+				uint8[] buffer;
+				Posix.off_t offset;
+				while (archive.read_data_block (out buffer, out offset) == Archive.Result.OK) {
+					manifest_blob.append_byte_array(buffer[offset:]);
+				}
+
+                var element = new InvercargillJson.JsonElement.from_string(manifest_blob.to_raw_string());
+                Manifest.get_mapper().map_into(this, element.as<Invercargill.Properties>());
+                return;
+            }
+
+            throw new ManifestError.INVALID_PACKAGE("MANIFEST.usm not found within archive");
+        }
+
         private void build_provides_dict(Properties obj) throws Error {
             provides = new Dictionary<ResourceRef, ManifestFile>();
             var mapper = ManifestFile.get_mapper();

+ 1 - 0
src/lib/meson.build

@@ -22,6 +22,7 @@ dependencies = [
     dependency('json-glib-1.0'),
     dependency('invercargill'),
     dependency('invercargill-json'),
+    dependency('libarchive')
 ]
 
 usm = shared_library('usm', sources,