Explorar el Código

feat(cli): add scaffold command to CLI

clanker hace 1 mes
padre
commit
a3a349aa1f
Se han modificado 3 ficheros con 285 adiciones y 1 borrados
  1. 4 1
      src/cli/Cli.vala
  2. 280 0
      src/cli/Scaffold.vala
  3. 1 0
      src/cli/meson.build

+ 4 - 1
src/cli/Cli.vala

@@ -25,6 +25,9 @@ public static int main(string[] args) {
     if(command == "install") {
         return install_main(args);
     }
+    if(command == "scaffold") {
+        return scaffold_main(args);
+    }
 
 
     usage();
@@ -32,7 +35,7 @@ public static int main(string[] args) {
 }
 
 private void usage() {
-    printerr("USAGE:\n\tusm manifest\n\tusm info\n\tusm repository\n\tusm install\n");
+    printerr("USAGE:\n\tusm manifest\n\tusm info\n\tusm repository\n\tusm install\n\tusm scaffold\n");
 }
 
 

+ 280 - 0
src/cli/Scaffold.vala

@@ -0,0 +1,280 @@
+using Invercargill;
+using Invercargill.DataStructures;
+
+private int scaffold_main(string[] args) {
+    if(args.length < 4) {
+        return scaffold_usage();
+    }
+
+    var name = args[2];
+    var template = args[3];
+    
+    // Parse attributes
+    var attributes = new HashSet<string>();
+    for(int i = 4; i < args.length; i++) {
+        attributes.add(args[i]);
+    }
+
+    try {
+        // Create the manifest based on template and attributes
+        var manifest = create_manifest(name, template, attributes);
+        
+        // Write MANIFEST.usm file
+        write_manifest_file(manifest);
+        
+        // Create scripts directory and scripts based on template
+        create_scripts(template, attributes);
+        
+        print(@"Successfully scaffolded project '$name' with template '$template'\n");
+        return 0;
+    }
+    catch(Error e) {
+        printerr(@"Error: $(e.message)\n");
+        return 1;
+    }
+}
+
+private int scaffold_usage() {
+    printerr("USAGE:\n\tusm scaffold <name> <template> [attributes...]\n");
+    printerr("\nTemplates:\n");
+    printerr("\tbasic    - Creates only MANIFEST.usm\n");
+    printerr("\tmakefile - Creates MANIFEST.usm with make build scripts\n");
+    printerr("\tmeson    - Creates MANIFEST.usm with meson build scripts\n");
+    printerr("\nAttributes:\n");
+    printerr("\tvala     - Add Vala language dependencies\n");
+    printerr("\tc        - Add C language dependencies\n");
+    printerr("\tacquire  - Add acquire dependencies and script\n");
+    return 255;
+}
+
+private Usm.Manifest create_manifest(string name, string template, HashSet<string> attributes) throws Error {
+    var manifest = new Usm.Manifest();
+    
+    // Basic manifest fields
+    manifest.name = name;
+    manifest.version = new Usm.Version.from_string("0.1.0");
+    manifest.summary = @"$name project";
+    manifest.licences = new Vector<Usm.Licence>();
+    manifest.licences.add(new Usm.Licence() { name = "MIT", category = Usm.LicenceCategory.LIBRE });
+    
+    // Dependencies
+    manifest.dependencies = new Usm.Dependencies();
+    manifest.dependencies.runtime = new HashSet<Usm.ResourceRef>();
+    manifest.dependencies.build = new HashSet<Usm.ResourceRef>();
+    manifest.dependencies.manage = new HashSet<Usm.ResourceRef>();
+    
+    // Executables
+    manifest.executables = new Usm.Executables();
+    manifest.flags = new HashSet<Usm.ManifestFlag>();
+    
+    // Template-specific configurations
+    switch(template) {
+        case "basic":
+            manifest.executables.build = "usm-scripts/build.sh";
+            break;
+            
+        case "makefile":
+            manifest.executables.build = "usm-scripts/build.sh";
+            manifest.executables.install = "usm-scripts/install.sh";
+            manifest.dependencies.manage.add(new Usm.ResourceRef("bin:bash"));
+            manifest.dependencies.build.add(new Usm.ResourceRef("bin:make"));
+            break;
+            
+        case "meson":
+            manifest.executables.build = "usm-scripts/build.sh";
+            manifest.executables.install = "usm-scripts/install.sh";
+            manifest.dependencies.manage.add(new Usm.ResourceRef("bin:bash"));
+            manifest.dependencies.build.add(new Usm.ResourceRef("bin:meson"));
+            manifest.dependencies.build.add(new Usm.ResourceRef("bin:ninja"));
+            manifest.flags.add(Usm.ManifestFlag.NINJA_STYLE_PROGRESS);
+            break;
+            
+        default:
+            throw new Error(Quark.from_string("scaffold"), 1, @"Unknown template '$template'");
+    }
+    
+    // Apply attributes
+    if(attributes.contains("vala")) {
+        manifest.dependencies.build.add(new Usm.ResourceRef("bin:valac"));
+        manifest.dependencies.build.add(new Usm.ResourceRef("pc:glib-2.0.pc"));
+        manifest.dependencies.build.add(new Usm.ResourceRef("pc:gobject-2.0.pc"));
+        manifest.dependencies.runtime.add(new Usm.ResourceRef("lib:libc.so"));
+        manifest.dependencies.runtime.add(new Usm.ResourceRef("lib:libglib-2.0.so"));
+        manifest.dependencies.runtime.add(new Usm.ResourceRef("lib:libgobject-2.0.so"));
+    }
+    
+    if(attributes.contains("c")) {
+        manifest.dependencies.build.add(new Usm.ResourceRef("bin:gcc"));
+        manifest.dependencies.runtime.add(new Usm.ResourceRef("lib:libc.so"));
+    }
+    
+    if(attributes.contains("acquire")) {
+        manifest.dependencies.acquire = new HashSet<Usm.ResourceRef>();
+        manifest.dependencies.acquire.add(new Usm.ResourceRef("bin:bash"));
+        manifest.dependencies.acquire.add(new Usm.ResourceRef("bin:wget"));
+        manifest.dependencies.acquire.add(new Usm.ResourceRef("bin:tar"));
+        manifest.executables.acquire = "usm-scripts/acquire.sh";
+    }
+    
+    return manifest;
+}
+
+private void write_manifest_file(Usm.Manifest manifest) throws Error {
+    var mapper = Usm.Manifest.get_mapper();
+    var properties = mapper.map_from(manifest);
+    var json_element = new InvercargillJson.JsonElement.from_properties(properties);
+    
+    json_element.write_to_file("MANIFEST.usm");
+}
+
+private void create_scripts(string template, HashSet<string> attributes) throws Error {
+    // Create usm-scripts directory
+    var scripts_dir = File.new_for_path("usm-scripts");
+    if(!scripts_dir.query_exists()) {
+        scripts_dir.make_directory_with_parents();
+    }
+    
+    // Create build script
+    var build_script = File.new_for_path("usm-scripts/build.sh");
+    create_build_script(build_script, template);
+    
+    // Create install script if needed
+    if(template == "makefile" || template == "meson") {
+        var install_script = File.new_for_path("usm-scripts/install.sh");
+        create_install_script(install_script, template);
+    }
+    
+    // Create acquire script if needed
+    if(attributes.contains("acquire")) {
+        var acquire_script = File.new_for_path("usm-scripts/acquire.sh");
+        create_acquire_script(acquire_script);
+    }
+}
+
+private void create_build_script(File file, string template) throws Error {
+    string content;
+    
+    switch(template) {
+        case "basic":
+            content = """#!/bin/bash
+set -e
+
+src_dir=$(pwd)
+build_dir=$1
+
+# Basic build script
+echo "Building $(basename $(pwd))..."
+# Add your build commands here
+
+echo "Build completed successfully"
+""";
+            break;
+            
+        case "makefile":
+            content = """#!/bin/bash
+set -e
+
+src_dir=$(pwd)
+build_dir=$1
+
+cd ${build_dir}
+
+make
+""";
+            break;
+            
+        case "meson":
+            content = """#!/bin/bash
+set -e
+
+src_dir=$(pwd)
+build_dir=$1
+
+cd ${build_dir}
+
+meson setup ${src_dir}/src --prefix=${PREFIX} --libdir=${LIBDIR} --bindir=${BINDIR} --includedir=${INCLUDEDIR}
+ninja
+""";
+            break;
+            
+        default:
+            throw new Error(Quark.from_string("scaffold"), 1, @"Unknown template '$template' for build script");
+    }
+    
+    write_script_file(file, content);
+}
+
+private void create_install_script(File file, string template) throws Error {
+    string content = get_script_header();
+    
+    switch(template) {
+        case "makefile":
+            content += """src_dir=$(pwd)
+build_dir=$1
+install_dir=$2
+
+cd ${build_dir}
+
+make install DESTDIR=${install_dir}
+""";
+            break;
+            
+        case "meson":
+            content += """src_dir=$(pwd)
+build_dir=$1
+install_dir=$2
+
+cd ${build_dir}
+
+meson install --destdir ${install_dir}
+""";
+            break;
+            
+        default:
+            throw new Error(Quark.from_string("scaffold"), 1, @"Unknown template '$template' for install script");
+    }
+    
+    write_script_file(file, content);
+}
+
+private void create_acquire_script(File file) throws Error {
+    string content = get_script_header();
+    
+    content += """# Acquire script - download and extract source archive
+# Replace these placeholders with actual values
+ARCHIVE_URL="https://example.com/source.tar.gz"
+ARCHIVE_NAME="source.tar.gz"
+EXTRACT_DIR="source"
+
+echo "Downloading source archive..."
+wget -O ${ARCHIVE_NAME} ${ARCHIVE_URL}
+
+echo "Extracting archive..."
+mkdir -p ${EXTRACT_DIR}
+tar -xzf ${ARCHIVE_NAME} -C ${EXTRACT_DIR} --strip-components=1
+
+echo "Cleaning up..."
+rm ${ARCHIVE_NAME}
+
+echo "Acquisition completed successfully"
+""";
+    
+    write_script_file(file, content);
+}
+
+private string get_script_header() {
+    return """#!/bin/bash
+set -e
+""";
+}
+
+private void write_script_file(File file, string content) throws Error {
+    var data_stream = new DataOutputStream(file.replace(null, false, FileCreateFlags.NONE));
+    data_stream.put_string(content);
+    
+    // Set execute bit
+    var file_info = file.query_info("*", FileQueryInfoFlags.NONE);
+    var mode = file_info.get_attribute_uint32("unix::mode");
+    mode |= 0111; // Add execute bit for owner, group, and others
+    file.set_attribute_uint32("unix::mode", mode, FileQueryInfoFlags.NONE);
+}

+ 1 - 0
src/cli/meson.build

@@ -3,6 +3,7 @@ sources = files('Cli.vala')
 sources += files('Manifest.vala')
 sources += files('Repository.vala')
 sources += files('Install.vala')
+sources += files('Scaffold.vala')
 
  deps = dependencies
  deps += usm_dep