fermyon / spin-dotnet-sdk

Apache License 2.0
43 stars 11 forks source link

Using `-` slash as the name for the http-chsarp template generates invalid c-sharp namespace name #36

Closed mikkelhegn closed 1 year ago

mikkelhegn commented 2 years ago
🐟 > spin new http-csharp cloud-c-sharp
Project description:
HTTP base: /
HTTP path: /...

spin build generates the following error:

/Users/mikkel/code/cloud-c-sharp/Handler.cs(3,17): error CS0116: A namespace cannot directly contain members such as fields, methods or statements [/Users/mikkel/code/cloud-c-sharp/Project.csproj]

Content of Handler.cs

using Fermyon.Spin.Sdk;

namespace cloud-c-sharp;

public static class Handler
{
    [HttpHandler]
    public static HttpResponse HandleHttpRequest(HttpRequest request)
    {
        return new HttpResponse
        {
            StatusCode = System.Net.HttpStatusCode.OK,
            Headers = new Dictionary<string, string>
            {
                { "Content-Type", "text/plain" },
            },
            BodyAsString = "Hello from .NET\n",
        };
    }
}
itowlson commented 2 years ago

Thanks - the template needs to convert that to CloudCSharp or something like that.

itowlson commented 2 years ago

Okay, looking at this, we don't currently perform any transformation on the project name to get the namespace statement - we are not kebab-casing it or anything. The reason for this is that if someone chooses a project name such as Fermyon.CSharpDemo (which is a legal and idiomatic .NET project name), that's a legal and idiomatic namespace name. We would not want to convert that to PascalCase, as this would lose the dotted nesting.

A name like c-sharp-demo is not one I'd expect a .NET programmer to normally enter. But it's certainly plausible that someone might do it for a throwaway project (as you did). And it would be good not to break in this case.

But the only way I think we can achieve this is to teach the template system a new text transformation, a sort of "pascal case but preserving dots". Which is quite specific to .NET, and doesn't exist in the templates engine at the moment.

We also don't have validation on the project name since we moved it out of the parameters and into the CLI. So we can't even reject the project name as un-namespace-like. So there are various things we can do"

  1. Tell people do use .NET conventions for project names.
  2. Add the ".NET-like" transformation to the templates engine.
  3. Add template-controlled name validation (e.g. regex) to the templates engine.
  4. Provide a way for templates to define custom transformations.

Of these, all except 1 would require a release of Spin - they can't be accomplished in the .NET template alone.

radu-matei commented 2 years ago

I can confirm that I bumped into this while making a throw-away sample application. The issue was identifiable rather easily, but the experience was not ideal.

itowlson commented 2 years ago

I started noodling on this; thanks for the confirmation case!