feat: 增加 GenerateCommand 和 GenerateTask 实现生成项目骨架

This commit is contained in:
Luke 2025-06-24 11:29:54 +08:00
parent bd9691b7eb
commit 9c5ae39ead
3 changed files with 152 additions and 0 deletions

View File

@ -29,6 +29,7 @@ public class SnowCLI {
* 值为返回相应 {@link CLICommand} 实例的 Supplier
*/
private static final Map<String, Supplier<CLICommand>> 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
);
/**

View File

@ -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 生成项目目录结构
*
* <pre>
* $ snow generate
* </pre>
*
* - 若当前目录不存在 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;
}
}

View File

@ -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} 元数据创建标准项目目录
* <p>
* 生成内容
* <ul>
* <li>src/ 源码目录</li>
* <li>test/ 测试源码目录</li>
* <li>build/ 编译输出目录</li>
* <li>dist/ 打包输出目录</li>
* <li>src/main.snow Hello, Snow! 示例入口</li>
* </ul>
*/
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<Path> 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.");
}
}