templating icon indicating copy to clipboard operation
templating copied to clipboard

Add Licence dotnet new templates for e.g. Apache and MIT using the standard texts from GitHub?

Open DevTKSS opened this issue 5 months ago • 16 comments

Is your feature request related to a problem? Please describe.

I have to add License files only on github, would not know any options for doing this via CLI like we can for Directory.Package.props or editorconfig

Describe the solution you'd like.

Would be great if there would be dotnet new templates for the License.md files just like Github allows us to add online

Additional context

No response

DevTKSS avatar Jul 08 '25 14:07 DevTKSS

Sounds like a good idea, should consider the default name for the file, I think LICENSE.md is the standard and also matches README.md but this repo has https://github.com/dotnet/templating/blob/main/LICENSE.txt and the runtime repo has https://github.com/dotnet/runtime/blob/main/LICENSE.TXT. Even LICENSE.rst seems to be a thing https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository#determining-the-location-of-your-license.

Seems like the license picker when creating a new repo on GitHub.com has this instruction

In the file name field, type LICENSE or LICENSE.md (with all caps). https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository

So there it also proposes a file without a file extension.

So maybe the default should be LICENSE.md and I assume you would be able to choose the file name either way manually with the --name argument?

GitHub seems to recognize these license keywords https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository#searching-github-by-license-type that list is probably a good start for what to support but could also start out with just MIT or filter out some of the lesser used licenses and start with MIT, Apache-2.0, BSD-3-Clause?

Frulfump avatar Jul 08 '25 15:07 Frulfump

@Frulfump I would suggest the extension md, as Visual studio code for example as very basic coding environment does detect this and we could use markdownlint or cspell if someone wants to edit those files.

to stay close to available names, it would make sense to add it for this command:

dotnet new license

and as we know there are different contents, I am indeed not sure if the kind / type of the file we would get, should be or have a default value 🤔 the argument should be required in my opinion, just like it is when we using GitHub build in functionallity for it. Maybe there is a way to resemble their options and behavior for this?

DevTKSS avatar Jul 08 '25 18:07 DevTKSS

@Frulfump and as I were adding those type of files, I were also missing a Contributing template, which does not even Github provide any templates for.

This could be empty by default with maybe just a headline of # Contributing or we would assume the user could use docfx, it could have a yaml header with the git repo Name + .Contributing so it would be easy going to pull it into the documentation for example.

here would be cool if at least for OSS Repos there would be a option to get a standard text content that is commonly used. I did not explore very much, but as I requested Copilot using the vs code new / empty file ghost line commands, for "Add a commonly used Contributing Content assuming my project is licensed with Apache 2.0"

It came up with this:

# Contributing to DevTKSS.Uno.SampleApps

Thank you for your interest in contributing to this project! We welcome contributions from the community.

## Code of Conduct

Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) to foster a welcoming and respectful community.

## How to Contribute

1. **Fork the repository** and create your branch from `main`.
2. **Write clear, concise commit messages**.
3. **Test your changes** to ensure they work as expected.
4. **Submit a pull request** with a description of your changes.

## License

By contributing, you agree that your contributions will be licensed under the [Apache License 2.0](LICENSE.md).

## Reporting Issues

If you find a bug or have a feature request, please [open an issue](../../issues).

## Development Guidelines

- Follow Uno Platform best practices.
- Ensure code is clean, well-documented, and tested.
- Adhere to existing coding style and conventions.

Thank you for helping improve DevTKSS.Uno.SampleApps!

And in my opinion, thats a really nice content for this! Okay, beside the fact, that I am missing still the Code of conduct file it referenced - also for this, I would not know of an available template except from using github 🤔 The Guidelines reference to Uno I think it did take from the context, that this repo of mine is meant to provide Sample Apps and tutorials in e.g. german localization (theirs are and will be only english)

DevTKSS avatar Jul 08 '25 18:07 DevTKSS

@DevTKSS Yes adding the template with the short name license seems like a good idea e.g dotnet new license

The type of license it generates should probably require an explicit template option but the file name itself could have a default that could be overridden with --name (or something else like --license-filename if --name normally means something else) e.g dotnet new license --type MIT --name LICENSE.txt. (and just doing dotnet new license --type MIT would then create a LICENSE.md containing the MIT license)

➜ dotnet new globaljson --name foobar.txt The template "global.json file" was created successfully.

Creates a global.json file (strange that there isn't an error for the command)

➜ dotnet new --help ... Options: ... -n, --name The name for the output being created. If no name is specified, the name of the output directory is used. ...

➜ dotnet new class --name foobar The template "Class" was created successfully.

That creates a file foobar.cs

I think having CONTRIBUTING.md is of lesser value as the contents is more likely to vary whereas the license idea covers a set of known texts to add. The CONTRIBUTING and Code of Conduct creation idea is probably better served by another tool maybe you could use this? https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository. But should probably be discussed in its own issue to keep this focused on the license idea.

Frulfump avatar Jul 08 '25 18:07 Frulfump

for the naming of the license file, I am not sure, if it is common to have other names of this? But it could maybe replicate a similar behavior than the .editorconfig to editorconfig so the template could provide the extensions using its alias

DevTKSS avatar Jul 08 '25 18:07 DevTKSS

hm 😅 I am not so best friends with dotnet new globaljson or whatever its named. I did try once, but as Uno as my codebase is using a different content than the dotnet new tool provides, I commonly use their template provided one.

DevTKSS avatar Jul 08 '25 18:07 DevTKSS

for the naming of the license file, I am not sure, if it is common to have other names of this? But it could maybe replicate a similar behavior than the .editorconfig to editorconfig so the template could provide the extensions using its alias

Ah that's true I think it's rare to have another name or other casing than LICENSE, but I did a quick code search here on GitHub and found some cases of license.md though seems very rare and it seems GitHub respects it anyways. I guess one could limit the configuration to just the extension i.e --file-extension txt but that might be unnecessarily strict for some use cases. So to cover both bases --name would be optional and default to LICENSE and an optional --file-extension that would default to md, but that could maybe be considered unnecessary if the --name option already supports choosing an arbitrary filename and extension.

Frulfump avatar Jul 08 '25 19:07 Frulfump

Also needs to consider the options --copyright-holder / holder (required or default to $(git config user.name)?) and --copyright-year / year (default: current year, not sure how often you add a license for a different year than current tough?) at least for --type MIT https://opensource.org/license/mit as those are placeholders in the license. Haven't really looked at the others to see if they have other placeholders to consider.

Frulfump avatar Jul 08 '25 20:07 Frulfump

I think, the git repo we place it in, should know about the owner and maybe it can get this through that? otherwise what about checking for an appxmanifest since this would normally contain the owner information to use?

DevTKSS avatar Jul 08 '25 20:07 DevTKSS

For the year, I honestly would not know of one reason that would make sense to not be the current one. you can not really apply licenses for the future and if you use the last year, then you would need to update this right afterwards, so it would be up to date.

DevTKSS avatar Jul 08 '25 20:07 DevTKSS

I think, the git repo we place it in, should know about the owner and maybe it can get this through that? otherwise what about checking for an appxmanifest since this would normally contain the owner information to use?

The repo prior to having a license file has to some degree an unknown owner I think defaulting to $(git config user.name) is not perfect (will be empty string if you haven't configured it I think, so that could cause some issues as well if the implementation doesn't output a placeholder then, and if git doesn't exist it would also cause issues and not sure how to handle it from an implementation stand point). And if you create open source for someone else your git user name isn't what you want in the license file. so maybe the --copyright-holder / holder should be required to avoid guessing and complicating the implementation.

I think looking in appxmanifest is too much logic/too specialized for a simple template command. Not many repos have an appxmanifest.

For the year, I honestly would not know of one reason that would make sense to not be the current one. you can not really apply licenses for the future and if you use the last year, then you would need to update this right afterwards, so it would be up to date.

Yeah that's true. Maybe best to skip it initially and only add it if someone brings a good argument for its inclusion. Default to DateTime.Now.Year (intentionally not DateTime.UtcNow.Year so that it's actually the year of the local computer)

Frulfump avatar Jul 08 '25 21:07 Frulfump

@Frulfump yes, so year should be the year you would execute the command as simplest, the name should be optional to be set and behave just like GitHub uses to put in there. I think thats just empty? I as user would not assume a TEMPLATE to be a final result then a startpoint. So we should allow to provide the Name or company to use otherwise leave it open.

DevTKSS avatar Jul 10 '25 14:07 DevTKSS

@DevTKSS Yes sounds good! Yeah I think it would be empty then but maybe the LICENSE file should have a place holder in that case to make it clear where that info should go, but on the other hand you are likely to be aware of what owner should be set to when you run the command so not a bad idea to just enforce it imo (if you are unsure you can just write foo and that will serve as your own place holder).

Another thing to consider is if a new option should be provided when you use licenses like Apache-2.0 to output a file header you can manually add to your files as a convenience i.e --show-header-snippet (or some better name)

So it would work like this

dotnet new license --type Apache-2.0 --owner Contoso --show-header-snippet The template "LICENSE.md" was created successfully. Copyright (c) 2025 Contoso

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

https://www.apache.org/licenses/LICENSE-2.0#apply

Unclear from the docs if you must/MUST/should/SHOULD also have the LICENSE file as Apache-2.0 when only applying it to some files. (if not (maybe) the usage of the option --show-header-snippet shouldn't create the LICENSE file). The apply link says to include it in a license file and if you want to apply it to specific files you do

To apply the Apache License to specific files in your work, attach the following boilerplate declaration ...

But if you already have a LICENSE file all your files are under the license anyways and the header is redundant unless for legal reasons you must add it to all files but then you aren't applying the license to specific files since it's just blanket all files...urgh legal mumbo jumbo + docs written in a non-explicit way.

Not sure what they mean by

We also recommend that you include a file or class name and description of purpose on the same "printed page" as the copyright notice for easier identification within third-party archives.

Is "printed page" the file in which you add the header? I guess the template will not be able to accommodate this recommendation so maybe the recommendation itself should just be outputted then when using the --show-header-snippet or just link the license apply docs https://www.apache.org/licenses/LICENSE-2.0#apply and let the user of the command figure it out to avoid it looking like the dotnet new license command is giving recommendations. Or just skip that part?

Frulfump avatar Jul 10 '25 18:07 Frulfump

I don't know about this, but it would be maybe cool if there would be a option like --project that would allow us to add the appropriate include this license in that project tags in the csproj file or if that is possible (?) in some Directory.?.? File... I myself am still lost in a proper guide for setting the nuget / packaging informations. Seen on oss projects they are using nuspec files but to me its a bit difficult to understand the difference between dotnet nuget , dotnet package and nuget because last one keeps not getting detected as cmdlet

DevTKSS avatar Jul 11 '25 09:07 DevTKSS

For NuGet packages I use <PackageLicenseExpression>MIT</PackageLicenseExpression> and <None Include="LICENSE.md" Pack="true" Visible="false" PackagePath="/" /> <!-- Don't add as <PackageLicenseFile> as it's mutually exclusive with the <PackageLicenseExpression> and would cause NU5033 -->. I add them to the main .csproj I haven't considered if I should add it to my Directory.Build.Props file really but I think I don't want it there as I only package one main project.

So both of those would be interesting to consider.

Some (other) properties I set

<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>packageIcon.png</PackageIcon>
  <ItemGroup>
    <None Include="LICENSE.md" Pack="true" Visible="false" PackagePath="/" /> <!-- Don't add as <PackageLicenseFile> as it's mutually exclusive with the <PackageLicenseExpression> and would cause NU5033 -->
    <None Include="README.md" Pack="true" Visible="true" PackagePath="/" />
    <None Include="packageIcon.png" Pack="true" Visible="false" PackagePath="/" />
  </ItemGroup>

The Visible property just handles if the file should show up in the Visual Studio / VS Code C# DevKit / Rider solution explorer or not.

I myself am still lost in a proper guide for setting the nuget / packaging informations.

Yeah I can understand that it's not super clear, I haven't searched for info in that area in a long time. But I think a good place to ask a question for that info would be https://github.com/NuGet/Home/discussions/categories/q-a let me know if you open a discussion as I would be interested in following the conversation. Perhaps this guide helps a bit? https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package-dotnet-cli

I used nuspec files in the .NET Core 1/2 era but after tooling improved I didn't have to anymore and I consider them to be more for advanced scenarios these days so if you can manage with just properties in your .csproj / Directory.Build.props I would recommend that. There will be a generated nuspec file that you can inspect in the obj/[Debug][Release]/ folder.

One issue I ran into when using nuspec files was that some developers forgot to sync the version for dependencies in the .csproj with the dependencies in the nuspec. It was a long time ago (2017/2018) so could have been other issues as well.

to me its a bit difficult to understand the difference between dotnet nuget , dotnet package and nuget because last one keeps not getting detected as cmdlet

nuget not being detected as a cmdlet means you don't have nuget.exe separately available in your path i.e you haven't installed NuGet separatly and for the common cases I don't think you would need to https://learn.microsoft.com/en-us/nuget/install-nuget-client-tools?tabs=windows#feature-availability. The dotnet CLI comes packaged with NuGet by default and is why it's available via dotnet nuget.

https://learn.microsoft.com/en-us/nuget/install-nuget-client-tools

Image

both the commands dotnet pack and dotnet package exists but they handle different things so I think you meant dotnet pack

dotnet pack --help

➜ dotnet pack --help Description: .NET Core NuGet Package Packer

Usage: dotnet pack [<PROJECT | SOLUTION>...] [options]

Arguments: <PROJECT | SOLUTION> The project or solution file to operate on. If a file is not specified, the command will search the current directory for one.

Options: -o, --output <OUTPUT_DIR> The output directory to place built packages in. --artifacts-path <ARTIFACTS_DIR> The artifacts path. All output from the project, including build, publish, and pack output, will go in subfolders under the specified path. --no-build Do not build the project before packing. Implies --no-restore. --include-symbols Include packages with symbols in addition to regular packages in output directory. --include-source Include PDBs and source files. Source files go into the 'src' folder in the resulting nuget package. -s, --serviceable Set the serviceable flag in the package. See https://aka.ms/nupkgservicing for more information. --nologo Do not display the startup banner or the copyright message. --interactive Allows the command to stop and wait for user input or action (for example to complete authentication). [default: True] --no-restore Do not restore the project before building. -v, --verbosity <LEVEL> Set the MSBuild verbosity level. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]. --version-suffix <VERSION_SUFFIX> Set the value of the $(VersionSuffix) property to use when building the project. -c, --configuration <CONFIGURATION> The configuration to use for building the package. The default is 'Release'. --disable-build-servers Force the command to ignore any persistent build servers. --ucr, --use-current-runtime Use current runtime as the target runtime. -?, -h, --help Show command line help.

dotnet package --help

➜ dotnet package --help Description:

Usage: dotnet package [command] [options]

Options: -?, -h, --help Show command line help.

Commands: search <SearchTerm> Searches one or more package sources for packages that match a search term. If no sources are specified, all sources defined in the NuGet.Config are used. add <PACKAGE_ID> Add a NuGet package reference to the project. list List all package references of the project or solution. remove <PACKAGE_NAME> Remove a NuGet package reference from the project.

And as they recommend in the link https://learn.microsoft.com/en-us/nuget/install-nuget-client-tools, you can use this tool on Windows to inspect your NuGet package https://github.com/NuGetPackageExplorer/NuGetPackageExplorer "This application is an open-source standalone tool that lets you visually explore, create, and edit NuGet packages. It's helpful for many scenarios, such as making experimental changes to a package structure without rebuilding the package."

Frulfump avatar Jul 11 '25 10:07 Frulfump

@Frulfump wow, huge thank you! I will add it to my "lookup this" list for after returning from vaccation next week, to try it out on my own extensions project, where I was trying to use the packaging capability 👍 indeed the "duplicated command" thing was making me assume that might be the same but seems like not and requires some more lookup. 😄 I was thinking (but most likly thats not the case) that using the nuget CLI tool, would automatically publishe it to nuget gallery, while you will know, that even if you pack something, that does not automatically makes it publish able. also in case of using such tool in company environment would be absolutly crucial if that capability would not be there, so I think it will be of course absolutly possible this has been considered and implemented on that specialized tool already 😅 kind of ridiculos thinking that would not be the case.

to the tags to implement the files for packing license, you mentioned, I am a bit surprised, because I was already thinking, that including and visibility and duplicated reference of this files would be natural 😯 and yes I was indeed trying to add it with that "do not use that" tag I think 🤔 but no error so far, just many duplicated tags and the post build action setup in Directory.Build.props is... jeah lets say you see its done from a newbe ;) but therefore, I would suggest you will know this details and required settings for such license file template better than me. I just started with c# end of last year, so much possibilities to improve my knowledge!

Can I somehow assist you in adding this? Never done a template and the generator selector setup it seems to use most of the time is not really easy to understand 😅 but would be cool to know in the future.

DevTKSS avatar Jul 11 '25 12:07 DevTKSS