Prechádzať zdrojové kódy

refactor(paths): split path resolution into base path and resource methods

clanker 1 mesiac pred
rodič
commit
d40f2e32aa
3 zmenil súbory, kde vykonal 87 pridanie a 140 odobranie
  1. 53 113
      src/cli/Manifest.vala
  2. 5 5
      src/lib/Manifest.vala
  3. 29 22
      src/lib/Paths.vala

+ 53 - 113
src/cli/Manifest.vala

@@ -261,7 +261,7 @@ private int uininstall() {
 
     // Do files and symlinks first
     foreach (var resource in manifest.provides.where(r => r.value.file_type != Usm.ManifestFileType.DIRECTORY)) {
-        var path = paths.get_suggested_path(resource.key);
+        var path = paths.get_suggested_path_for_resource(resource.key);
         printerr(@"Deleting resource $(resource.key) from $path...");
         try {
             var file = File.new_for_path(path);
@@ -281,7 +281,7 @@ private int uininstall() {
 
     // Do directories last
     foreach (var resource in manifest.provides.where(r => r.value.file_type == Usm.ManifestFileType.DIRECTORY)) {
-        var path = paths.get_suggested_path(resource.key);
+        var path = paths.get_suggested_path_for_resource(resource.key);
         printerr(@"Deleting resource $(resource.key) from $path...");
         try {
             var file = File.new_for_path(path);
@@ -437,6 +437,10 @@ public static Invercargill.DataStructures.Vector<string> autoprovides_scan_tree(
             var true_path = file.get_path().substring(install_root.length);
             var type = get_local_resource_type(true_path);
             var relative_path = get_relative_path_for_type(true_path, type);
+            // Remove leading slash from relative_path if present
+            if (relative_path.has_prefix("/")) {
+                relative_path = relative_path.substring(1);
+            }
             provides.add(@"$type:$relative_path");
 
         }
@@ -454,80 +458,52 @@ private static string get_local_resource_type(string path) {
     // Remove leading slash if present
     string clean_path = path.has_prefix("/") ? path.substring(1) : path;
     
-    // Define all resource types with their path patterns
-    var resource_patterns = new Invercargill.DataStructures.Dictionary<string, Invercargill.DataStructures.Vector<string>>();
-    
-    // Helper function to create a Vector from a string array
-    Invercargill.DataStructures.Vector<string> create_vector(string[] patterns) {
-        var vector = new Invercargill.DataStructures.Vector<string>();
-        foreach (var pattern in patterns) {
-            vector.add(pattern);
-        }
-        return vector;
-    }
-    
-    // Binary executables
-    resource_patterns.set("bin", create_vector(new string[] {"usr/bin/"}));
-    resource_patterns.set("sbin", create_vector(new string[] {"usr/sbin/"}));
-    
-    // Libraries
-    resource_patterns.set("lib", create_vector(new string[] {"usr/lib/", "usr/lib64/", "lib/", "lib64/"}));
-    resource_patterns.set("libexec", create_vector(new string[] {"usr/libexec/"}));
-    
-    // Headers
-    resource_patterns.set("inc", create_vector(new string[] {"usr/include/"}));
-    
-    // Share resources
-    resource_patterns.set("app", create_vector(new string[] {"usr/share/applications/"}));
-    resource_patterns.set("info", create_vector(new string[] {"usr/share/info/"}));
-    resource_patterns.set("man", create_vector(new string[] {"usr/share/man/"}));
-    resource_patterns.set("locale", create_vector(new string[] {"usr/share/locale/"}));
-    resource_patterns.set("vapi", create_vector(new string[] {"usr/share/vala/vapi/", "usr/share/vala-0.56/vapi/"}));
-    resource_patterns.set("gir", create_vector(new string[] {"usr/share/gir-1.0/"}));
-    resource_patterns.set("tag", create_vector(new string[] {"usr/share/usm-tags/"}));
-    resource_patterns.set("res", create_vector(new string[] {"usr/share/"}));
-    
-    // Package config and typelib (more specific types)
-    resource_patterns.set("pc", create_vector(new string[] {"usr/lib/pkgconfig/", "usr/lib64/pkgconfig/", "usr/share/pkgconfig/"}));
-    resource_patterns.set("typelib", create_vector(new string[] {"usr/lib64/girepository-1.0/", "usr/lib/girepository-1.0/", "lib64/girepository-1.0/", "lib/girepository-1.0/"}));
-    
-    // Configuration and optional
-    resource_patterns.set("cfg", create_vector(new string[] {"etc/"}));
-    resource_patterns.set("opt", create_vector(new string[] {"opt/"}));
+    // Create a temporary Paths object to get the default paths
+    var default_paths = new Usm.Paths.defaults();
     
     // Find all matching resource types and calculate directory traversals
     var matching_types = new Invercargill.DataStructures.Vector<string>();
     var traversal_counts = new Invercargill.DataStructures.Vector<int>();
     
     // Define all resource types to check
-    string[] types_to_check = {
-        "bin", "sbin", "lib", "libexec", "inc", "app", "info", "man",
-        "locale", "vapi", "gir", "tag", "res", "pc", "typelib", "cfg", "opt"
+    Usm.ResourceType[] types_to_check = {
+        Usm.ResourceType.BINARY,
+        Usm.ResourceType.SUPER_BINARY,
+        Usm.ResourceType.LIBRARY,
+        Usm.ResourceType.LIBRARY_EXECUTABLE,
+        Usm.ResourceType.INCLUDE,
+        Usm.ResourceType.APPLICATION,
+        Usm.ResourceType.INFO_PAGE,
+        Usm.ResourceType.MANUAL_PAGE,
+        Usm.ResourceType.LOCALE,
+        Usm.ResourceType.VALA_API,
+        Usm.ResourceType.GOBJECT_IR,
+        Usm.ResourceType.TAG,
+        Usm.ResourceType.RESOURCE,
+        Usm.ResourceType.PKG_CONFIG,
+        Usm.ResourceType.TYPELIB,
+        Usm.ResourceType.CONFIGURATION,
+        Usm.ResourceType.OPTIONAL
     };
     
     foreach (var type in types_to_check) {
-        try {
-            var patterns = resource_patterns.get(type);
-            
-            for (int i = 0; i < patterns.peek_count(); i++) {
-                var pattern = patterns[i];
-                if (clean_path.has_prefix(pattern)) {
-                    var relative_path = clean_path.substring(pattern.length);
-                    // Count slashes (directory traversals) in the relative path
-                    int traversal_count = 0;
-                    for (int j = 0; j < relative_path.length; j++) {
-                        if (relative_path[j] == '/') {
-                            traversal_count++;
-                        }
-                    }
-                    
-                    matching_types.add(type);
-                    traversal_counts.add(traversal_count);
-                    break; // Found a matching pattern for this type, move to next type
+        var suggested_path = default_paths.get_suggested_base_path_for_type(type);
+        // Remove the destination prefix (usually "/") to get the relative path
+        var relative_suggested_path = suggested_path.has_prefix("/") ?
+            suggested_path.substring(1) : suggested_path;
+        
+        if (clean_path.has_prefix(relative_suggested_path)) {
+            var relative_path = clean_path.substring(relative_suggested_path.length);
+            // Count slashes (directory traversals) in the relative path
+            int traversal_count = 0;
+            for (int j = 0; j < relative_path.length; j++) {
+                if (relative_path[j] == '/') {
+                    traversal_count++;
                 }
             }
-        } catch (Error e) {
-            // Type not found, continue to next type
+            
+            matching_types.add(type.to_string());
+            traversal_counts.add(traversal_count);
         }
     }
     
@@ -554,58 +530,22 @@ private static string get_relative_path_for_type(string path, string type) {
     // Remove leading slash if present
     string clean_path = path.has_prefix("/") ? path.substring(1) : path;
     
-    // Helper function to create a Vector from a string array
-    Invercargill.DataStructures.Vector<string> create_vector(string[] patterns) {
-        var vector = new Invercargill.DataStructures.Vector<string>();
-        foreach (var pattern in patterns) {
-            vector.add(pattern);
-        }
-        return vector;
-    }
-    
-    // Define all resource types with their path patterns (same as in get_local_resource_type)
-    var resource_patterns = new Invercargill.DataStructures.Dictionary<string, Invercargill.DataStructures.Vector<string>>();
-    
-    // Binary executables
-    resource_patterns.set("bin", create_vector(new string[] {"usr/bin/"}));
-    resource_patterns.set("sbin", create_vector(new string[] {"usr/sbin/"}));
-    
-    // Libraries
-    resource_patterns.set("lib", create_vector(new string[] {"usr/lib/", "usr/lib64/", "lib/", "lib64/"}));
-    resource_patterns.set("libexec", create_vector(new string[] {"usr/libexec/"}));
+    // Create a temporary Paths object to get the default paths
+    var default_paths = new Usm.Paths.defaults();
     
-    // Headers
-    resource_patterns.set("inc", create_vector(new string[] {"usr/include/"}));
-    
-    // Share resources
-    resource_patterns.set("app", create_vector(new string[] {"usr/share/applications/"}));
-    resource_patterns.set("info", create_vector(new string[] {"usr/share/info/"}));
-    resource_patterns.set("man", create_vector(new string[] {"usr/share/man/"}));
-    resource_patterns.set("locale", create_vector(new string[] {"usr/share/locale/"}));
-    resource_patterns.set("vapi", create_vector(new string[] {"usr/share/vala/vapi/", "usr/share/vala-0.56/vapi/"}));
-    resource_patterns.set("gir", create_vector(new string[] {"usr/share/gir-1.0/"}));
-    resource_patterns.set("tag", create_vector(new string[] {"usr/share/usm-tags/"}));
-    resource_patterns.set("res", create_vector(new string[] {"usr/share/"}));
-    
-    // Package config and typelib (more specific types)
-    resource_patterns.set("pc", create_vector(new string[] {"usr/lib/pkgconfig/", "usr/lib64/pkgconfig/", "usr/share/pkgconfig/"}));
-    resource_patterns.set("typelib", create_vector(new string[] {"usr/lib64/girepository-1.0/", "usr/lib/girepository-1.0/", "lib64/girepository-1.0/", "lib/girepository-1.0/"}));
-    
-    // Configuration and optional
-    resource_patterns.set("cfg", create_vector(new string[] {"etc/"}));
-    resource_patterns.set("opt", create_vector(new string[] {"opt/"}));
-    
-    // Find the matching pattern for the given type and extract relative path
     try {
-        var patterns = resource_patterns.get(type);
-        for (int i = 0; i < patterns.peek_count(); i++) {
-            var pattern = patterns[i];
-            if (clean_path.has_prefix(pattern)) {
-                return clean_path.substring(pattern.length);
-            }
+        // Convert string type to ResourceType enum
+        var resource_type = Usm.ResourceType.from_string(type);
+        var suggested_path = default_paths.get_suggested_base_path_for_type(resource_type);
+        // Remove the destination prefix (usually "/") to get the relative path
+        var relative_suggested_path = suggested_path.has_prefix("/") ?
+            suggested_path.substring(1) : suggested_path;
+        
+        if (clean_path.has_prefix(relative_suggested_path)) {
+            return clean_path.substring(relative_suggested_path.length);
         }
     } catch (Error e) {
-        // Type not found in dictionary, fall through to default case
+        // Type not found, fall through to default case
     }
     
     // Default case - return the path as-is

+ 5 - 5
src/lib/Manifest.vala

@@ -271,10 +271,10 @@ namespace Usm {
             var resources_installed = 0;
 
             // Install from shortest path to longest path, to ensure directories are created before children
-            var install_order = provides.sort((a, b) => paths.get_suggested_path(a.key).length - paths.get_suggested_path(b.key).length);
+            var install_order = provides.sort((a, b) => paths.get_suggested_path_for_resource(a.key).length - paths.get_suggested_path_for_resource(b.key).length);
             foreach (var resource in install_order) {
                 callback(resource.key, resources_installed, resource_count, 0.0f);
-                var path = paths.get_suggested_path(resource.key);
+                var path = paths.get_suggested_path_for_resource(resource.key);
                 
                 if(resource.key.resource_type == ResourceType.TAG) {
                     // Ensure parent directories are created first
@@ -303,7 +303,7 @@ namespace Usm {
                             if(install_path == null) {
                                 throw new ManifestError.INVALID_FILE_PATH("Install path was not provided");
                             }
-                            base_path = Path.build_filename(install_path, paths.get_suggested_path(resource.key));
+                            base_path = Path.build_filename(install_path, paths.get_suggested_path_for_resource(resource.key));
                             break;
                         default:
                             assert_not_reached();
@@ -349,7 +349,7 @@ namespace Usm {
             // Delete files and symlinks first
             foreach (var resource in non_directories) {
                 callback(resource.key, current_operation, total_operations, 0.0f);
-                var path = paths.get_suggested_path(resource.key);
+                var path = paths.get_suggested_path_for_resource(resource.key);
                 var file = File.new_for_path(path);
                 if(file.query_exists()) {
                     file.delete();
@@ -361,7 +361,7 @@ namespace Usm {
             // Delete directories last
             foreach (var resource in directories) {
                 callback(resource.key, current_operation, total_operations, 0.0f);
-                var path = paths.get_suggested_path(resource.key);
+                var path = paths.get_suggested_path_for_resource(resource.key);
                 try {
                     var file = File.new_for_path(path);
                     if(file.query_exists()) {

+ 29 - 22
src/lib/Paths.vala

@@ -39,53 +39,60 @@ namespace Usm {
             Environment.set_variable("TAGSDIR", tags, true);
         }
 
-        public string get_suggested_path(ResourceRef resource) {
-            switch (resource.resource_type) {
+        public string get_suggested_base_path_for_type(ResourceType type) {
+            switch (type) {
                 case ResourceType.ROOT_PATH:
-                    return Path.build_filename(destination, resource.resource);
+                    return destination;
                 case ResourceType.PATH:
-                    return Path.build_filename(destination, prefix, resource.resource);
+                    return Path.build_filename(destination, prefix);
                 case ResourceType.OPTIONAL:
-                    return Path.build_filename(destination, "opt", resource.resource);
+                    return Path.build_filename(destination, "opt");
                 case Usm.ResourceType.RESOURCE:
-                    return Path.build_filename(destination, prefix, data, resource.resource);
+                    return Path.build_filename(destination, prefix, data);
                 case ResourceType.CONFIGURATION:
-                    return Path.build_filename(destination, sys_config, resource.resource);
+                    return Path.build_filename(destination, sys_config);
                 case Usm.ResourceType.BINARY:
-                    return Path.build_filename(destination, prefix, bin, resource.resource);
+                    return Path.build_filename(destination, prefix, bin);
                 case Usm.ResourceType.SUPER_BINARY:
-                    return Path.build_filename(destination, prefix, sbin, resource.resource);
+                    return Path.build_filename(destination, prefix, sbin);
                 case Usm.ResourceType.LIBRARY:
-                    return Path.build_filename(destination, prefix, lib, resource.resource);
+                    return Path.build_filename(destination, prefix, lib);
                 case Usm.ResourceType.LIBRARY_EXECUTABLE:
-                    return Path.build_filename(destination, prefix, libexec, resource.resource);
+                    return Path.build_filename(destination, prefix, libexec);
                 case Usm.ResourceType.LIBRARY_RESOURCE:
-                    return Path.build_filename(destination, prefix, lib, resource.resource);
+                    return Path.build_filename(destination, prefix, lib);
                 case Usm.ResourceType.INFO_PAGE:
-                    return Path.build_filename(destination, prefix, info, resource.resource);
+                    return Path.build_filename(destination, prefix, info);
                 case Usm.ResourceType.MANUAL_PAGE:
-                    return Path.build_filename(destination, prefix, man, resource.resource);
+                    return Path.build_filename(destination, prefix, man);
                 case Usm.ResourceType.LOCALE:
-                    return Path.build_filename(destination, prefix, locale, resource.resource);
+                    return Path.build_filename(destination, prefix, locale);
                 case Usm.ResourceType.APPLICATION:
-                    return Path.build_filename(destination, prefix, "share", "applications", resource.resource);
+                    return Path.build_filename(destination, prefix, "share", "applications");
                 case Usm.ResourceType.INCLUDE:
-                    return Path.build_filename(destination, prefix, include, resource.resource);
+                    return Path.build_filename(destination, prefix, include);
                 case Usm.ResourceType.PKG_CONFIG:
-                    return Path.build_filename(destination, prefix, lib, "pkgconfig", resource.resource);
+                    return Path.build_filename(destination, prefix, lib, "pkgconfig");
                 case Usm.ResourceType.VALA_API:
-                    return Path.build_filename(destination, prefix, "share", "vala", "vapi", resource.resource);
+                    return Path.build_filename(destination, prefix, "share", "vala", "vapi");
                 case Usm.ResourceType.GOBJECT_IR:
-                    return Path.build_filename(destination, prefix, "share", "gir-1.0", resource.resource);
+                    return Path.build_filename(destination, prefix, "share", "gir-1.0");
                 case Usm.ResourceType.TYPELIB:
-                    return Path.build_filename(destination, prefix, lib, "girepository-1.0", resource.resource);
+                    return Path.build_filename(destination, prefix, lib, "girepository-1.0");
                 case Usm.ResourceType.TAG:
-                    return get_tag_file_path(resource.resource);
+                    return Path.build_filename(destination, prefix, tags);
                 default:
                     assert_not_reached();
             }
         }
 
+        public string get_suggested_path_for_resource(ResourceRef resource) {
+            if (resource.resource_type == ResourceType.TAG) {
+                return get_tag_file_path(resource.resource);
+            }
+            return Path.build_filename(get_suggested_base_path_for_type(resource.resource_type), resource.resource);
+        }
+
 
         public string get_tag_file_path(string tag) {
             var tag_path = tag.replace(".", "/");