From 75570f0770fade6f31b779099002cc8ecf092e31 Mon Sep 17 00:00:00 2001 From: T1mL3arn Date: Mon, 16 Oct 2023 20:30:02 +1000 Subject: [PATCH 1/2] Allow to use any template by giving its path --- info/template.txt | 21 ++++++++-- src/FlxTools.hx | 6 +++ src/commands/Template.hx | 85 ++++++++++++++++++++++++++++++++------ src/utils/CommandUtils.hx | 2 +- src/utils/FileSysUtils.hx | 7 +++- src/utils/TemplateUtils.hx | 53 ++++++++++++++++++------ 6 files changed, 144 insertions(+), 30 deletions(-) diff --git a/info/template.txt b/info/template.txt index 98c1b5a..65cd333 100644 --- a/info/template.txt +++ b/info/template.txt @@ -1,10 +1,25 @@ Usage : template - : The name for the template to generate, the "default" - template will be created when none is specified. + : The name or the path for the template to generate. + The "default" template will be created when none is specified. : The name for the path to create the template in, default is the name of the template itself. : The options available will depend on the specific template's template.json. The default template has options such as -n for project name and -w -h for width and height. Eg. flixel tpl -n "Name" -w 680 -h 480 - -ide : The IDE to use (overrides the configuration). \ No newline at end of file + -ide : The IDE to use (overrides the configuration). + + Examples : + + flixel tpl -n "Hello World" + Creates a project with name "Hello World" + from the "default" template, + inside "./Hello World" directory. + flixel tpl ./my-game -n MyGame + Creates a project with name "MyGame" + from the "default" template, + inside "./my-game" directory. + flixel tpl ../platformer-template . -n "Marevo" + Creates a project with name "Marevo" + from the template found in "../platformer-template" directory, + inside current directory. \ No newline at end of file diff --git a/src/FlxTools.hx b/src/FlxTools.hx index b4b2457..e7ef0bb 100644 --- a/src/FlxTools.hx +++ b/src/FlxTools.hx @@ -39,6 +39,12 @@ class FlxTools extends CommandLineRunner displayInfo(); } + override public function createConsole() + { + final isHaxelibRun = Sys.getEnv('HAXELIB_RUN') != null; + return new massive.sys.cmd.Console(isHaxelibRun); + } + static function displayInfo() { displayLogo(); diff --git a/src/commands/Template.hx b/src/commands/Template.hx index 2496075..03eab77 100644 --- a/src/commands/Template.hx +++ b/src/commands/Template.hx @@ -1,9 +1,11 @@ package commands; import FlxTools.IDE; +import haxe.io.Path; import massive.sys.cmd.Command; import sys.FileSystem; import utils.CommandUtils; +import utils.FileSysUtils; import utils.ProjectUtils; import utils.TemplateUtils; @@ -14,6 +16,32 @@ class Template extends Command override public function execute() { + /* + Ways to use `template` command + NOTE: literaly no one on github used "flixel tpl ./ + + - tpl + creates "FlxProject" from "default" tpl inside "%cwd/default" dir + - tpl -n MyGame + creates "MyGame" from "default" tpl inside "%cwd/MyGame" dir + - tpl demo + creates "FlxProject" from "demo" tpl inside "%cwd/demo" dir + - tpl demo -n MyGame + creates "MyGame" from "demo" tpl inside "%cwd/MyGame" dir + - tpl ./my-game + creates "FlxProject" from "default" tpl inside "%cwd/my-game" dir + - tpl ./my-game -n MyGame + creates "MyGame" from "default" tpl inside "%cwd/my-game" dir + - tpl demo my-game + creates "FlxProject" from "demo" tpl inside "%cwd/my-game" dir + - tpl demo my-game -n MyGame + creates "MyGame" from "demo" tpl inside "%cwd/MyGame" dir + - tpl ./demo ./../my-game + creates "FlxProject" from "./demo" tpl inside "%cwd/../my-game" dir + - tpl ../demo ./../my-game -n MyGame + creates "MyGame" from "./demo" tpl inside "%cwd/../my-game" dir + */ + TemplateUtils.verifyTemplatesLoaded(); var targetPath = ""; @@ -30,12 +58,9 @@ class Template extends Command ideOption = ProjectUtils.resolveIDEChoice(console, autoContinue); - if (console.getOption("-n") != null) - targetPath = console.getOption("-n"); - // support a path as an arg without name for default - // flixel t ./ - if (templateName.startsWith("./")) + // flixel tpl ./ + if (FileSysUtils.isDirectoryPath(templateName) && targetPath == "") { targetPath = templateName; templateName = ""; @@ -48,11 +73,30 @@ class Template extends Command { var template:TemplateProject = TemplateUtils.get(templateName); + // to fake existence of non-existed templates, + // will be deleted before merge + if (template == null) + { + trace('template was faked'); + template = { + name: templateName, + path: 'some/path/to/${templateName}', + template: { + replacements: [ + { + replacement: "FlxProject", + cmdOption: "-n", + pattern: "${PROJECT_NAME}" + } + ] + } + } + } + if (template == null) { - error("Error getting the template with the name of " - + templateName - + " make sure you have installed flixel-templates ('haxelib install flixel-templates')"); + error('Error getting the template with the name of "${templateName}"' + + "\nMake sure you have installed flixel-templates ('haxelib install flixel-templates')"); } else { @@ -62,15 +106,27 @@ class Template extends Command // override the template defaults form the command arguments template = addOptionReplacement(template); + // try to use project name as target path + if (targetPath == "" && console.getOption('-n') != null) + targetPath = console.getOption('-n'); + if (targetPath == "") { - targetPath = Sys.getCwd() + templateName; + targetPath = Path.join([Sys.getCwd(), templateName]); } - else if (!targetPath.startsWith("/")) + else if (!Path.isAbsolute(targetPath)) { - targetPath = CommandUtils.combine(Sys.getCwd(), CommandUtils.stripPath(targetPath)); + targetPath = Path.join([Sys.getCwd(), targetPath]); } + // used for tests, will be deleted before merge + Sys.print('\n--------- +template name: ${template.name} +template path: ${template.path} +target path: $targetPath +project name: ${console.getOption("-n") != null ? console.getOption("-n") : "FlxProject"} +---------\n'); + if (FileSystem.exists(targetPath)) { Sys.println("Warning::" + targetPath); @@ -79,7 +135,7 @@ class Template extends Command if (!autoContinue) { - answer = CommandUtils.askYN("Directory exists - do you want to delete it first?"); + answer = CommandUtils.askYN("Directory exists - do you want to delete it first? Type . to abort."); } if (answer == Answer.Yes) @@ -94,6 +150,11 @@ class Template extends Command exit(); } } + else if (answer == null) + { + Sys.println("Aborted by user"); + exit(); + } } Sys.println('Copying template files...'); diff --git a/src/utils/CommandUtils.hx b/src/utils/CommandUtils.hx index 1b59c2d..f3b36b4 100644 --- a/src/utils/CommandUtils.hx +++ b/src/utils/CommandUtils.hx @@ -76,7 +76,7 @@ class CommandUtils } /** - * Prompt user with a y/n/a + * Prompt user with a y/n * * @param question String with the prompt to display * @return User choice in an Answer enum or null if an invalid answer given diff --git a/src/utils/FileSysUtils.hx b/src/utils/FileSysUtils.hx index 273a09e..1bf77cc 100644 --- a/src/utils/FileSysUtils.hx +++ b/src/utils/FileSysUtils.hx @@ -19,7 +19,7 @@ class FileSysUtils } catch (e:Dynamic) { - throw "Error loading file::" + filePath + " \n check you dont have it open and you have permissions to modify it."; + throw "Error loading file::" + filePath + " \n Check the file exists or you dont have it open and you have permissions to modify it."; } } @@ -45,4 +45,9 @@ class FileSysUtils segments.shift(); return segments.join(cwd); } + + public static function isDirectoryPath(str:String):Bool + { + return new Path(str).dir != null; + } } diff --git a/src/utils/TemplateUtils.hx b/src/utils/TemplateUtils.hx index a2550b7..6692d42 100644 --- a/src/utils/TemplateUtils.hx +++ b/src/utils/TemplateUtils.hx @@ -2,6 +2,7 @@ package utils; import FlxTools.IDE; import haxe.Json; +import haxe.io.Path; import massive.sys.io.FileSys; import sys.FileSystem; import sys.io.FileOutput; @@ -24,6 +25,9 @@ class TemplateUtils if (templateName == "") templateName = 'default'; + if (FileSysUtils.isDirectoryPath(templateName)) + return findTemplate(templateName); + for (template in findTemplates()) { if (template.name == templateName) @@ -32,17 +36,33 @@ class TemplateUtils return null; } + public static function findTemplate(path:String):TemplateProject + { + if (!FileSys.exists(path)) + return null; + + // NOTE: isDirectory() throws an error if path does not exist + if (!FileSys.isDirectory(path)) + return null; + + path = FileSystem.fullPath(Path.normalize(path)); + var dirName = Path.withoutDirectory(Path.removeTrailingSlashes(path)); + var template = readTemplateJson(path, dirName); + + return template; + } + public static function findTemplates(?templatesPath:String):Array { if (templatesPath == null) { templatesPath = CommandUtils.getHaxelibPath("flixel-templates"); if (templatesPath == "") - return null; + return []; } if (!FileSys.exists(templatesPath)) - return null; + return []; final templates = []; @@ -52,20 +72,13 @@ class TemplateUtils if (FileSys.exists(folderPath) && FileSys.isDirectory(folderPath) && name != '.git') { - var filePath = CommandUtils.combine(templatesPath, name); - filePath = CommandUtils.combine(filePath, "template.json"); + var templatePath = CommandUtils.combine(templatesPath, name); + var templateJsonPath = CommandUtils.combine(templatePath, "template.json"); // Make sure we don't get a crash if the file doesn't exist - if (FileSystem.exists(filePath)) + if (FileSystem.exists(templateJsonPath)) { - final file = FileSysUtils.getContent(filePath); - final FileData:TemplateFile = Json.parse(file); - final project:TemplateProject = { - name: name, - path: templatesPath + name, - template: FileData - }; - templates.push(project); + templates.push(readTemplateJson(templatePath, name, templateJsonPath)); } } } @@ -73,6 +86,20 @@ class TemplateUtils return templates; } + static function readTemplateJson(templatePath:String, teamplateName:String, ?templateJsonPath:String):TemplateProject + { + if (templateJsonPath == null) + templateJsonPath = Path.join([templatePath, "template.json"]); + + final fileContent = FileSysUtils.getContent(templateJsonPath); + + return { + name: teamplateName, + path: templatePath, + template: Json.parse(fileContent) + }; + } + public static function getReplacementValue(replacements:Array, pattern:String):String { for (o in replacements) From a3a35f2732bd285bc086d2aca03a30af08e12ba7 Mon Sep 17 00:00:00 2001 From: Timur Date: Thu, 16 Nov 2023 11:43:51 +1000 Subject: [PATCH 2/2] Trying to make command help less confusing --- info/template.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/info/template.txt b/info/template.txt index 65cd333..32b34aa 100644 --- a/info/template.txt +++ b/info/template.txt @@ -1,8 +1,10 @@ - Usage : template - : The name or the path for the template to generate. + Usage : template + : + The name or the path of the template to generate. The "default" template will be created when none is specified. - : The name for the path to create the template in, default - is the name of the template itself. + : + The path to create the template in, default is the name + of the template itself. : The options available will depend on the specific template's template.json. The default template has options such as -n for project name and -w -h for width and height.