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

Example / standard template organization #2

Closed
RamblingCookieMonster opened this issue May 17, 2016 · 14 comments
Closed

Example / standard template organization #2

RamblingCookieMonster opened this issue May 17, 2016 · 14 comments

Comments

@RamblingCookieMonster
Copy link

RamblingCookieMonster commented May 17, 2016

Hi!

This might seem superficial at first glance, but given that end users may end up using examples / typical module templates the most, it might be worth some extra thought on their organization.

Two initial thoughts:

  • Consider a separate module folder. Given that many CI/CD solutions like you to dump configuration files in the root of a repo, IMHO it would be a better practice to have an independent YourModuleName folder under the root folder, specifically for module content.
  • Tests are awesome to have available, but IMHO should not be included with a typical download. It might be handy to leave these outside of the aforementioned YourModuleName subfolder, and have a Tests folder in the root. This way you could still distribute tests via github, without packaging them up, or having to write logic to avoid packaging them up.

Those are the biggest that stand out - love the idea of the tool, thanks for putting this together!

Cheers!

@rkeithhill
Copy link
Collaborator

Hey, thanks for checking out what we've got at this stage with Plaster! We are still early enough in development (almost prototyping really) that I don't want to focus too much on what this particular example generates. It is meant just to show what is possible and hopefully a typical use case. The content of this template will surely change before Plaster is done.

Right now we want to make sure that A) we have a manifest format that will allow you to scaffold what you want (create your own templates) and B) we have a manifest format that is safe from script injection attacks. After that we will want to make sure we have certain features like "default value" storage so I don't have to keep specifying my "full name" over and over. :-) Then we will want to think about working with ZIP'd versions of the template (ala nukpkg) and how we might distribute template pkgs. Then there is integration with VSCode. And then finally, what do some of the "built-in" template pkgs look like - if we even provide any built-in templates.

WRT test, the size of the test artifacts in this particular example is tiny. There is only one test to verify the manifest is valid. So I don't think template pkg size should be an issue. Also, the user can elect not to have the test scaffolded. When the template is invoked it prompts you:

15> Invoke-Plaster -TemplatePath . -Destination ..\Out -ModuleName FooUtils -Version 1.1.1
Enter your fullname (): Keith Hill
Select desired options
[P] Pester test support
[S] PSake build script
[G] Git
[?] Help
(default choices are P,S,G)
Choice[0]:
Which editor do you use
[I] ISE  [V] Visual Studio Code  [N] None  [?] Help (default is "N"): V
Select a license for your module
[A] Apache  [M] MIT  [N] None  [?] Help (default is "N"):

You can elect to pick all, some or none of Git, PSake and Pester. Note: this example is missing the None choice for "options". :-)

@gerane
Copy link
Contributor

gerane commented May 20, 2016

I was working on making a custom template for something other than a module, but it's not really practical until the zip/folder support is added. The one I was working on had likely 50+ individual files I would need to manually add 1 by 1.

II also felt you should give the option to tie the Root directory name to the name of the project. That way you don't have to enter the same name twice.

@rkeithhill
Copy link
Collaborator

rkeithhill commented May 21, 2016

IMHO it would be a better practice to have an independent YourModuleName folder under the root folder, specifically for module content.

@gerane Can you clarify if this is for the template directory structure or the directory structure that gets created by the invoked template? If it is the latter you have control over what gets created. And you can use the template's ${PLASTER_PARAM_ModuleName} parameter value to name a subdir.

One thing I have been thinking of providing is pre-defined variable(s) for the DestinationPath the user provides when invoking the template. Perhaps $PLASTER_DestinationPath and $PLASTER_DestinationName.

In general I've viewed this process as - the user tells the template author under what dir (creating it if necessary) they want the template to scaffold its stuff and then the template is free to create whatever file/folders under this dir that it needs to.

@RamblingCookieMonster
Copy link
Author

RamblingCookieMonster commented Jul 21, 2016

Hi all!

I hear a release or pre-release might be coming!

Just wanted to ping you on this - there's a good chance that the default example used in Plaster will become canon, or at least will be used by a good number of folks, given that it's from the PowerShell team (and community).

I might be slightly biased, but I think it would be worth re-considering the example template organization. I tend to lean towards nesting a module outside of all the scaffolding cruft (some details here).

Having a README, LICENSE, gitignore, Tests (this might be okay, some prefer it in the module folder, I do not), build.ps1, psake.ps1, etc. all in the root makes things quite messy and difficult to work with.

I'm not particularly tied to that exact layout, as long as an alternative helps keep things clean and readable. I can live with it if no changes are made, just figured it would be worth pinging you one more time before this becomes more "official" : )

Cheers!

@rkeithhill
Copy link
Collaborator

lean towards nesting a module outside of all the scaffolding cruft

Not sure what you mean by "nesting" here. Are you talking about simply separating the "shipped" module contents from the "infrastructure"?

build.ps1, psake.ps1, etc. all in the root makes things quite messy

I dunno. I kind of appreciate a Git repo with a build.bat or build.ps1 in its root so I can easily build whatever the repo has to build. :-) As for README and LICENSE, I think that is very common on GitHub at least to put in the root folder.

We could stick all the module stuff into a subfolder like <module-name> but a lot of modules are really simple - like foo.psd1 and foo.psm1 and you're done. A New Module Template for VSCode IMO should cater to the common case and not get too opinionated. Although I do recognize there is room for encouraging good structure.

BTW there can be other templates e.g. perhaps a New Module Template - Advanced or New PSGallery Module Template. When I look at Visual Studio there isn't a single New Project Wizard. You select the type of project first (Console, Library, WPF App, Web App, etc). This results in a wizard that is much more focused.

In your case, we "could" handle this a single template with lots of options that generates the appropriate artifacts based on how the user responds to template prompts. That said, if the common case is two files I don't want the user to have to answer a bunch of prompts that don't apply - every single time they use the template.

I think this will be a balancing act but I don't have a good feel yet for when you should create a new template. I'm spit balling here but I'd say we'd like to keep the template prompts down to <= 6?? If a template needs more than that, perhaps it should be broken up into separate templates.

@RamblingCookieMonster
Copy link
Author

RamblingCookieMonster commented Jul 21, 2016

Hi Keith!

Apologies if it wasn't clear - like you mentioned, a subfolder with the module name is what I was aiming for. Even for a simple module, things will start to get confusing for new folks. Here's a quick example for a PSStackExchange module. I personally much, much prefer the latter.

Current state:

  • PSStackExchange (Repo and module root folder)
    • Tests (folder)
    • build.ps1
    • LICENSE
    • psake.ps1
    • PSStackExchange.psd1
    • PSStackExchange.psm1
    • README.md

Proposed alternative:

  • PSStackExchange (Repo root folder)
    • PSStackExchange (Module root folder)
      • PSStackExchange.psd1
      • PSStackExchange.psm1
    • Tests (folder)
    • build.ps1
    • LICENSE
    • psake.ps1
    • README.md

This makes it abundantly clear that if you are in the module folder, you are working with module-related-files, and if you're in the root folder, you're working with repo-and-related-systems-files (scaffolding).

IMHO if you're going to have any scaffolding (readme, license, build, psake, etc.), the former (current) organization is cluttered, and should never be used. This could be me being finicky, I just find it difficult to parse through things, vs. having clear cut separation.

Good point on multiple templates. That would certainly make sense and could address this : )

Cheers!

@rkeithhill
Copy link
Collaborator

I'm leaning in this direction. I could see using a generic Module folder or Src (kind matches nicely with Tests) or <module-name>. The one advantage of using <module-name> is that you could publish directly from there. However, I still like the idea of have a Release folder where you can prepare your module for publishing. For instance, if you sign your scripts you want to do that before publishing (not on the original source files). So with this in mind, I think Src could be just fine. Thoughts?

@RamblingCookieMonster
Copy link
Author

RamblingCookieMonster commented Jul 24, 2016

Either works for me - personally I stick to ModuleName for simplicity, but I could see how src might clarify content in cases where you also have a release folder, if that's a common or desirable scenario.

May as well ping some other module authors: cc @dlwyatt @Jaykul @proxb @KirkMunro @dfinke @devblackops @gerane (Apologies for everyone I left out, didn't want to spam the whole community : P)

Cheers!

@dlwyatt
Copy link
Member

dlwyatt commented Jul 24, 2016

Don't use me as an example. :P (See: https://github.com/dlwyatt/ProtectedData ). I write build scripts that leave out all the non-essential stuff when it's published, but the repo is just one big folder full of stuff.

@rkeithhill
Copy link
Collaborator

What right we currently have is a Build.ps1 script that is a PSake script. I kind of like your convention of Build.Psake.ps1. That could leave a Build.ps1 that simply imports Psake and runs it against Build.Psake.ps1. So for the Psake uninitiated, they could just execute .\Build.ps1 have the module do a basic build (but not publish).

@RamblingCookieMonster
Copy link
Author

Yep, that's a handy process, use something similar as well, pulling down psake if it doesn't exist.

@dlwyatt: figured I'd ping folks on both sides : )

@devblackops
Copy link
Collaborator

devblackops commented Jul 24, 2016

I agree with @RamblingCookieMonster. Keeping files related to the repository separate from files related to the module makes things easier. Especially as you start authoring more advanced modules. The current project I'm working on Watchmen has 12 files (build.ps1, psake.ps1, README.md, etc) at the repository root that are not directly related to the actual PowerShell module. IMHO having all those files and the PS module itself at the same level is messy.

  • ModuleName\
    • Docs\
    • ModuleName\
      • Public\
      • Private\
      • en-US\
        • about_modulename.help.txt
        • modulename-help.xml
      • ModuleName.psd1
      • ModuleName.psm1
    • Tests\
    • .gitignore
    • CHANGELOG.md
    • CONTRIBUTING.md
    • ISSUE_TEMPLATE.md
    • LICENSE
    • PULL_REQUEST_TEMPLATE.md
    • README.md
    • appveyor.yml
    • build.ps1
    • mkdocs.yml
    • module.psdeploy.pd1
    • psake.ps1

I also like having build.ps1 be your entry point into executing all your psake tasks. I have build.ps1 execute the default psake task unless the user specifies another task to execute via the -Task parameter. This way any action related to the repository (Pester, Script Analyzer, module help generation, module deployment, etc) is executed via build.ps1 and the appropriate task name.

@Jaykul
Copy link

Jaykul commented Jul 25, 2016

I agree in principle with what devblackops wrote there, except that I generally name the folder "src"

  1. For projects on github, a "Source" or "src" folder is more common, obvious and cross-language
  2. For anything we're cloning from git, it's less recursive, since when people git clone https://github.com/Author/ModuleName.git you're going to end up with a ModuleName\ModuleName (not ModuleNameRoot\ModuleName)

For what it's worth, I always add my "projects" folder to my module path, and I build into folders with version numbers so I can import-module by name the module output:

  • C:\Users\Joel\Projects
    • ModuleName git root
      • 1.0.0
      • 1.0.1
      • ...
      • Tests
      • src
        • Private
        • Public
        • ....

If I have a C# project, then it's there in parallel to the "src" folder.
If I have nuget packages, the packages folder would be there too.
If I have other linked git sub-repos, I put them in a lib folder there too

@rkeithhill
Copy link
Collaborator

I think the current NewModule template scaffolds files and folders in a way most folks here can live with. It keeps the "shipped" module files separate from the infrastructure files for build, test, script analyzer settings, license, etc.

schittli pushed a commit to schittli/Plaster that referenced this issue Mar 29, 2018
…the template full FileName which is used to create a File

Example of use:
# Used Template: <%=$PLASTER_TemplateSource%>
Will get the full Template name:
# Used Template PowerShellOrg#2: C:\…\scaffold\Build.template
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

6 participants