Templating: Allow sourceName to be used as source for casing generator

Created on 31 Dec 2019  路  19Comments  路  Source: dotnet/templating

I'm after a way to get the lowercase version of the main template name. The below template configuration produces the issue with the below csproj file. Maybe I've got invalid syntax or an something else isn't correct. I can't just specify the lowercase name as the -n command because I want to support a mixed case for that parameter (e.g. I want the user to specify FooDomain instead of foodomain because of naming conventions).

To repro, you can use the following template config:

{  
  "$schema": "http://json.schemastore.org/template",
  "author": "Blank",
  "classifications": [
    "Web",
    "WebAPI"
  ],
  "name": "Test",
  "identity": "Test.Casing",
  "shortName": "casing-test",
  "sourceName": "ApplicationName",
  "preferNameDirectory": true,
  "tags": {  
    "language": "C#"
  },
  "primaryOutputs": [
    {  
      "path": "ApplicationName.csproj"
    }
  ],
  "symbols": {
    "sourceNameLower": {
      "type": "generated",
      "generator": "casing",
      "parameters": {
        "source":"sourceName",
        "toLower": true
      },
      "replaces": "ApplicationNameLower"
    }
  },
  "postActions": []
}

And a single file in the template content called "ApplicationName.csproj":

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <Authors>Blank/Authors>
    <Version>1.0.0</Version>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
    <UserSecretsId>dd663411-3e30-405b-85b6-be2f9b61bf95</UserSecretsId>
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
    <ArtifactsDirectory>app</ArtifactsDirectory>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.7.9" />
  </ItemGroup>

    <!--
        DeleteArtifacts target:
            This target runs after clean.
    -->
    <Target Name="DeleteArtifacts" BeforeTargets="Package" Condition="Exists('$(ArtifactsDirectory)')">
        <Message Importance="High" Text="Deleting artifacts directory '$(ArtifactsDirectory)''" />
        <RemoveDir Directories="$(ArtifactsDirectory)" />
    </Target>

    <!--
        Package target:
            This target compiles the project in release mode and builds the docker container.
    -->
    <Target Name="Package">
        <Message Importance="High" Text="Publishing release artifacts..." />
        <Exec Command="dotnet publish -c Release -o $(ArtifactsDirectory)" />

        <Message Importance="High" Text="Building docker container..." />
        <Exec Command="docker build . -t ApplicationNameLower:latest" />
    </Target>

</Project>

My expectation is that when a user runs dotnet new casing-test -n FooDomain that they get a csproj called FooDomain.csproj with the Exec step in the Package target matching <Exec Command="docker build . -t foodomain:latest" />. Currently, the part that says foodomain is just left blank.

1.0 triaged

Most helpful comment

Any workarounds or news of a fix for this? I'd really like the lower case sourceName, so I can use it for a Docker tag which is required to be lower case.

All 19 comments

Have you tried with a different string for the lower casing? For ex AppNameLower instead of ApplicationNameLower? Since ApplicationName is a substring of ApplicationNameLower I could see how that may introduce issues.

@sayedihashimi, unfortunately, I'm seeing the same behavior even with something that doesn't contain ApplicationName. dotnet cli version => 3.1.100

@ardove that鈥檚 a bummer, let鈥檚 see what the team here says. I鈥檓 curious about this one as well.

@sayedihashimi any updates from the team?

This issue is larger than the casing generator. I think it鈥檚 that sourceName can鈥檛 be referenced by a generated symbol.

I had created some templates and was using a series of RegEx replacements on sourceName. I was hoping to be able to split camel/Pascal & dot notation into words for a more friendly title tag in an HTML document in the template and create a variation of the sourceName for a gRPC proto package name.

Being able to use the sourceName as a variable would be incredibly useful!

A potential workaround I'm considering is running an included PowerShell script that would do the replacements for me and remove itself.

Is there a potential that this would be available in .Net Core 3x?

@mikhey were you able to access sourceName?

@mikhey were you able to access sourceName?

@brettrowberry I wasn't able to, it gave me an empty string.

Here's an example from the template config:

{
  "$schema": "http://json.schemastore.org/template",
  "author": "mikhey",
  "classifications": [
    "Web",
    "Micro-Service"
  ],
  "name": "My Micro-Service",
  "identity": "My.Template.MicroService.CSharp",
  "groupIdentity": "My.Template.MicrosService",
  "shortName": "my-microservice",
  "tags": {
    "language": "C#",
    "type": "project"
  },
  "sourceName": "MicroService",
  "preferNameDirectory": true,
  "symbols": {
    "serviceName": {
      "type": "generated",
      "generator": "regex",
      "datatype": "string",
      "replaces": "$(serviceName)$",
      "parameters": {
        "source": "sourceName",
        "action": "replace",
        "steps": [
          {
            "regex": "(\\.|-|_)",
            "replacement": ""
          },
          {
            "regex": "(?<=[\\.])(?=[A-Z])|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g",
            "replacement": ""
          }
        ]
      }
    },
  //...
 }
}

Ok same. Good to know it definitely doesn鈥檛 work instead of thinking it鈥檚 just me!

Any workarounds or news of a fix for this? I'd really like the lower case sourceName, so I can use it for a Docker tag which is required to be lower case.

Any workarounds or news of a fix for this? I'd really like the lower case sourceName, so I can use it for a Docker tag which is required to be lower case.

This is exactly the case we wanted it for originally.

This solution solved my problem: https://github.com/dotnet/templating/issues/1746#issuecomment-456977693

"sourceName -> name" is not the only replacement related to sourceName that applies to the template. To see all the generated replacements for the template, visit our wiki page.

In particular, the lowercase replacement already exists. All that is needed is to use applicationname in your code where you do wish to see the lowercase version of the name.

Being able to use the sourceName as a variable is another question. We will discuss this with PM and see if we would like this as a feature.

@ardove sourceName is available in name symbol. The following change is needed to template.json:

{  
  "$schema": "http://json.schemastore.org/template",
  "author": "Blank",
  "classifications": [
    "Web",
    "WebAPI"
  ],
  "name": "Test",
  "identity": "Test.Casing",
  "shortName": "casing-test",
  "sourceName": "ApplicationName",
  "preferNameDirectory": true,
  "tags": {  
    "language": "C#"
  },
  "primaryOutputs": [
    {  
      "path": "ApplicationName.csproj"
    }
  ],
  "symbols": {
    "sourceNameLower": {
      "type": "generated",
      "generator": "casing",
      "parameters": {
        "source":"name",
        "toLower": true
      },
      "replaces": "ApplicationNameLower"
    }
  },
  "postActions": []
}

@vlada-shubina -- what version of .NET can we expect that fix in?

@ardove the configuration above works in dotnet 2.1 and 3.1.
Commit above is for documentation update and will be available in Wiki once reviewed.

@vlada-shubina -- that seems odd -- I just tried your suggested fix using the dotnet cli version 3.1.402 and it still reproduces the same issue.

@ardove could you please share the template configuration you are using? I can check it.

Below is the configuration that works for me on dotnet 3.1.402.
Test-Template-Source-Name-As-Symbol-Source.zip

@vlada-shubina apologies, it looks like I still had a bad template configuration and upon fixing that, it appears to be correct. thanks!

Was this page helpful?
0 / 5 - 0 ratings