提交 0e89d33b 编写于 作者: sq3536's avatar sq3536

支持-t...

支持-t 参数多模板文件夹逗号分隔叠加,支持--template-path强行指定目录中的一个或多个相对模板文件路径,支持--template-filter指定一个或多个模板文件全路径正则表达式关键词筛选
上级 cdaa4b8e
......@@ -34,11 +34,20 @@ public class Generate extends IbizLabGeneratorCommand {
description = "location of the ibizlab-Model spec, as URL or file (required if not loaded via config using -c)")
private String spec;
@Option(name = {"-t", "--template-dir"}, title = "template directory",
description = "folder containing the template files")
@Option(name = {"-t", "--template-dir"}, title = "template directories",
description = "folder containing the template files, multiple paths are supported, separated by commas. (e.g. /templateA,/tmp/templateB).")
private String templateDir;
@Option(name = {"--template-path"}, title = "template files relative path",
description = "special template file's relative path, multiple paths are supported, separated by commas. (e.g. /folderA/README.md.hbs,/folderB/sub/file.json.hbs).")
private String templatePath;
@Option(name = {"--template-filter"}, title = "template file's filter regex",
description = "template file's filter regex, multiple regex are supported, separated by commas. (e.g. /folderA,/folderB/.*/{{entities}}.java.hbs).")
private String templateFilter;
@Option(
name = {"-a", "--auth"},
title = "authorization",
......@@ -151,6 +160,14 @@ public class Generate extends IbizLabGeneratorCommand {
configurator.setTemplateDir(templateDir);
}
if (isNotEmpty(templatePath)) {
configurator.setTemplatePath(templatePath);
}
if (isNotEmpty(templateFilter)) {
configurator.setTemplateFilter(templateFilter);
}
if (isNotEmpty(packageName)) {
configurator.setPackageName(packageName);
}
......
package cn.ibizlab.codegen;
import cn.ibizlab.codegen.config.GlobalSettings;
import cn.ibizlab.codegen.templating.MustacheEngineAdapter;
import cn.ibizlab.codegen.templating.TemplateDefinition;
import cn.ibizlab.codegen.templating.TemplatingEngineAdapter;
import cn.ibizlab.codegen.templating.*;
import cn.ibizlab.codegen.templating.mustache.*;
import cn.ibizlab.codegen.utils.StringAdvUtils;
import com.github.benmanes.caffeine.cache.Cache;
......@@ -15,6 +13,7 @@ import lombok.Setter;
import lombok.experimental.Accessors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.io.File;
......@@ -33,9 +32,14 @@ public class CodegenConfig {
private String inputSpec;
private String outputDir;
private String templateDir;
private List<String> templateDirs;
private String auth;
private List<String> templatePaths;
private List<String> templateFilters;
public CodegenConfig setInputSpec(String inputSpec) {
if(!StringUtils.isEmpty(inputSpec))
{
......@@ -54,21 +58,121 @@ public class CodegenConfig {
return this;
}
public CodegenConfig setTemplateDir(String templateDir) {
public CodegenConfig setTemplateDirs(List<String> templateDirs) {
if(ObjectUtils.isEmpty(templateDirs))
return this;
this.templateDirs=new ArrayList<>();
for(String templateDir:templateDirs)
{
templateDir=templateDir.trim();
if(!StringUtils.isEmpty(templateDir))
{
templateDir=templateDir.replace("\\", "/");
templateDir=Paths.get(templateDir).toString();
this.templateDir=templateDir.replace("\\", "/");
templateDir=templateDir.replace("\\", "/");
this.templateDirs.add(templateDir);
}
}
return this;
}
public CodegenConfig setTemplateDirs(String dirs) {
if(!StringUtils.isEmpty(dirs))
setTemplateDirs(Arrays.asList(dirs.split(";|,")));
return this;
}
public CodegenConfig setTemplatePaths(List<String> templatePaths) {
if(ObjectUtils.isEmpty(templatePaths))
return this;
this.templatePaths=new ArrayList<>();
for(String templatePath:templatePaths)
{
templatePath=templatePath.trim();
if(!StringUtils.isEmpty(templatePath))
{
templatePath=templatePath.replace("\\", "/");
if(!templatePath.startsWith("/"))
templatePath="/"+templatePath;
templatePath=Paths.get(templatePath).toString();
templatePath=templatePath.replace("\\", "/");
this.templatePaths.add(templatePath);
}
}
return this;
}
public CodegenConfig setTemplatePaths(String paths) {
if(!StringUtils.isEmpty(paths))
setTemplatePaths(Arrays.asList(paths.split(";|,")));
return this;
}
public CodegenConfig setTemplateFilters(List<String> templateFilters) {
if(ObjectUtils.isEmpty(templateFilters))
return this;
this.templateFilters=new ArrayList<>();
for(String filter:templateFilters)
{
filter=filter.trim();
if(!StringUtils.isEmpty(filter))
{
filter=filter.replace("{{","\\{\\{").replace("}}","\\}\\}");
if(!filter.startsWith(".*"))
filter=".*"+filter;
if(!filter.endsWith(".*"))
filter=filter+".*";
this.templateFilters.add(filter);
}
}
return this;
}
public CodegenConfig setTemplateFilters(String templateFilters) {
if(!StringUtils.isEmpty(templateFilters))
setTemplateFilters(Arrays.asList(templateFilters.split(";|,")));
return this;
}
public String getTemplateDir()
{
if(!ObjectUtils.isEmpty(this.getTemplateDirs()))
return this.getTemplateDirs().get(0);
return null;
}
private Map<String, Object> additionalProperties = new HashMap<>();
private Map<String, String> typeMappings;
private TemplatingEngineAdapter templatingEngine;
private TemplateManager templateProcessor;
public TemplateManager getTemplateProcessor()
{
if(templateProcessor==null)
{
List<TemplatePathLocator> list=new ArrayList<>();
this.getTemplateDirs().forEach(templateDir->{
list.add(new GeneratorTemplateContentLocator(templateDir));
});
list.add(new CommonTemplateContentLocator());
this.templateProcessor = new TemplateManager(
new TemplateManagerOptions(this.isEnableMinimalUpdate(),this.isSkipOverwrite()),
templatingEngine,
list
);
}
return templateProcessor;
}
public boolean isEnableMinimalUpdate()
{
return Boolean.valueOf(additionalProperties.getOrDefault("enableMinimalUpdate",false).toString());
......@@ -83,16 +187,43 @@ public class CodegenConfig {
return additionalProperties.getOrDefault(CodegenConstants.IGNORE_FILE_OVERRIDE,"").toString();
}
private List<TemplateDefinition> templateDefinitions;
private Map<String,TemplateDefinition> templates;
public List<TemplateDefinition> getTemplateDefinitions()
public synchronized Collection<TemplateDefinition> getTemplateDefinitions()
{
if(templateDefinitions==null&& (!StringUtils.isEmpty(templateDir)))
if(templates==null)
{
templateDefinitions=new ArrayList<>();
scanTemplate(new File(templateDir),templateDefinitions);
templates=new LinkedHashMap<>();
if(!ObjectUtils.isEmpty(templateDirs))
{
if(!ObjectUtils.isEmpty(templatePaths))
{
templateDirs.forEach(dir->{
File templateDir=new File(dir);
if(templateDir.exists()&&templateDir.isDirectory())
{
templatePaths.forEach(templatePath->{
scanTemplate(dir,Paths.get(dir,templatePath).toFile(),templates);
});
}
return templateDefinitions;
});
}
else
{
templateDirs.forEach(dir->{
scanTemplate(dir,new File(dir),templates);
});
}
}
}
return templates.values();
}
public CodegenConfig addLambda()
......@@ -116,16 +247,37 @@ public class CodegenConfig {
return this;
}
private void scanTemplate(File file,List<TemplateDefinition> templateDefinitions)
private void scanTemplate(String rootDir,File file,Map<String,TemplateDefinition> templateDefinitions)
{
if(file.exists()) {
if(file.isDirectory())
{
for(File sub:file.listFiles())
scanTemplate(sub,templateDefinitions);
scanTemplate(rootDir,sub,templateDefinitions);
}
else {
String path=file.getPath().replace("\\","/");
templateDefinitions.add(new TemplateDefinition(path.replace(this.getTemplateDir(),"").toString()));
String absolutePath=file.getPath().replace("\\","/");
String path=absolutePath.replace(rootDir,"");
if(!ObjectUtils.isEmpty(this.templateFilters))
{
boolean matched=false;
for(String filter:this.templateFilters)
{
if(path.matches(filter))
{
matched=true;
break;
}
}
if(!matched)
return;
}
if(!templateDefinitions.containsKey(path)){
TemplateDefinition templateDefinition=new TemplateDefinition(path,rootDir);
templateDefinitions.put(path,templateDefinition);
}
}
}
}
......
......@@ -38,22 +38,16 @@ public class DefaultGenerator implements Generator {
modelStorage=ModelStorage.getInstance().config(config);
TemplateManagerOptions templateManagerOptions = new TemplateManagerOptions(this.config.isEnableMinimalUpdate(),this.config.isSkipOverwrite());
TemplatingEngineAdapter templatingEngine = this.config.getTemplatingEngine();
TemplatePathLocator commonTemplateLocator = new CommonTemplateContentLocator();
TemplatePathLocator generatorTemplateLocator = new GeneratorTemplateContentLocator(this.config);
this.templateProcessor = new TemplateManager(
templateManagerOptions,
templatingEngine,
new TemplatePathLocator[]{generatorTemplateLocator, commonTemplateLocator}
);
this.templateProcessor=this.config.getTemplateProcessor();
String ignoreFileLocation = this.config.getIgnoreFilePathOverride();
this.ignoreProcessor=CodegenIgnoreProcessor.getInstance(ignoreFileLocation,this.config.getOutputDir(),this.config.getTemplateDir());
List<String> ignorePaths=new ArrayList<>();
ignorePaths.add(ignoreFileLocation);
ignorePaths.add(this.config.getOutputDir());
ignorePaths.addAll(this.config.getTemplateDirs());
this.ignoreProcessor=CodegenIgnoreProcessor.getInstance(ignorePaths);
return this;
}
......
......@@ -38,6 +38,8 @@ public final class CodegenConfigurator {
private String inputSpec;
private String outputDir;
private String templateDir;
private String templatePath;
private String templateFilter;
private String auth;
private String templatingEngineName="mustache";
......@@ -210,6 +212,15 @@ public final class CodegenConfigurator {
return this;
}
public CodegenConfigurator setTemplatePath(String templatePath) {
this.templatePath = templatePath;
return this;
}
public CodegenConfigurator setTemplateFilter(String templateFilter) {
this.templateFilter = templateFilter;
return this;
}
public CodegenConfig toClientOptInput() {
......@@ -239,7 +250,11 @@ public final class CodegenConfigurator {
if(!StringUtils.isEmpty(this.outputDir))
config.setOutputDir(this.outputDir);
if(!StringUtils.isEmpty(this.templateDir))
config.setTemplateDir(this.templateDir);
config.setTemplateDirs(this.templateDir);
if(!StringUtils.isEmpty(this.templatePath))
config.setTemplatePaths(this.templatePath);
if(!StringUtils.isEmpty(this.templateFilter))
config.setTemplateFilters(this.templateFilter);
if(!StringUtils.isEmpty(this.auth))
config.setAuth(this.auth);
......
......@@ -24,15 +24,21 @@ public class CodegenIgnoreProcessor {
private List<Rule> inclusionRules = new ArrayList<>();
public static CodegenIgnoreProcessor getInstance(final String... baseDirectorys) {
public static CodegenIgnoreProcessor getInstance(List<String> baseDirectorys) {
for(String baseDirectory:baseDirectorys)
{
if(StringUtils.isEmpty(baseDirectory))
continue;
final File directory = new File(baseDirectory);
final File targetIgnoreFile = new File(directory, ".ibizlab-generator-ignore");
if (directory.exists() && directory.isDirectory() && targetIgnoreFile.exists() && targetIgnoreFile.isFile()) {
File targetIgnoreFile = null;
if (directory.exists() && directory.isDirectory()){
targetIgnoreFile = new File(directory, ".ibizlab-generator-ignore");
}
else if (directory.exists() && directory.isFile()){
targetIgnoreFile=directory;
}
if (targetIgnoreFile!=null && targetIgnoreFile.exists() && targetIgnoreFile.isFile()) {
CodegenIgnoreProcessor processor = new CodegenIgnoreProcessor();
try {
try (FileInputStream fileInputStream = new FileInputStream(targetIgnoreFile);
......
......@@ -8,60 +8,23 @@ import java.io.File;
* Locates templates according to {@link CodegenConfig} settings.
*/
public class GeneratorTemplateContentLocator implements TemplatePathLocator {
private final CodegenConfig codegenConfig;
private String templateDir;
/**
* Constructs a new instance of {@link GeneratorTemplateContentLocator} for the provided {@link CodegenConfig}
*
* @param codegenConfig A generator's configuration used for determining template file location.
*/
public GeneratorTemplateContentLocator(CodegenConfig codegenConfig) {
this.codegenConfig = codegenConfig;
public GeneratorTemplateContentLocator(String templateDir) {
this.templateDir = templateDir;
}
/**
* Determines whether an embedded file with the specified name exists.
*
* @param name The name of the file (i.e. relative to resource root)
*
* @return true if file is an embedded resource, false if it does not exist
*/
public boolean embeddedTemplateExists(String name) {
return classpathTemplateExists(name);
}
private boolean classpathTemplateExists(String name) {
return this.getClass().getClassLoader().getResource(TemplateManager.getCPResourcePath(name)) != null;
}
/**
* Get the template file path with template dir prepended, and use the library template if exists.
*
* Precedence:
* 1) (template dir)/libraries/(library)
* 2) (template dir)
* 3) (embedded template dir)/libraries/(library)
* 4) (embedded template dir)
*
* Where "template dir" may be user defined and "embedded template dir" are the built-in templates for the given generator.
*
* @param relativeTemplateFile Template file
* @return String Full template file path
*/
@Override
public String getFullTemplatePath(String relativeTemplateFile) {
CodegenConfig config = this.codegenConfig;
// check the supplied template main folder for the file
// File.separator is necessary here as the file load is OS-specific
final String template = config.getTemplateDir() + File.separator + relativeTemplateFile;
final String template = templateDir + File.separator + relativeTemplateFile;
// looks for user-defined file or classpath
// supports template dir which refers to local file system or custom path in classpath as defined by templateDir
if (new File(template).exists() || classpathTemplateExists(template)) {
if (new File(template).exists()) {
return template;
}
......
......@@ -23,6 +23,10 @@ import java.util.regex.Pattern;
public class TemplateDefinition {
private String templateFile;
private String absolutePath;
private String templateDir;
protected TemplateFileType templateType;
private String subType;
......@@ -30,8 +34,13 @@ public class TemplateDefinition {
protected CliData templateDatas;
public TemplateDefinition(String templateFile) {
}
public TemplateDefinition(String templateFile,String templateDir) {
if (templateFile == null) throw new IllegalArgumentException("templateFile may not be null.");
this.templateDir=templateDir;
this.templateFile = templateFile;
this.templateType = getType(Paths.get(this.templateFile));
CliData data=ModelStorage.getInstance().getTemplateData(this.templateType);
......@@ -73,4 +82,12 @@ public class TemplateDefinition {
return getType(path.getParent());
}
public static void main(String[] args) {
String m="src/main/resources/templ/r7/{{projectName}}-boot/src/main/java/{{packageName@NONE}}/config/DevBootAutoConfiguration.java.hbs"
.replace("{{","\\{\\{").replace("}}","\\}\\}");
System.out.println("src/main/resources/templ/r7/{{projec1tName}}-boot/src/main/java/{{packageName@NONE}}/config/DevBootAutoConfiguration.java.hbs"
.matches(".*"+m+".*"));
}
}
......@@ -9,10 +9,7 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;
import java.util.*;
import java.util.regex.Pattern;
/**
......@@ -21,7 +18,7 @@ import java.util.regex.Pattern;
public class TemplateManager implements TemplatingExecutor, TemplateProcessor {
private final TemplateManagerOptions options;
private final TemplatingEngineAdapter engineAdapter;
private final TemplatePathLocator[] templateLoaders;
private final List<TemplatePathLocator> templateLoaders;
private final Logger LOGGER = LoggerFactory.getLogger(TemplateManager.class);
......@@ -29,14 +26,14 @@ public class TemplateManager implements TemplatingExecutor, TemplateProcessor {
public TemplateManager(
TemplateManagerOptions options,
TemplatingEngineAdapter engineAdapter,
TemplatePathLocator[] templateLoaders) {
List<TemplatePathLocator> templateLoaders) {
this.options = options;
this.engineAdapter = engineAdapter;
this.templateLoaders = templateLoaders;
}
private String getFullTemplateFile(String name) {
String template = Arrays.stream(this.templateLoaders)
String template = templateLoaders.stream()
.map(i -> i.getFullTemplatePath(name))
.filter(Objects::nonNull)
.findFirst()
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册