PoshCode Logo PowerShell Code Repository

Extract-PluginMeta by mario 3 weeks ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/6832"></script>download | new post

Provides a crude implementation of plugin meta data (PMD) extraction

  1. # encoding: utf-8
  2. # api: ps
  3. # type: functions
  4. # title: PMD extraction
  5. # description: Provides a crude implementation of Plugin Meta Data extraction
  6. # version: 0.3
  7. # depends: powershell >= 2.0, regex
  8. # category: io
  9. # author: mario
  10. # src: https://pypi.python.org/pypi/pluginconf/0.6.7
  11. # license: Public domain
  12. # config: -
  13. # status: alpha
  14. # priority: extra
  15. #
  16. # A little consistency always goes a long way. -- This sample comment is a basic
  17. # version of PMD. The format is (1) fairly obvious, (2) easy to extract, (3) most
  18. # compatible to implementations in other scripting languages (Python, Ruby, PHP, )
  19. #
  20. # The advantage over hodgepodge comments becomes more striking the more scripts
  21. # amass. Or once integration or packaging become an issue.
  22. #
  23. # This version uses a few crude regex methods to fetch fields and config options:
  24. #
  25. #   Extract-PluginMeta reads from a given file name.
  26. #   Simply scans the topmost comment block.
  27. #   Fields are basically YAML entries.
  28. #   Key names are case-insensitive, meant to be message/rfc-style,
  29. #    but otherwise free-form and per-project customizable.
  30. #   Wheres the config: field is a JSON-style list.
  31. #   No dependency management or anything else provided here.
  32. #
  33. # The default field names are api:, type:, title:, description:, version:, category:
  34. # and config:. Though they're mostly decoration, and it's encouraged to introduce
  35. # new ones, depending on project and tool requirements.
  36.  
  37.  
  38. #-- baseline plugin meta data support
  39. function Extract-PluginMeta() {
  40.     <#
  41.       .SYNOPSIS
  42.          Extract plugin meta data from given filename
  43.       .DESCRIPTION
  44.          Reads specified file, returns hashtable for key:value entries
  45.          from topmost comment block. Prepares config{} dicts.
  46.       .PARAMETER fn
  47.          Script to read from
  48.       .OUTPUTS
  49.          Returns a HashTable of extracted field &#8594; values
  50.       .EXAMPLE
  51.          For instance to read a couple of "plugins" at once:
  52.            $menu = (Get-Item tools/*.ps1 | % { Extract-PluginMeta $_ })
  53.          Which builds a usable hashtable list from asorted scripts,
  54.          once they have been documented. Which thus eases processing:
  55.            Show-MenuCLI ($menu | % { $_.title -and $_.type -eq "inline" })
  56.          Or executing "init" plugins for instance:
  57.            $menu | ? { $_.api -eq "mytool" -and $_.type -eq "init" } | { . $_.fn }
  58.       .TEST
  59.          (Extract-PluginMeta $MyInvocation.MyCommand.Definition).version -eq "0.3"
  60.       .NOTES
  61.          Packs comment remainder as `doc` field.
  62.     #>
  63.     Param($fn, $meta=@{}, $cfg=@())
  64.  
  65.     # read file
  66.     $str = Get-Content $fn | Out-String
  67.  
  68.     # look for first comment block
  69.     if ($m = [regex]::match($str, '(?m)((?:^\s*[#]+.*$\n?)+)')) {
  70.  
  71.         # remove leading #&#9251; from lines, then split remainder comment
  72.         $str = $m.groups[1] -replace "(?m)^\s*#[ \t]*", ""
  73.         $str, $doc = [regex]::split($str, '(?m)^$\n')
  74.  
  75.         # find all `key:value` pairs
  76.         preg_match_all -rx "(?m)^([\w-]+):\s*(.*(?:[\r\n]*^\s+.*$)*)" -str $str | % { $meta[$_[1]] = $_[2].trim() }
  77.  
  78.         # split out config: and crude-parse it (JSONish serialization)
  79.         preg_match_all -rx "\{(.+?)\}" -str $meta.config | % { $r = @{};
  80.             preg_match_all -rx "([\w]+)\s*[:=]\s*(?:[']?([^,;}]+)[']?)" -str $_[1] | % {  $r[$_[1]] = $_[2] }; $cfg += $r;
  81.         }
  82.  
  83.         # merge into hashtable
  84.         $meta.fn = $fn
  85.         $meta.doc = ($doc -join "`r`n")
  86.         $meta.config = $cfg
  87.     }
  88.     return $meta  # or return as (New-Object PSCustomObject -Prop $meta)
  89. }
  90.  
  91. #-- Regex/Select-String -Allmatches as nested array / a convenience shortcut /  well, why, yes; it's a PHP-style function
  92. function preg_match_all() {
  93.     Param($rx, $str)
  94.     $str | Select-String $rx -AllMatches | % { $_.Matches } | % { ,($_.Groups | % { $_.Value }) }
  95. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me