PoshCode / ModuleBuilder

A PowerShell Module to help scripters write, version, sign, package, and publish.
MIT License
445 stars 54 forks source link

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

Closed johlju closed 3 years ago

johlju commented 4 years ago

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.

https://github.com/PoshCode/ModuleBuilder/blob/8de7520b8884b3b6ba6ed187a116bd766d25856b/Source/Private/GetBuildInfo.ps1#L81-L102

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.

Jaykul commented 4 years ago

I think the fix here has to be that you TELL IT which file is the module manifest.

Otherwise, you'll break compatibility with modules that have translation files (which are psd1 files in a language subfolder), Configuration.psd1 files, or even build.psd1 files.

johlju commented 4 years ago

It only looks for the .psd1 files in the root of the source folder if there are no build.psd1 file (that file overrides the above code). But didn't think there could be other *.psd1 files in the root of source. That will break my suggestion. 🤔 Going back to the drawing board and look at changing our build pipeline.

Thanks @Jaykul, always good to have more than one pair of eyes on a problem. 🙂

johlju commented 4 years ago

@Jaykul I think if SourcePath always should point to the source module manifest then I think the code above (that is in the module now) is not needed at all. 🤔 Whole point of that could is finding a module manifest if SourcePath is pointing to the source folder. But that only works if the root project folder has the same name as the module name. In Azure Pipelines it does not.

I changed our pipeline to pass the module manifest so this won't be an issue for us. Closing this.

Jaykul commented 4 years ago

@johlju Azure pipelines does allow you to specify the name of the folder you're checking out to... In fact, if you check out more than one repository (say, for instance, you have a build helpers repo), then the default name of the folder will actually be the repo name.

But you're right, the automatic detection doesn't work properly when your source is checked out to \s -- we could probably improve it so that if there's only one found, it'll use that one (and even filter out non-module metadata files, since configuration and language files don't look like module manifests).

I would like that, since it would make it easier to build one-size-fits all build templates 😉

johlju commented 4 years ago

Yes, it is possible to rename the checkout folder name. Didn't know that. https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#checkout

steps:
- checkout: self
  path: MyModuleName

I reopen this issue and the PR and I can give your suggestion a try.