poshbotio / PoshBot

Powershell-based bot framework
MIT License
540 stars 108 forks source link

PluginConfiguration and PoshBot.FromConfig #45

Closed brianbunke closed 7 years ago

brianbunke commented 7 years ago

Expected Behavior

Per help New-PoshBotConfiguration -Full, this is the example found on the -PluginConfiguration parameter:

@{
    Demo = @{
        MyParam = 'bar'
    }
}

[...snip...]

function Get-Foo {
    [cmdletbinding()]
    param(
        [PoshBot.FromConfig()]
        [parameter(mandatory)]
        [string]$MyParam
    )

    Write-Output $MyParam
}

I expect $MyParam to default to 'bar'.

Current Behavior

Importing my custom plugin throws the following error:

❗️ Cannot find an overload for ".ctor" and the argument count: "0".

Debugging the code, I find this is actually happening here: https://github.com/poshbotio/PoshBot/blob/94931fe8e25e09da7774838a4c5ac2b6db16c217/PoshBot/Classes/PluginManager.ps1#L432

The Get-Help fails on my Get-Foo equivalent command while trying to import my custom plugin. After adding help, I found it's actually just choking on the [PoshBot.FromConfig()] line. I can remove that and it returns help as expected.

I believe this also happens on the included Demo plugin packaged with PoshBot.

Steps to Reproduce (for bugs)

Does !ip Demo work for anyone else right now?

Context

During new plugin development, I'm hoping to store some more...ahem...unsavory data, but I've found I'm not sure how to use the PluginConfiguration area and the PoshBot.FromConfig class in tandem.

I found the aforementioned example on the cmdlet-based help, but didn't see anything else on the ReadTheDocs site at this time.

If docs need to be updated, I'm happy to help there once this gets sorted out.

Your Environment

devblackops commented 7 years ago

Hi @brianbunke!

There were some bugs with getting the help information for commands that hopefully has been fixed in 94931fe8e25e09da7774838a4c5ac2b6db16c217. These changes will be in v0.6.0 when it is released. You can also try and build the latest version from source following building.md and see if your issues magically go away.

The Demo plugin that was included in PoshBot has also been removed from the core module. I stopped using it a while ago but forgot to delete it. I'm not surprised there were issues with it. For development testing, I use the separate plugin PoshBot.Demo. That plugin has a bunch more example commands for testing PoshBot functionality. You can clone that plugin down and put it in your $env:PSModulePath or your PoshBot configuration directory and the Install-Plugin command should find it.

The way the PluginConfiguration feature is supposed to work is that you define a hashtable with keys that correspond to each plugin you want to supply values to. The value of each plugin key is itself another hashtable with keys that are the values you want to make available to the plugin.

Example bot.psd1

@{
  PluginRepository = @('PSGallery')
  Name = 'Cherry2000'
  # Other properties omitted
  PluginConfiguration = @{
    'PoshBot.Wolfram' = @{
      ApiKey = 'hunter2'
    }
    'PoshBot.Demo' = @{
      Config1 = 'bar'
      SomeValue = 'asdf'
    }
  }
}

In your plugin, you decorate any parameter with [PoshBot.FromConfig()] to state that you want PoshBot to supply the value from the PluginConfiguration. If the parameter name, Config1 in this case, is the same name as the key in PluginConfiguration, you don't need to specify the name of the PluginConfiguration item (ie, [PoshBot.FromConfig('Config1')]. [PoshBot.FromConfig()] should work fine. You may want to store the value in PluginConfiguration under a different name than the parameter name and in that case, you do need to specify the name. If I wanted to pull value of SomeValue from PluginConfiguration I would use `[PoshBot.FromConfig('SomeValue')] instead.

PoshBot.Demo

function Get-Foo {
    <#
    .SYNOPSIS
        Gets parameter value from bot configuration
    .EXAMPLE
        !get-foo
    #>
    [cmdletbinding()]
    param(
        [PoshBot.FromConfig('Config1')]
        [parameter(Mandatory)]
        [string]$Config1
    )

    Write-Output "[$Config1] was passed in from bot configuration"
}

Sorry for the long winded answer 😄 I hope that makes sense.

If you still see the Cannot find an overload for ".ctor" and the argument count: "0". error using the latest version, let me know.

-Brandon

brianbunke commented 7 years ago

Thanks, that's helpful info. Your API key is '***'? What are the odds of that?

Unfortunately, I built 46a6c8f7ceba7bbc82f96b4a3a4318a48d52a391/ master from source and ran into the same error. The function's help (and thus, the plugin) loads if I comment out the [PoshBot.FromConfig()] line.

My demo command is basically yours, except I also have the PoshBot.BotCommand section below CmdletBinding.

devblackops commented 7 years ago

I use the same password for my luggage but don't tell anybody 😄

I was able to reproduce the issue and put in a fix in 66712e557633b34f0802f10757309402e73344ff.

Back in https://github.com/poshbotio/PoshBot/commit/c6da83740cb15a0cffdc35165c465285fabafc70#diff-dd0c809ffdda6f5f649e99adc30df168L45 I must have been in a drunken stupor.

Build from 66712e557633b34f0802f10757309402e73344ff and see if that fixes it. The catch is that your plugin commands run as a job and if they have a dependency on PoshBot in their module manifest, PowerShell will attempt to load the PoshBot module before the command is run. That means that the fixed version of PoshBot needs to be in your $env:PSModulePath so your commands loads the correct version of the module.

brianbunke commented 7 years ago

I can confirm this is fixed in 0.6.0. Thank you, sir!