Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit role Pluggable;
- use JSON::Fast;
- use File::Find;
- method plugin-base( $base ) { "{$base.defined ?? $base !! ::?CLASS.^name}" }
- # Public Interface
- method plugins( :$base = Nil, :$plugins-namespace = 'Plugins', :$name-matcher = Nil ) {
- say "plugins";
- say self.plugin-base($base);
- pluginz( self.plugin-base($base), $plugins-namespace, $name-matcher );
- }
- method available-plugins(:$base = Nil, :$plugins-namespace = 'Plugins', :$name-matcher = Nil) {
- list-modules(self.plugin-base($base), $plugins-namespace, $name-matcher);
- }
- multi sub available-plugins($base = Nil, :$plugins-namespace = 'Plugins', :$name-matcher = Nil) is export {
- list-modules($base, $plugins-namespace, $name-matcher);
- }
- multi sub available-plugins($base = Nil, $search-list = [], :$plugins-namespace = 'Plugins', :$name-matcher = Nil ) is export {
- ( list-modules($base, $plugins-namespace, $name-matcher).Bag ∩
- $search-list.map({ "{$base}::{$plugins-namespace}::$_" }).Bag
- ).keys.Array ;
- }
- my sub pluginz( :$base = Nil, :$plugins-namespace = 'Plugins', :$name-matcher = Nil ) is export {
- say "pluginz";
- #load-modules($base, $plugins-namespace, $name-matcher);
- }
- my sub load-modules($base, $namespace, $name-matcher) {
- say "load-modules";
- list-modules($base, $namespace, $name-matcher)
- .map({ require-module( $_ ) })
- .grep({ !.isa(Nil) }) # Filter out modules that failed to load
- .unique # Potentially, there could be the same module installed and in lib at the same time
- .Array;
- }
- my sub require-module($module-name) {
- try {
- require ::($module-name);
- return ::($module-name);
- }
- given $! {
- .say if ($*DEBUG-PLUGINS//False);
- say .WHAT.perl, do given .backtrace[0] { .file, .line, .subname }
- return;
- }
- }
- my sub list-modules($base, $namespace, $name-matcher) {
- ( |installed-modules($base, $namespace, $name-matcher),
- |filesystem-modules($base, $namespace, $name-matcher)
- ).unique.Array;
- }
- my sub filesystem-modules($base, $namespace, $name-matcher) {
- matching-modules( all-filesystem-modules(), $base, $namespace, $name-matcher );
- }
- my sub installed-modules($base, $namespace, $name-matcher) {
- matching-modules( all-installed-modules(), $base, $namespace, $name-matcher );
- }
- my sub matching-modules($modules, $base, $namespace, $name-matcher) {
- $modules.grep(-> $module-name {
- match-module( $module-name, $base, $namespace, $name-matcher);
- });
- }
- my sub match-module($module-name, $base, $namespace, $name-matcher) {
- ($module-name.chars > "{$base}::{$namespace}".chars) &&
- ($module-name.starts-with("{$base}::{$namespace}")) &&
- ((!defined $name-matcher) || ($module-name ~~ $name-matcher));
- }
- my sub all-filesystem-modules() {
- $*REPO.repo-chain
- .grep({ .isa(CompUnit::Repository::FileSystem) })
- .map({ |modules-in-directory( .prefix ) });
- }
- my sub modules-in-directory( $directory ) {
- my @files = find(dir => $directory, name => /\.pm6?$/);
- return map(-> $module-file { cleanup-module-name($module-file, $directory) }, @files);
- }
- my sub cleanup-module-name ($module-name is copy, $prefix) {
- $module-name = $module-name.substr($prefix.chars + 1);
- $module-name = $module-name.substr(0, $module-name.rindex('.'));
- $module-name = $module-name.subst(/\//, '::', :g);
- $module-name = $module-name.subst(/\\/, '::', :g);
- }
- my sub all-installed-modules() {
- # XXX perhaps $r.installed() could be leveraged here, but it
- # seems broken at the moment
- $*REPO.repo-chain
- .grep({ .isa(CompUnit::Repository::Installation) })
- .map({ |modules-in-dist( .prefix ) });
- }
- my sub modules-in-dist( $directory ) {
- my $dist_dir = $directory.child('dist');
- gather {
- if ($dist_dir.?e) {
- for $dist_dir.IO.dir.grep(*.IO.f) -> $idx_file {
- my $data = from-json($idx_file.IO.slurp);
- for $data{'provides'}.keys -> $f {
- take $f;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement