From 9c5ae39ead39a267f13d0848b420ca243f61ed56 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 24 Jun 2025 11:29:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20GenerateCommand=20?= =?UTF-8?q?=E5=92=8C=20GenerateTask=20=E5=AE=9E=E7=8E=B0=E7=94=9F=E6=88=90?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E9=AA=A8=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/jcnc/snow/cli/SnowCLI.java | 2 + .../snow/cli/commands/GenerateCommand.java | 59 ++++++++++++ .../org/jcnc/snow/pkg/tasks/GenerateTask.java | 91 +++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 src/main/java/org/jcnc/snow/cli/commands/GenerateCommand.java create mode 100644 src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java diff --git a/src/main/java/org/jcnc/snow/cli/SnowCLI.java b/src/main/java/org/jcnc/snow/cli/SnowCLI.java index 8b9e903..03a4391 100644 --- a/src/main/java/org/jcnc/snow/cli/SnowCLI.java +++ b/src/main/java/org/jcnc/snow/cli/SnowCLI.java @@ -29,6 +29,7 @@ public class SnowCLI { * 值为返回相应 {@link CLICommand} 实例的 Supplier。 */ private static final Map> COMMANDS = Map.of( + "generate", GenerateCommand::new, "compile", CompileCommand::new, "run", RunCommand::new, "version", VersionCommand::new, @@ -37,6 +38,7 @@ public class SnowCLI { "install", InstallCommand::new, "publish", PublishCommand::new, "clean", CleanCommand::new + ); /** diff --git a/src/main/java/org/jcnc/snow/cli/commands/GenerateCommand.java b/src/main/java/org/jcnc/snow/cli/commands/GenerateCommand.java new file mode 100644 index 0000000..8772776 --- /dev/null +++ b/src/main/java/org/jcnc/snow/cli/commands/GenerateCommand.java @@ -0,0 +1,59 @@ +package org.jcnc.snow.cli.commands; + +import org.jcnc.snow.cli.api.CLICommand; +import org.jcnc.snow.pkg.dsl.CloudDSLParser; +import org.jcnc.snow.pkg.lifecycle.LifecycleManager; +import org.jcnc.snow.pkg.lifecycle.LifecyclePhase; +import org.jcnc.snow.pkg.model.Project; +import org.jcnc.snow.pkg.tasks.GenerateTask; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +/** + * CLI 命令:根据 project.cloud 生成项目目录结构。 + * + *
+ * $ snow generate
+ * 
+ * + * - 若当前目录不存在 project.cloud,则提示先执行 snow init。 + * - 成功后会在控制台输出已创建的目录/文件列表。 + */ +public final class GenerateCommand implements CLICommand { + + @Override + public String name() { + return "generate"; + } + + @Override + public String description() { + return "Generate project directory structure based on project.cloud."; + } + + @Override + public void printUsage() { + System.out.println("Usage: snow generate"); + } + + @Override + public int execute(String[] args) throws Exception { + Path dsl = Paths.get("project.cloud"); + if (Files.notExists(dsl)) { + System.err.println("project.cloud not found. Please run `snow init` first."); + return 1; + } + + /* 1. 解析 DSL */ + Project project = CloudDSLParser.parse(dsl); + + /* 2. 执行生成任务 —— 复用 Lifecycle INIT 阶段 */ + LifecycleManager lm = new LifecycleManager(); + lm.register(LifecyclePhase.INIT, new GenerateTask(project)); + lm.executeAll(); + + return 0; + } +} diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java new file mode 100644 index 0000000..4f43f51 --- /dev/null +++ b/src/main/java/org/jcnc/snow/pkg/tasks/GenerateTask.java @@ -0,0 +1,91 @@ +package org.jcnc.snow.pkg.tasks; + +import org.jcnc.snow.pkg.model.Project; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +/** + * 任务:依据 {@link Project} 元数据创建标准项目目录。 + *

+ * 生成内容: + *

+ */ +public final class GenerateTask implements Task { + + private final Project project; + + public GenerateTask(Project project) { + this.project = project; + } + + @Override + public void run() throws IOException { + Path root = Paths.get(".").toAbsolutePath(); + + /* -------- 创建目录 -------- */ + List dirs = List.of( + root.resolve("src"), + root.resolve("test"), + root.resolve("build"), + root.resolve("dist") + ); + + for (Path dir : dirs) { + if (Files.notExists(dir)) { + Files.createDirectories(dir); + System.out.println("[generate] created directory " + root.relativize(dir)); + } + } + + /* -------- 创建示例入口文件 -------- */ + Path mainSnow = root.resolve("src").resolve("main.snow"); + if (Files.notExists(mainSnow)) { + Files.writeString(mainSnow, """ + module: Math + function: main + parameter: + return_type: int + body: + Math.factorial(6) + return 0 + end body + end function + + function: factorial + parameter: + declare n:int + return_type: int + body: + declare num1:int = 1 + loop: + initializer: + declare counter:int = 1 + condition: + counter <= n + update: + counter = counter + 1 + body: + num1 = num1 * counter + end body + end loop + return num1 + end body + end function + end module + """); + System.out.println("[generate] created src/main.snow"); + } + + System.out.println("[generate] project scaffold is ready."); + } +}