Просмотр исходного кода

refactor(autoprovides): use ResourceRef/ManifestFile instead of string paths

Replace simple string-based path storage with proper ResourceRef and
ManifestFile objects to better handle canonical and alternative resource
types. This change enables more sophisticated resource type management
while maintaining compatibility with existing JSON output.

The autoprovides_scan_tree function now returns a Dictionary with
ResourceRef keys and ManifestFile values instead of a Vector of strings.
Canonical resources are automatically converted to alternative types
when regular counterparts exist.
clanker 1 месяц назад
Родитель
Сommit
e2b5d531c6
1 измененных файлов с 49 добавлено и 22 удалено
  1. 49 22
      src/cli/Manifest.vala

+ 49 - 22
src/cli/Manifest.vala

@@ -471,45 +471,49 @@ private int autoprovides() {
     try {
         var provides = autoprovides_scan_tree(install_dir.get_path(), install_dir.get_path());
 
-        var json = "\"provides\": {\n";
-        foreach (var item in provides) {
-            json += @"    \"$item\": \"as-expected\",\n";
-        }
-        if(provides.any()) {
-            json = json.substring(0, json.length - 2);
+        // Create a JSON representation of the provides dictionary
+        var json_object = new InvercargillJson.JsonObject();
+        foreach (var entry in provides) {
+            // Handle special case: when pathBase is as-expected, path is empty, and type is reg
+            // output string "as-expected" instead of full JSON object
+            if(entry.value.path_base == Usm.ManifestFilePathBase.AS_EXPECTED &&
+               entry.value.path == "" &&
+               entry.value.file_type == Usm.ManifestFileType.REGULAR) {
+                json_object.set_native(entry.key.to_string(), "as-expected");
+            } else {
+                var mapper = Usm.ManifestFile.get_mapper();
+                json_object.set_native(entry.key.to_string(), mapper.map_from(entry.value));
+            }
         }
-        json += "\n}";
+        
+        var json_string = json_object.as_element().stringify(true);
 
         if(replace_provides) {
             try {
                 // Update the manifest's provides property
-                var new_provides = new Invercargill.DataStructures.Dictionary<Usm.ResourceRef, Usm.ManifestFile>();
-                foreach (var item in provides) {
-                    new_provides[new Usm.ResourceRef(item)] = new Usm.ManifestFile.from_string("as-expected");
-                }
-                manifest.provides = new_provides;
+                manifest.provides = provides;
                 
                 // Serialize the updated manifest back to JSON
                 var mapper = Usm.Manifest.get_mapper();
                 var properties = mapper.map_from(manifest);
-                var json_element = new InvercargillJson.JsonElement.from_properties(properties);
-                var json_string = json_element.stringify(true);
+                var manifest_json_element = new InvercargillJson.JsonElement.from_properties(properties);
+                var manifest_json_string = manifest_json_element.stringify(true);
                 
                 // Write the updated manifest to file
                 var file = File.new_for_path("MANIFEST.usm");
                 var data_stream = new DataOutputStream(file.replace(null, false, FileCreateFlags.REPLACE_DESTINATION));
-                data_stream.put_string(json_string);
+                data_stream.put_string(manifest_json_string);
                 
                 printerr("Successfully updated 'provides' property in MANIFEST.usm\n");
             }
             catch(Error e) {
                 printerr(@"Error updating MANIFEST.usm: $(e.message)\n");
                 printerr("Original file left unchanged. Generated provides:\n");
-                print(@"$json\n");
+                print(@"$json_string\n");
                 return 249;
             }
         } else {
-            print(@"$json\n");
+            print(@"$json_string\n");
         }
         
         return 0;
@@ -520,14 +524,14 @@ private int autoprovides() {
     }
 }
 
-public static Invercargill.DataStructures.Vector<string> autoprovides_scan_tree(string install_root, string path) throws Error {
+public static Invercargill.DataStructures.Dictionary<Usm.ResourceRef, Usm.ManifestFile> autoprovides_scan_tree(string install_root, string path) throws Error {
     // Creating a new Directory object for the given folder path
     var folder = File.new_for_path(path);
 
     // Getting a list of all files and folders inside the directory
     var enumerator = folder.enumerate_children("*", FileQueryInfoFlags.NONE);
 
-    var provides = new Invercargill.DataStructures.Vector<string>();
+    var provides = new Invercargill.DataStructures.Dictionary<Usm.ResourceRef, Usm.ManifestFile>();
 
     // Looping through each file/folder and removing them
     while (true) {
@@ -548,13 +552,36 @@ public static Invercargill.DataStructures.Vector<string> autoprovides_scan_tree(
             if (relative_path.has_prefix("/")) {
                 relative_path = relative_path.substring(1);
             }
-            provides.add(@"$type:$relative_path");
-
+            
+            // Create ResourceRef and ManifestFile
+            var resource_ref = new Usm.ResourceRef.with_type(type, relative_path);
+            var manifest_file = new Usm.ManifestFile.from_string("as-expected");
+            provides[resource_ref] = manifest_file;
         }
         else if (info.get_file_type() == FileType.DIRECTORY) {
             // Removing the folder recursively
             var subfolder = folder.get_child(info.get_name());
-            provides.add_all(autoprovides_scan_tree(install_root, subfolder.get_path()));
+            var sub_provides = autoprovides_scan_tree(install_root, subfolder.get_path());
+            // Add all entries from subdirectory
+            foreach (var entry in sub_provides) {
+                provides[entry.key] = entry.value;
+            }
+        }
+    }
+
+    // If we have any cananocal resources, check to make sure they aren't actually alternative
+    var canon_resources = provides.keys.where(p => p.resource_type == Usm.ResourceType.CANONICAL_LIBRARY || p.resource_type == Usm.ResourceType.CANONICAL_LIBRARY_RESOURCE).to_series();
+    foreach (var canon_resource in canon_resources) {
+        var canon_type = canon_resource.resource_type;
+        var regular_type = canon_type == Usm.ResourceType.CANONICAL_LIBRARY ? Usm.ResourceType.LIBRARY : Usm.ResourceType.LIBRARY_RESOURCE;
+        var alternative_type = canon_type == Usm.ResourceType.CANONICAL_LIBRARY ? Usm.ResourceType.ALTERNATIVE_FORMAT_LIBRARY : Usm.ResourceType.ALTERNATIVE_FORMAT_LIBRARY_RESOURCE;
+        Usm.ManifestFile? regular_file;
+        // Is there a regular counterpart?
+        if(provides.try_get(new Usm.ResourceRef.with_type(regular_type, canon_resource.resource), out regular_file)) {
+            // Convert from canonical resource to alternative resource
+            Usm.ManifestFile canon_file;
+            provides.remove(canon_resource, out canon_file);
+            provides[new Usm.ResourceRef.with_type(alternative_type, canon_resource.resource)] = canon_file;
         }
     }