Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sourceName replacement ("." -> "_") #402

Closed
javitosanchez opened this issue Mar 3, 2017 · 12 comments
Closed

sourceName replacement ("." -> "_") #402

javitosanchez opened this issue Mar 3, 2017 · 12 comments
Assignees
Milestone

Comments

@javitosanchez
Copy link

I have a problem in the replacement you are doing in sourceName property. The "." replacement has been doing only inside files replacements (text), but not in file names.
My problem is that I'm using the sourceName to create a solution file:

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlankProject", "BlankProject\BlankProject.csproj", "{7CF740F7-735F-48EA-8B7B-3FFA4902371C}"

After generation (sourceName = 'Blank.Project') I get:

Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blank_Project", "Blank_Project\Blank_Project.csproj", "{7CF740F7-735F-48EA-8B7B-3FFA4902371C}"

but the folder & project file name is Blank.Project\Blank.Project.csproj

Is there a way to not have this replacement?

Thanks!!

@sayedihashimi
Copy link
Member

@javitosanchez can you change the source project name to include a "." to see if that fixes it? For example instead of the original project being named "BlankProject" try "Blank.Project" and then when creating the template try some different like "Contoso.Project".

@RobertVejvoda
Copy link

I'm having the same issue. Is it possible not to replace underscores? It's quite common to create projects called My.Company.Business.Web.
Thanks!

@javitosanchez
Copy link
Author

@sayedihashimi, your solution works, but, do you have plans to change this behavior? It's quite strange to force having a "." in our sources...

@sayedihashimi
Copy link
Member

@RobertVejvoda if you modify your original source project to have a . in the name I believe your scenario should work.

@javitosanchez

your solution works, but, do you have plans to change this behavior? It's quite strange to force having a "." in our sources...

You're not strictly required to modify your sources. It's possible to get the replacements to work w/o doing that but you would have to add a bunch of content into the template.json file. We have some special logic which determines how to translate the SourceName (namespace value) to the correct representation when it's transformed (i.e. replace special chars with _ or make all lowercase). It's a much harder task than it seems. To do that right we need a . in the value for SourceName. I think it's easier for template authors to just update project names to have a . (and I'll be including that info as a best practice in docs), but as I said it is possible to

@mlorbetske
Copy link
Contributor

This is due to a special behavior applied to the name parameter - it's the only parameter with multiple forms currently & unfortunately they're implicit and not overridable at the moment (but they will be when we address #141). This behavior should definitely be documented on the authoring section of the Wiki, but we'll start here:

Value forms (as a concept) take the value it replaces & applies a set of transforms to it. Those same transforms are applied to the user supplied value for the parameter and a mapping between the forms is established.

Ex.

For a "Replaces" value of "My.Application.0*" and a user supplied value of "My.App.1?", the following set of replacements is produced

Transform To Replace Replace With
(Identity) My.Application.0* My.App1?
Safe Filename My.Application.0_ My.App.1_
Safe Namespace My.Application._0_ My.App._1_
Safe Class Name My_Application__0_ My_App__1_

When any of the values in the To Replace column are found, they're replaced with the corresponding value from Replace With.

Let's take a look at what happens, if the values in the To Replace column aren't unique:

For a "Replaces" value of "BlankApp" and a user supplied value of "My.App.1?", the following set of replacements is produced

Transform To Replace Replace With
(Identity) BlankApp My.App1?
Safe Filename BlankApp My.App.1_
Safe Namespace BlankApp My.App._1_
Safe Class Name BlankApp My_App__1_

To make this case deterministic (and give the highest odds of successful generation), the replacement that ends up happening (for a set of replacements that would replace the same value) is the one that was specified last, in this case, it's:

Safe Class Name BlankApp My_App__1_

To relate this back to the issue at hand - sourceName is the value that gets plugged in to replaces on a special (hidden) parameter that gets bound to the user supplied name. This parameter has transforms similar to the previously mentioned ones applied to it (how it works specifically is here).

Unfortunately, this one's kind of by design with the Runnable Project Generator - to keep the project (or content, generally) that's being treated as a template in as close to running shape as possible, we need to infer what the right thing to do in each situation is. There are other ways we could have approached this (like requiring that each place the name could be used, it'd be surrounded by a comment indicating which form to replace it with - or not dealing with name forms at all, forcing each difference to be a fundamentally different string and requiring the configuration to be added to generate the appropriate replacement for each one of those strings (equivalent to how other template engines have approached the problem)), but all of the other options we came up with seemed to either violate the design of not requiring specific tokenization that breaks the content or was overly intrusive and not guaranteed to actually be supported by the content (surrounding usages with metadata).

When we start in earnest on #141, we'll be looking at the following scenarios very hard

  • Getting the behaviors that come in normally with name to be overridable
  • Making sure that all of the knobs that can be turned for other values with multiple forms are exposed

We're also thinking about what it might look like to specify forms that are particular to a certain file pattern (which would also work in the exact scenario mentioned - and address #368, possibly #381 too)

@mrahhal
Copy link

mrahhal commented Mar 26, 2017

I think it's easier for template authors to just update project names to have a .

@sayedihashimi when you're creating a generic template for a whole solution this doesn't make sense at all. As an example, I'm creating a template that has:

MyTemplate
|-- MyTemplate.sln
|-- src
|    +-- MyTemplate
|         +-- MyTemplate.csproj
|-- test
|    +-- MyTemplate.Tests
|        +-- MyTemplate.Tests.csproj

A user of this template might be creating a package named MR.AspNetCore.ApiVersioning. I - as a template author - can't include dots to satisfy all the different naming strategies.

@mlorbetske
Copy link
Contributor

@mrahhal could you elaborate on this? Isn't it just changing what you're calling "MyTemplate" to be something more verbose (or even just throwing in a dot between "My" and "Template"):

My.Template
|-- My.Template.sln
|-- src
|    +-- My.Template
|         +-- My.Template.csproj
|-- test
|    +-- My.Template.Tests
|        +-- My.Template.Tests.csproj

The number of dots or special characters doesn't matter - it's essentially just a key for pattern matching. Ex. if you have a template with a name of My.Template and My_Template is found somewhere in the source text, per the grid above, it'll treat this as something to replace using the class name replacement. If it finds My.Template in text, it'll treat it as something to replace with the namespace replacement, if it finds My.Template in a filename, it'll treat it as something to replace using the filename replacement.

@mrahhal
Copy link

mrahhal commented Mar 27, 2017

@mlorbetske didn't know including a single dot would enable this to work with all cases. Thanks!

@mlorbetske
Copy link
Contributor

With #561 merged, the remaining work here is to allow the overriding of the forms of the implicit name parameter by specifying it in config (already can be done) and setting the value forms for it explicitly.

@mlorbetske
Copy link
Contributor

#867 has the other piece to this

@mlorbetske mlorbetske modified the milestones: Backlog, 15.3-preview3 Jul 17, 2017
@mlorbetske
Copy link
Contributor

It looks like the referenced PR has been merged, please reopen if this is still an issue

@kristianmandrup
Copy link

Please have the CLI respond with a warning when passing in a name that is not in .NET class name format (ie. camelcase with first letter uppercase). Alternatively have it automatically convert any name passed as project name to a valid name. Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants