Git Product home page Git Product logo

modulebuilder's Introduction

PoshCode Package Manager Module (BETA)

PoshCode's purpose is to make it easier to distribute PowerShell modules and scripts over the internet or within local and corporate networks.

With this new project we are focusing on making it easy to distribute modules without explaining module installation to your users.

Additionally, we're supporting the automatic installation of dependencies, so that you can distribute modules which have a dependency on other modules without having to worry about how your users will find and install them.

The module has two main commands for users, and a third for module developers:

  1. Find-Module searches configured module registries and repositories
  2. Install-Module installs modules from local packages (.nupkg or .zip files), or from URLs or UNC paths
  3. Compress-Module creates a redistributable module package from a module on your system

To install the PoshCode module

If your "WebClient" service is running (this is Window's built-in WebDAV client), you can install it straight from our server with a single command in any version of PowerShell:

    \\PoshCode.org\DavWWWRoot\Modules\Install.ps1

If you have problems with that (various things can make Windows WebDAV slow, and the service doesn't seem to be installed by default on server OSes), you will need to download and run our Install.ps1 script. Of course, you can still do that from PowerShell:

On PowerShell 3 and up you can do that using Invoke-WebRequest:

    # First download, then run, then delete the installer:
    iwr http://PoshCode.org/i -OutF PC.ps1; .\PC; rm .\PC.ps1

On PowerShell 2 you need to create and use a WebClient:

    (New-Object System.Net.WebClient).DownloadFile("http://poshcode.org/i","$pwd\pc.ps1"); .\PC; rm .\PC.ps1

The rest of the documentation will be in the wiki, broken into several sections:

  1. Installing Modules (user's guide)
  2. Creating Module Packages
  3. Distributing Module Packages (should include the "how to" for enterprise users)
  4. Additional Features of PoshCode (everything else)

Note: the additional features of PoshCode include coverages of some of the mini modules I wrote to support the Package Manager functionality, mostly around Serialization and Configuration.

modulebuilder's People

Contributors

bravo-kernel avatar disco0 avatar gaelcolas avatar hobadee avatar jaykul avatar johlju avatar jrich523 avatar kilasuit avatar lipkau avatar techdufus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

modulebuilder's Issues

Build-Module always build in a versioned directory

It seems that Build-Module always build in a version sub directory, even when setting $VersionedOutputDirectoryto$false`:

Build-Module .\Source\build.psd1 -OutputDirectory output\ModuleBuilder -VersionedOutputDirectory:$false

Is it worth implementing that choice (I know it's not difficult), or should we remove the option altogether?

use #Region keyword

As a VS, Code or ISE user
In order to improve productivity when working with output
I need to be able to collapse per-file content


Replace the # BEGIN and # END text with #REGION SOURCE: and #ENDREGION SOURCE:

Using #REGION would provide some utility to anyone who opens the output file in an editor, but would not change our ability to extract information (decompile or lookup). However, we need a second magic keyword to make sure we aren't confused by the possible use of normal regions within the source.

Important: this requires changes to Build-Module and also Convert-CodeCoverage -- and any other potential line-conversion functions.

We need a ConvertLineNumber function based on lines 43 and 56 of the Convert-CodeCoverage function --- we're going to need the same logic for converting error message stack traces, etc. Just make sure not to loose the ability to cache the source data, even if that means storing it temporarily in a $Script: scope variable.

Build-Module makes use of Configuration module but build.ps1 doesn't install it.

When trying to build the latest version of ModuleBuilder I discovered that I was getting now functions exported in the psd1. Digging into Build-Module it makes use of Update-MetaData from the Configuration module which I didn't have installed, somehow this wasn't causing an error.

build.ps1 has a section for installing dependencies but nothing is listed there, Configuration should be and we should probably be using PSDepend to manage these as mentioned in the ReadMe.

I'll try to put together a PR for this in the next few days.

Keep relative path to ExternalHelp

If a module uses external help (maml) (eg: with platyPS), powershell v3 requires the functions to have a CBH with

.EXTERNALHELP <path to -help.xml>

in a setup where the functions are not in the same folder as the modules .psd1 file, the path must be relative to the function (ie: .EXTERNALHELP ..\JiraPS-help.xml)
when "compiling" the functions into the .psm1 file, this relative path is influenced and must be fixed (ie: .EXTERNALHELP JiraPS-help.xml)

Adding option for parsing public Functions and Aliases

First off, I realize that this might be a highly opinionated subject and don't mind to be told that I'm wrong.

Today, Build-Module reads the BaseName of files matching $PublicFilter to populate FunctionsToExport, which works well enough unless you misspell a file or want to have more than one function per file. My main problem is that this method won't export any aliases for commands, meaning that I will have to either set AliasesToExport to '*' which is bad for performance or parse my aliases in a post-build task.

I would like to add an option to use AST to get all functions and aliases from all files matching $PublicFilter. This option could be enabled by a swich parameter $UseAST. I am aware that this will have an impact on build performance. In my testing on a small module with ~20 public functions, this change takes the build time from ~0.35seconds to ~0.7 seconds, an impact I'm gladly willing to endure to get Aliases parsed for me.

Would a PR for this be of interest?

[FP] New-ModuleSkeleton

As a possible approach for PotentialContribution/ModuleCreation I have created a working demo branch that generates a fresh module following ModuleBuilder best practices.

The code is obviously just to make things work. If desired I could go forth and create a proper PR to get things started for real. Motivation bulleted in the code New-ModuleSkeleton source. The intended 30-second-up-and-running user story would be something like:

  1. install ModuleBuilder
  2. run New-ModuleSkeleton -Name MyNewModule
  3. cd MyNewModule
  4. build
  5. Get-HelloMyNewModule (optional)

Also:

  • commit ready
  • azure pipelines ready
  • pester ready

Please let me know

Version 1.5.2 doesn't copy in the prefix file

I have this build.psd1 file:

@{
    ModuleManifest = "ModuleName.psd1"
    CopyDirectories = @("Formats", "Lib")
    Target = "CleanBuild"
    Prefix = "./Prefix.ps1"
    Suffix = "./Suffix.ps1"
}

When I run Build-Module .\build.psd1 the contents of the prefix file are not copied in to the resulting psm1 file, but the suffix is included.

I verified that this works if I load the v1.0.0 module.

Bootstrap script - requiredversion

In the RequiredModules.psd1 the requiredversion is used to get the 'correct' PowerShell Modules installed. I already have some newer module versions installed on my system.

Would it be an idea to use minimumversion?

The build.ps1 script does not specially imports the PowerShell Module version configured in the RequiredModules.psd1 if I'm correct.

Bootstrap Module build with Build.ps1 Script

For any PS Module project using ModuleBuilder, there will be a minimum code to be included in those repo to bootstrap the build process, namely the Build.ps1 entry point.

It will have to at least:

  • Boostrap the project by downloading dependencies such as ModuleBuilder if not already avail
  • call Build-Module

That open the discussion to the following questions:

  1. Shall we include a sample/re-usable version in ModuleBuilder, so that it can be used as part of a template?
  2. How do we make the Build.ps1 bootstrap process?
Save-Module ModuleBuilder
# Pull dependencies with PSDepend
Build-Module

Do we make a ModuleBuilder function call Invoke-PSDepend (in which case, do we make PSDepend a dependency of ModuleBuilder)?
3. Do we allow to change the PSModulePath as per #10
4. Do we make Build.ps1 also read the Build.psd1 so that Configuration data (such as which Source to pull ModuleBuilder from during bootstrap)?
5. How do we customize the Build workflow (the steps to be called). Do we do this within Build.ps1, in external Data File? How do we manage the Interfaces for Build Steps (function signatures & Params)?

I need to refresh/refactor my SampleModule template, and I'd rather contribute to ModuleBuilder going forward but need 'guidance' as to how you envision solving those issues before I start submitting PRs.

Extract the actual compile step

As a ModuleBuilder contributor
In order to improve code quality
I need testable code


There are still a few pieces in build-module that need to come out for testability, in particular the begin/process/end block which actually compiles a list of ps1 files into a single psm1 file. i.e. lines 185-226 of Build-Module.ps1.

There are other pieces that could come out too, but this one would be significant in making testing easier.

Given this creates something like a CompileSource private function, we may want a matching DecompileSource ...

SourceDirectories can't be changed in build.ps1

When I change the default SourceDirectories list in build.ps1:
@{ SourceDirectories = @("Private", "Public", "Data") }

It doesn't work. Still uses the default value from ModuleBuilder.ps1 ("Enum", "Classes", "Private", "Public").

I found that using $ModuleInfo.SourceDirectories instead of $SourceDirectories in line 659 in ModuleBuilder.ps1 like this:
$AllScripts = Get-ChildItem -Path @($ModuleInfo.SourceDirectories).ForEach{ Join-Path $ModuleInfo.ModuleBase $_ } -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue
instead of
$AllScripts = Get-ChildItem -Path $SourceDirectories.ForEach{ Join-Path $ModuleInfo.ModuleBase $_ } -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue
solves the problem.

I'm just not sure if I'm doing this right... If that's ok, I can contribute and create a pull request.

bootstrap.ps1 error

bootstrap.ps1 causes the following error:

Install-Module : Cannot validate argument on parameter 'MaximumVersion'. The argument is null. Provide a valid value
for the argument, and then try running the command again.

It is because the cast to [ModuleSpecification[]] of the RequiredModules, creates empty properties for Version, MaximumVersion, and Guid

-Prefix or -Suffix dot not throw an exception when a file do not exist

With this setting:

@{
    Path = "MyModule.psd1"
    OutputDirectory = "C:\temp\Delivery\MyModule"
    VersionedOutputDirectory = $true
    CopyDirectories=@('.\Demos','.\fr-FR','.\TypeData')
    Prefix='.\Initialzation.ps1' 
    Suffix='.\Finalization.ps1'
}     

If the file does not exist, no errors are triggered:
image

If I correct the file name, the addition is done correctly :
image

The error exists but is not displayed :
image
Same behavior with Suffix :
image

Add a -CoverageFile for Convert-CodeCoverage

As a module author
In order to understand my code coverage
I need to use CodeCov.io and other such tools


Basically I just want to overwrite Pester's coverage file with one based on the modified output of Convert-CodeCoverage. If that's already possible by piping this to some Pester functions, can you put an example of how to do it in the help for Convert-CodeCoverage so others can figure out how -- or better yet, just add a parameter and do it yourself...

Add an exclude list for Clean

When you Target Clean, sometimes (as per #10 for instance), you want to not clean some subfolders from the Output directory.
Are you happy with adding an ExcludeFoldersFromClean parameter?
Do you have a better name for it, pretty please?

[discussion] Install-RequiredModule design question

Hi,
Great work on the Install-RequiredModule script. I'm late to the party, but I have a few questions:

  1. PSGallery Release shows v3.0.0 but this repo shows only v2.0.1. Am I missing something (I don't want to look at the wrong code)

  2. Save-script -Name Install-RequiredModule -path . also downloads PowerShellGet & PackageManagement. Is there a way to turn that off? Is that 'magic' from the #Requires? The problem is that I don't want to download those modules to . or even the same path used by RequiredModules (because DSC and multiple versions problem). I know I could use yet another folder for -Path but wondering if we want to download that to the repo's root anyway...?

  3. This script does not support Pre-release version (on a per module option), how much of a pain would that be to add? How would you suggest I try to implement that feature?

  4. This does not support Proxy/Auth and PSGallery (I saw the TODO), so it's likely to be of limited use within restricted environments with private galleries.

  5. Should -Scope be in a different parameter set than -Destination?

  6. Is the Wait-Debugger line 276 (I think) is meant to stay?

  7. I know you hate this, but are you not re-writing PSDepend? Or is it PowerShellGet? Worth putting in a module? Not that it's a bad thing, just asking :) At least, please consider putting this file in its own repo?

Let me know if you want me to file separate issues for any of those points. I'm happy to send PRs when time permits, but I want to make sure I'm not wasting time going against your intent.

Values in build.psd1 should override defaults

The expected result is that values should be used in order:

  1. Actual values provided at the command-line always win
  2. The values in build.psd1 override the
  3. Default values on Build-Module

Perhaps we should not have the default parameter values in Build-Module, and instead set those as fallback values during initialization after we read build.psd1 ...

Please document dependency on gitversion

the bootstrap build.ps1 file uses something called gitversion which is not listed in RequiredModules and I have no idea what it is or how to get it.

I'm aware of the gitversion project but this gitversion uses Powershell style parameter passing but doesn't follow Powershell cmdlet naming functions, and also I can't find any reference to a showvariable parameter in the gitversion documentation. I also can't find anything in the powershell gallery related to gitversion. Looking through the sourcecode of gitversion there does appear to be a /showvariable parameter but it also requires /output json which isn't being specified here so I don't think this is just merely the gitversion executable.

And IF IT IS just the gitversion executable, that needs to be called out in the documentation.

Edit-Code isn't working with my git config

When I run edit my choice of VS Code Insiders is not being picked up properly by Find-Editor with the -n -w parameters that I have added to git config:

To reproduce, import EditFunction.psm1 from the PotentialContribution folder and run:

git config core.editor "code-insiders -n -w"
Edit-Code prompt -Verbose

Although it does find code-insiders, it doesn't find it from the git config as documented, so it's missing the -n -w

Question about Modules with .Net Assemblies

Is there any support or guidance for modules with dependent .Net assemblies? For instance, I have a module with a .Net Core project and PowerShell module content, and these need to be compiled together.

Alternatively, would it be better to have a dotnet build step prior to invoking Build-Module?

Thanks!

ModuleName in OutputDirectory

When I'm building multiple modules on a build server, and need to force them all to go in a specific output folder. I want:

$(Build.BinariesDirectory)\ModuleOne\1.0.4\ModuleOne.psm1
$(Build.BinariesDirectory)\ModuleTwo\2.3.0\ModuleTwo.psm1
$(Build.BinariesDirectory)\ModuleThree\8.1.1\ModuleThree.psm1

So I would like to specify:

Build-Module ... -Destination "$(Build.BinariesDirectory)" -NamedOutputDirectory -VersionedOutputDirectory

And have Build-Module automatically do [IO.Path]::FileNameWithoutExtension( on the Path parameter (after reading build.psd1) and guarantee that the actual OutputDirectory either already ends with that or if not, add that before adding the version.

Write a guide: Git Flow for Contributors

We need one of these for git flow, showing the happy path for new contributors.

Unlike every other git flow document on the internet, it should not mention releases or hotfixes, but instead document a process exactly the same as github flow, except working against the "develop" branch instead of "master" and changing the ProTip on the first page to explain that you're contributing to the development branch because the master branch represents already released content.

Automatic alias exports fail when there's more than one on a function

When I have a public function like:

function Set-Source {
    [CmdletBinding()]
    [Alias("ss", "ssou")]
    param()
}

Unless it's the only function that's exporting aliases, it breaks the module manifest. It outputs the aliases for that command as "System.String[]" which not only doesn't export the alias, but interferes with PowerShell parsing the manifest properly (because [] is seen as an invalid wildcard range), so the module won't import and Get-Module -ListAvailable reports partial information about it.

Bootstrap discussion - Install vs Save module

Not an issue, just a discussion to see what you have in mind.

I find that installing modules, even in the CurrentUser scope, leads to annoying issues. As an example, the -SkipPublisherCheck and -AllowClobber issues when trying to build ModuleBuilder on a vanilla Windows 10 machine. Package management is another problem, by default you get 1.0.0.1 which is not great and creates some problems (I think with PSDepend, iirc, not even mentioning DSC).

I also find it easier when all dependencies are only local to the project (in the output folder), so that you have less variables from environment to environment (i.e. DEV box to CI agent), and thus for troubleshooting. I even usually go the extra mile to change the $PSModulePath to $PSHome plus the downloaded dependencies, to limit where modules are loaded from. When you have DSC managing systems it's hard to be sure what's available and can change from one run to another.

Most of this would be dealt by PSDepend by adding a target = ".\Output\modules" or similar in the options, but we'd probably need to also enable this for the bootstrap script (which I'll open a separate issue for).
We'd also have to change the $Env:PSModulePath to, at least, add the resolved path where dependencies are downloaded.
This should probably be optional, and could be handled by a parameter, and set in the Build.psd1.

Would you consider this option? What do you think?


Error building ModuleBuilder on (almost) vanilla Windows 10, PS 5.1.

PS C:\src\ModuleBuilder> .\build.ps1 -Verbose
VERBOSE: BUILDING ModuleBuilder VERSION 1.0.0
VERBOSE: Bootstrap hack for building ModuleBuilder with ModuleBuilder
WARNING: The verb 'Build' was approved recently, but PowerShell 5.1 doesn't know. You will be warned about
Build-Module
VERBOSE: The 'Build-Module' command in the ModuleBuilderBootStrap' module was imported, but because its name
does not include an approved verb, it might be difficult to find. The suggested alternative verbs are "New".
VERBOSE: Importing function 'Build-Module'.
VERBOSE: Importing function 'Convert-CodeCoverage'.
VERBOSE: Importing function 'Convert-LineNumber'.
WARNING: The names of some imported commands from the module 'ModuleBuilderBootStrap' include unapproved verbs  that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module
command again with the Verbose parameter. For a list of approved verbs, type Get-Verb.
VERBOSE: Populating RepositorySourceLocation property for module PSDepend.
VERBOSE: Loading module from path
'C:\Users\GaelColas\Documents\WindowsPowerShell\Modules\PSDepend\0.2.3\PSDepend.psm1'.
PackageManagement\Install-Package : The version '4.4.0' of the module 'Pester' being installed is not catalog
signed. Ensure that the version '4.4.0' of the module 'Pester' has the catalog file 'Pester.cat' and signed
with the same publisher 'CN=Microsoft Development Root Certificate Authority 2014, O=Microsoft Corporation,
L=Redmond, S=Washington, C=US' as the previously-installed module '4.4.0' with version '3.4.0' under the
directory 'C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0'. If you still want to install or update,
use -SkipPublisherCheck parameter.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:1809 char:21
+ ...          $null = PackageManagement\Install-Package @PSBoundParameters
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Microsoft.Power....InstallPackage:InstallPackage) [Install-P
   ackage], Exception
    + FullyQualifiedErrorId : ModuleIsNotCatalogSigned,Validate-ModuleAuthenticodeSignature,Microsoft.PowerSh
   ell.PackageManagement.Cmdlets.InstallPackage

How to specify an order for the Classes?

As you know Classes sometimes need to be imported or merged in a specific order.

I haven't found an elegant way of importing them in a specific order without prepending a number in the file name (which I'm not a fan of either).

e.g.:

1.ClassA.ps1
2.ClassC.ps1
3.ClassB.ps1

I tend to prefer specifying the order in a PSD1 and/or sorting the files within the Classes folder for merging them in the PSM1, but that's a bit over-engineered:

$order = {(Import-PowerShellDataFile -EA 0 .\Classes\classes.psd1).order.indexOf($_.BaseName)}
Get-ChildItem $FilePath -Filter *.ps1 -Recurse | Sort-Object $Order | Merge-ToModule $ModuleInfo

Happy to go with file names (less code), if that's your intent.

[Documentation] Readme.md

The help content of the Build-Module function says :

DESCRIPTION
2. Source subfolders in the same directory as the manifest:
Enum, Classes, Private, Public contain ps1 files

and the readme.md says :

By convention, use folders named "Classes", "Private", and "Public"

Should this document be updated ?

Install-RequiredModule error on Mac/Linux

Unsure if this is related to the module update but Azure Pipelines (for Mac and Linux) is choking on Install-RequiredModule with the following error:

Unable to find type [VersionRange]

Looks to be caused by this pipeline template: https://github.com/PoshCode/Azure-Pipelines/blob/master/Install-RequiredModule-step.yml#L34 (already mentioning Windows only).

Pipeline details found here:
https://dev.azure.com/alt3bv/Docusaurus.Powershell/_build/results?buildId=620&view=logs&j=18fe8392-28c7-5583-f88f-5fc6a2f5d637&t=8a5ae15e-4367-56d2-ffbc-efca611e9efb

No issues on Windows:

image

Pointers appreciated

Alias Postfix with Suffix

It might be just me but I found Suffix more mainstream than PostFix (see line 86 of Build-Module)?
Ideally, we would rename Postfix as Suffix and alias it as Postfix for backward compatibility/convenience, but I'm fine with just an alias.

an example in Readme.md does not work as intended

While following the readme instructions, the module was not installed correctly. I know the powershell command was qualified with "something like this" but it's so close to correct that I wanted to help the next guy. Using the instructions as is, only created a folder "1.0.0" in Modules\ModuleBuilder. When I added the -Recurse switch as shown below then the contents of the module were copied into the destination as I believe the intention was:

Original:
$UserModules = Join-Path (Split-Path $Profile.CurrentUserAllHosts) "Modules\ModuleBuilder" New-Item $UserModules -Type Directory -Force Copy-Item (.\build.ps1) -Destination $UserModules -Force

Suggested:
$UserModules = Join-Path (Split-Path $Profile.CurrentUserAllHosts) "Modules\ModuleBuilder" New-Item $UserModules -Type Directory -Force Copy-Item (.\build.ps1) -Destination $UserModules -Force -Recurse

Error when Build-Module params are specified but no Build.psd1 present

When invoking the command Build-Module with required Parameters like this:
Build-Module -Path .\Source\ModuleBuilder.psd1 -OutputDirectory ..\ -VersionedOutputDirectory
but the Build.psd1 file is absent, we get the error below.
The only way to work around it is to create a Build.psd1 with an empty hashtable.

I think we should make that file optional when required parameters are provided, and clearer error when not.

> build-module -Path .\Source\ModuleBuilder.psd1 -OutputDirectory ..\ -VersionedOutputDirectory
Import-Metadata : Can't find file C:\src\ModuleBuilder\Source\[Bb]uild.psd1
At C:\src\ModuleBuilder\output\ModuleBuilder\1.0.0\ModuleBuilder.psm1:83 char:18
+ ... BuildInfo = Import-Metadata -Path (Join-Path $ModuleSource [Bb]uild.p ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [Import-Metadata], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Metadata\Import-Metadata,Import-Metadata

InitializeBuild : You cannot call a method on a null-valued expression.
At C:\src\ModuleBuilder\output\ModuleBuilder\1.0.0\ModuleBuilder.psm1:610 char:27
+             $ModuleInfo = InitializeBuild $SourcePath
+                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [InitializeBuild], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,InitializeBuild

Installation of dependencies does not work on old PowershellGet

$RequiredModules | Install-Module -Scope $Scope -Repository PSGallery -SkipPublisherCheck -Verbose

In PowershellGet v1.0.0.1 :

Install-Module : Cannot validate argument on parameter 'MaximumVersion'. The argument is null. > Provide a valid value for the argument, and then try running the command again.
At C:\Users\olive\Projects\ConfluencePS\Tools\BuildTools.psm1:59 char:28
+ ... edModules | Install-Module -Scope $Scope -Repository PSGallery -SkipP ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (@{ ModuleName =...ion = '5.4.2' }:ModuleSpecification) [Install-> Module], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Install-Module

Install-RequiredModule.ps1 is missing

The README implies the script should live in the root of the repo, and it appears that was once true. But for some reason in 6e564dd it was deleted without explanation. I can't find it anywhere else in this org, was it removed for a reason? Should it be restored? The version deleted there seems to match what's currently published in the gallery but if that's the case where is the source code for the gallery script living? That script links to this repo so this seems like a mistake that it was removed rather than an intentional decision.

Install-RequiredModule is ignoring the full name

I was trying to do a build that's split across multiple agents. My default RequiredModules.psd1 file has all the things in it which I want on my dev laptop for this project:

@{
    "PowerShellGet"    = "[2.1.4, 3.0)"
    "ModuleBuilder"    = "1.*"
    "Pester"           = "[4.8.0, 5.0)"
    "PSScriptAnalyzer" = "1.18.0"
}

But on the build and test agents, I'd like to install a subset:

#### RequiredModules.Build.psd1
@{
    "ModuleBuilder"    = "1.*"
}

#### RequiredModules.Test.psd1
@{
    "Pester"           = "[4.8.0, 5.0)"
    "PSScriptAnalyzer" = "1.18.0"                                                                                                                            }

However Install-RequiredModule in ImportRequiredModulesFile does this:

        $LocalizedData = @{
            BaseDirectory = [IO.Path]::GetDirectoryName($RequiredModulesFile)
            FileName = [IO.Path]::GetFileNameWithoutExtension($RequiredModulesFile)
        }
        Import-LocalizedData @LocalizedData

And so when I call it with RequiredModules.Build.psd1 it's removing the .psd1 and then Import-LocatlizedData actually sees the .Build as a file extension, and removes it, and then loads RequiredModules.psd1 instead of RequiredModules.Build.psd1

I don't know why we might need to GetFileNameWithoutExtension there, but I think it's better if we don't, to support the idea of installing a subset like this. What do you think?

I suppose I can just rename them to RequiredModules-Build.psd1 but it seems weird that I need to, and this feels like a bug.

[Documentation] Build-Module parameter -Target

Its possible values are not explained :

[ValidateSet("Clean", "Build", "CleanBuild")]

Regarding its behavior, should the value Clean delete the versioned directory?
image

build.pds1:

@{
    Path = "MyModule.psd1"
    OutputDirectory = "C:\temp\Delivery\MyModule"
    VersionedOutputDirectory = $true
    CopyDirectories=@('.\Demos','.\fr-FR','.\TypeData')
}

Debugging Modules

Internally we have begun using a module builder that is heavily inspired by this project and tweaked a bit for our environment. One piece of feedback I received was that arranging the code so that classes and functions live in separate files makes debugging harder.

Assuming you were working with a monolithic psm1, It would be possible to debug and refactor within the same file with VS Code. With code living in separate files you have to build the module, set your breakpoints in the compiled psm1, follow the code to its bug, then fix the bug in a similar location in the actual source file.

While tooling for converting source line to compiled line and vice versa is somewhat helpful here, it does make the debugging experience more cumbersome.

I have tried to consider a way in which you can debug and code in the source files, but I'm at a loss. One thing I considered was allowing a Debug Build which would create a psm1 that dot sources the function files. This is doable but would only work for functions because classes have to live in the psm1 to support using each other (class a uses class b and class b uses class a). As I vaguely recall there are other caveats to dot sourcing classes.

Or maybe there is some way to allow for edits in the compiled psm1 to be pushed back to the source file or something.

Anyway, I never ran into this issue because my module coding workflows don't rely heavily on the debugging engine. However, a few of my co-workers do rely on it.

I'm looking for feedback on how we either document debugging modules built from this project or tools to make it much easier.

Add Tests for Function Exports

As a ModuleBuilder user
In order to ensure expectations
I need shared tests that validate inputs and outputs


We should create common test cases

  • Test all exported functions came from separate files
  • Test all public functions are properly exported by the module
  • Test only public functions are exported by the module

dotnet template needs to ensure of unique GUIDs

In the latest sets of changes to the dotnet template,on passing glance it looks like this will always create a module with a hardcoded GUID. So if you created 100 modules, they would all share the same GUID.

Whilst it's only a really minor thing, this is something that we should ensure is uniquely different on every run of the dotnet template at the creation of a module manifest, and ensure that this is then never changed as a module evolves.

Add support for Build.psd1 outside Source

I like having my Build.psd1 outside (one folder up) the source, so that it's clear everything in source will be part of the module.

The documentation makes it clear it's a requirement, but I don't see a good reason not to support this.

Currently the limitation seems to be coming from InitializeBuild.

Would you be accept a PR that supports having the Build.psd1 in a different folder than the Module Manifest?

Fails to import source module manifest when not using a build manifest

When there is no build manifest (build.psd1 then it fails to import source module manifest when the root folder name is not module name. It is because this code assumes the folder name is the same as the module name.

if ((-not $BuildInfo.SourcePath) -and $ParameterValues["SourcePath"] -notmatch '\.psd1') {
# Find a module manifest (or maybe several)
$ModuleInfo = Get-ChildItem $BuildManifestParent -Recurse -Filter *.psd1 -ErrorAction SilentlyContinue |
ImportModuleManifest -ErrorAction SilentlyContinue
# If we found more than one module info, the only way we have of picking just one is if it matches a folder name
if (@($ModuleInfo).Count -gt 1) {
# Resolve Build Manifest's parent folder to find the Absolute path
$ModuleName = Split-Path -Leaf $BuildManifestParent
# If we're in a "well known" source folder, look higher for a name
if ($ModuleName -in 'Source', 'src') {
$ModuleName = Split-Path (Split-Path -Parent $BuildManifestParent) -Leaf
}
$ModuleInfo = @($ModuleInfo).Where{ $_.Name -eq $ModuleName }
}
if (@($ModuleInfo).Count -eq 1) {
Write-Debug "Updating BuildInfo SourcePath to $($ModuleInfo.Path)"
$ParameterValues["SourcePath"] = $ModuleInfo.Path
}
if (-Not $ModuleInfo) {
throw "Can't find a module manifest in $BuildManifestParent"
}
}

Instead in this case, when there are no build manifest, it should be assumed that the variable $ParameterValues["SourcePath"] contains the path to the source folder.
The code should be changed to this:

if ((-not $BuildInfo.SourcePath) -and $ParameterValues["SourcePath"] -notmatch '\.psd1') {
    # Find a module manifest (or maybe several)
    $ModuleInfo = Get-ChildItem -Path $ParameterValues["SourcePath"] -Filter *.psd1 -ErrorAction 'SilentlyContinue' |
        ImportModuleManifest -ErrorAction 'SilentlyContinue'

    if (-Not $ModuleInfo) {
        throw "Can't find a module manifest in $BuildManifestParent"
    }

    # If we found more than one module info, the only way we have of picking just one is if it matches a folder name
    if (@($ModuleInfo).Count -gt 1) {
        throw ("Found multiple module manifest in the root of the path {0}." -f $ParameterValues["SourcePath"])
    }

    Write-Debug "Updating BuildInfo SourcePath to $($ModuleInfo.Path)"
    $ParameterValues["SourcePath"] = $ModuleInfo.Path
}

Using this code the build was successful.

The MoveUsingStatements feature doesn't work for using namespace

If I have this, for instance, in a file in classes:

using namespace System.Collections.Generic

class Resolver {
    [Dictionary[string, PSObject]]$Cache = [Dictionary[string, PSObject]]::new()
}

Then if we get the error because the using statement isn't the first thing in the new module, we will always(?) also get a TypeNotFound error about the Dictionary, which will prevent the using statement from being removed.

I thought we already fixed this?

Prerelease Key being stripped

I have a module with Prerelease = "alpha" set in the manifest. This value is being stripped out on build. I attempted to set this value using the -Prerelease parameter, but I'm still left with an empty value after build.

Feature: Where should the built module go?

As a module author, I need to be able to specify where the build output should go.

Background

Because of how the using module statement works in PowerShell, I usually need to build output into the PSModule path without breaking the working versions -- however, by default the output should go in a folder in the project (let's call it "output" though, because plain English is good, and these aren't binaries).

Assumptions:

I have a source folder

That is, I have a project "root" folder. Within that I have a source folder with the build.psd1 file in it. It may be named "source" but it might also be named with the module name (e.g. "ModuleBuilder") or something else entirely. I might even have multiple modules within a single project. In that case, each one has it's own source folder (which obviously can't all be named "Source").

I sometimes want to add the version number

I can specify the module name in my build.psd1, but not the version, because that changes with each commit/build/release, but sometimes I want to build output into my PSModulePath, so it needs to be able to have the version number, so it doesn't "clean" the old versions out.

When building clean, we should clean this version

If we're adding version numbers to the build output path, we should leave any old version numbers. That way if we're building to the PSModulePath, we won't accidentally remove old versions that I might need for production work, or supporting users.

Proposal

We need a parameter -VersionedOutputDirectory that determines whether a version number is appended to the output folder path or not. This should be a switch that's used in addition to the -OutputDirectory parameter and can be defaulted in the build.psd1.

Possible results:

  1. If you specify -VersionedOutputDirectory and no -OutputDirectory the output should go in a numbered subdirectory of the "root" folder.
  2. If you specify -VersionedOutputDirectory and -OutputDirectory the output should go in a numbered subdirectory of the output directory.
  3. If you specify a relative -OutputDirectory the output should go in a path relative to the build.psd1 (Currently, this is wrong)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.