|
@@ -12,7 +12,7 @@ public static int manifest_main(string[] args) {
|
|
|
|
|
|
var verb = args[1];
|
|
|
|
|
|
- if(verb != "remove" && verb != "acquire" && verb != "install" && verb != "package") {
|
|
|
+ if(verb != "remove" && verb != "acquire" && verb != "install" && verb != "package" && verb != "autoprovides") {
|
|
|
if(args.length < 3) {
|
|
|
manifest_usage();
|
|
|
return 255;
|
|
@@ -38,7 +38,7 @@ public static int manifest_main(string[] args) {
|
|
|
return build();
|
|
|
}
|
|
|
|
|
|
- if(verb == "install") {
|
|
|
+ if(verb == "install" || verb == "autoprovides") {
|
|
|
if(build_path == null) {
|
|
|
var dir = File.new_build_filename("/tmp", Uuid.string_random());
|
|
|
try {
|
|
@@ -50,6 +50,9 @@ public static int manifest_main(string[] args) {
|
|
|
}
|
|
|
build_path = dir.get_path();
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ if(verb == "install") {
|
|
|
return install();
|
|
|
}
|
|
|
|
|
@@ -65,6 +68,10 @@ public static int manifest_main(string[] args) {
|
|
|
return package();
|
|
|
}
|
|
|
|
|
|
+ if(verb == "autoprovides") {
|
|
|
+ return autoprovides();
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
manifest_usage();
|
|
|
return 255;
|
|
@@ -312,14 +319,135 @@ private int package() {
|
|
|
|
|
|
printerr("Writing archive...\n");
|
|
|
var output = @"../$(manifest.name)-$(manifest.version).usmc";
|
|
|
- var proc = new Subprocess.newv(new string[] { "tar", "-cJf", output, "."}, SubprocessFlags.INHERIT_FDS);
|
|
|
- var result = proc.wait_check() ? 0 : 254;
|
|
|
-
|
|
|
- if(result == 0) {
|
|
|
+ try {
|
|
|
+ var proc = new Subprocess.newv(new string[] { "tar", "-cJf", output, "."}, SubprocessFlags.INHERIT_FDS);
|
|
|
+ proc.wait_check();
|
|
|
printerr(@"Wrote package to path \"$(output)\"\n");
|
|
|
+ return 0;
|
|
|
}
|
|
|
- else {
|
|
|
+ catch(Error e) {
|
|
|
printerr("Failed to write package\n");
|
|
|
+ return 172;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+private int autoprovides() {
|
|
|
+ var missing_management_deps = manifest.dependencies.manage.where(d => !d.is_satisfied());
|
|
|
+ var missing_build_deps = manifest.dependencies.build.where(d => !d.is_satisfied());
|
|
|
+ var missing_runtime_deps = manifest.dependencies.runtime.where(d => !d.is_satisfied());
|
|
|
+
|
|
|
+ if(manifest.executables.install == null) {
|
|
|
+ printerr(@"Autoprovides command only works with manifests that specify an installation executable.\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ var sane = true;
|
|
|
+ if(missing_management_deps.any()) {
|
|
|
+ sane = false;
|
|
|
+ foreach (var item in missing_management_deps) {
|
|
|
+ printerr(@"Missing management dependency \"$item\".\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(missing_build_deps.any()) {
|
|
|
+ sane = false;
|
|
|
+ foreach (var item in missing_build_deps) {
|
|
|
+ printerr(@"Missing build dependency \"$item\".\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(missing_runtime_deps.any()) {
|
|
|
+ sane = false;
|
|
|
+ foreach (var item in missing_runtime_deps) {
|
|
|
+ printerr(@"Missing runtime dependency \"$item\".\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!sane) {
|
|
|
+ printerr("Could not install manifest, missing dependencies\n");
|
|
|
+ return 252;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ var proc = manifest.run_build(build_path, paths, SubprocessFlags.STDOUT_SILENCE);
|
|
|
+ proc.wait_check();
|
|
|
+ }
|
|
|
+ catch(Error e) {
|
|
|
+ printerr(@"Error running build exec: $(e.message)\n");
|
|
|
+ return 251;
|
|
|
+ }
|
|
|
+
|
|
|
+ var install_dir = File.new_build_filename("/tmp", Uuid.string_random());
|
|
|
+ try {
|
|
|
+ install_dir.make_directory();
|
|
|
+ }
|
|
|
+ catch(Error e) {
|
|
|
+ printerr(@"Could not create temporary install directory: $(e.message)\n");
|
|
|
+ return 250;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ manifest.run_install(build_path, install_dir.get_path(), paths, Usm.InstallType.FRESH, SubprocessFlags.STDOUT_SILENCE).wait_check();
|
|
|
+ }
|
|
|
+ catch(Error e) {
|
|
|
+ printerr(@"Error running install exec: $(e.message)\n");
|
|
|
+ return 249;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ print(@"$json\n}\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ catch(Error e) {
|
|
|
+ printerr(@"Error scanning installation result: $(e.message)\n");
|
|
|
+ return 249;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+public static Invercargill.Vector<string> 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.Vector<string>();
|
|
|
+
|
|
|
+ // Looping through each file/folder and removing them
|
|
|
+ while (true) {
|
|
|
+ FileInfo? info = enumerator.next_file();
|
|
|
+ if (info == null) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Checking if the current item is a file or a folder
|
|
|
+ if (info.get_file_type() == FileType.REGULAR) {
|
|
|
+ // Removing the file
|
|
|
+ var file = folder.get_child(info.get_name());
|
|
|
+ var true_path = file.get_path().substring(install_root.length);
|
|
|
+ var type = paths.get_suggested_resource_type(true_path);
|
|
|
+ if(type == Usm.ResourceType.ROOT_PATH) {
|
|
|
+ provides.add("rootpath:" + true_path);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ provides.add(@"$type:$(file.get_basename())");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ 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()));
|
|
|
+ }
|
|
|
}
|
|
|
- return result;
|
|
|
+
|
|
|
+ return provides;
|
|
|
}
|