jbang icon indicating copy to clipboard operation
jbang copied to clipboard

Unable to use {basename} in template file-refs

Open nandorholozsnyak opened this issue 3 years ago • 3 comments

Describe the bug JBang templates are providing ways to reuse the file input name coming as an input from the user. It can be {filename} and {basename}. If the input is Example.java (jbang init Example.java) the {filename} variable will be Example.java and the {basename} will be Example. That is cool, BUT, look at the following use case:

...
"q-aws-lambda-tf": {
      "file-refs": {
        "{filename}": "aws/aws-lambda.java.qute",
        "generate-jar": "aws/generate-jar",
        "generate-native-image": "aws/generate-native-image",
        "application.properties": "aws/application.properties",
        "lambda-aws-{basename}.tf": "aws/lambda-aws.tf.qute"
      },
...

If I would like to go with this approach (jbang init -t=q-aws-lambda-tf Example.java) the last entry with "lambda-aws-{basename}.tf": "aws/lambda-aws.tf.qute" will cause an error for the Init command because its extension is not .java, it is .tf and the Init commands checks if the {basename} variable is found in a file entry key, then it validates that the entry's key extension matches the input file extension.

Here is the code for the check:

static Path resolveBaseName(String refTarget, String refSource, String outName) {
		String result = refTarget;
		if (dev.jbang.cli.Template.TPL_FILENAME_PATTERN.matcher(refTarget).find()
				|| dev.jbang.cli.Template.TPL_BASENAME_PATTERN.matcher(refTarget).find()) {
			String baseName = Util.base(outName);
			String outExt = Util.extension(outName);
			String targetExt = Util.extension(refTarget);
			if (targetExt.isEmpty()) {
				targetExt = refSource.endsWith(".qute") ? Util.extension(Util.base(refSource))
						: Util.extension(refSource);
			}
			if (!outExt.isEmpty() && !outExt.equals(targetExt)) {
				throw new ExitException(BaseCommand.EXIT_INVALID_INPUT,
						"Template expects " + targetExt + " extension, not " + outExt);
			}
			result = dev.jbang.cli.Template.TPL_FILENAME_PATTERN.matcher(result).replaceAll(outName);
			result = dev.jbang.cli.Template.TPL_BASENAME_PATTERN.matcher(result).replaceAll(baseName);
		}
		return Paths.get(result);
	}

In my opinion the two variables (filename and basename) should be two different uses cases, I would like to use the {basename} variable in other entries as well, the filename variable is totally understandable, but the basename should be allowed to use with different extensions.

To Reproduce Above.

Expected behavior Let the {basename} variable be used for other file entries as well.

JBang version 0.91

nandorholozsnyak avatar Mar 20 '22 14:03 nandorholozsnyak

@quintesse @maxandersen what do you think about it?

nandorholozsnyak avatar Mar 21 '22 06:03 nandorholozsnyak

I think it should be ok.

It's just important the final list of file names are unique and deterministic which still seem to be the case here.

maxandersen avatar Mar 21 '22 07:03 maxandersen

I think it should be ok.

It's just important the final list of file names are unique and deterministic which still seem to be the case here.

Nothing should be broken. A PR is open for that.

nandorholozsnyak avatar Mar 21 '22 08:03 nandorholozsnyak