Initial Commit

This commit is contained in:
Riley Schneider
2025-12-03 16:38:10 +01:00
parent c5e26bf594
commit b732d8d4b5
17680 changed files with 5977495 additions and 2 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,204 @@
package CPANPLUS::Shell::Default::Plugins::CustomSource;
use strict;
use CPANPLUS::Error qw[error msg];
use CPANPLUS::Internals::Constants;
use Data::Dumper;
use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
use vars qw[$VERSION];
$VERSION = "0.9910";
=head1 NAME
CPANPLUS::Shell::Default::Plugins::CustomSource - add custom sources to CPANPLUS
=head1 SYNOPSIS
### elaborate help text
CPAN Terminal> /? cs
### add a new custom source
CPAN Terminal> /cs --add file:///path/to/releases
### list all your custom sources by
CPAN Terminal> /cs --list
### display the contents of a custom source by URI or ID
CPAN Terminal> /cs --contents file:///path/to/releases
CPAN Terminal> /cs --contents 1
### Update a custom source by URI or ID
CPAN Terminal> /cs --update file:///path/to/releases
CPAN Terminal> /cs --update 1
### Remove a custom source by URI or ID
CPAN Terminal> /cs --remove file:///path/to/releases
CPAN Terminal> /cs --remove 1
### Write an index file for a custom source, to share
### with 3rd parties or remote users
CPAN Terminal> /cs --write file:///path/to/releases
### Make sure to save your sources when adding/removing
### sources, so your changes are reflected in the cache:
CPAN Terminal> x
=head1 DESCRIPTION
This is a C<CPANPLUS::Shell::Default> plugin that can add
custom sources to your CPANPLUS installation. This is a
wrapper around the C<custom module sources> code as outlined
in L<CPANPLUS::Backend/CUSTOM MODULE SOURCES>.
This allows you to extend your index of available modules
beyond what's available on C<CPAN> with your own local
distributions, or ones offered by third parties.
=cut
sub plugins {
return ( cs => 'custom_source' )
}
my $Cb;
my $Shell;
my @Index = ();
sub _uri_from_cache {
my $self = shift;
my $input = shift or return;
### you gave us a search number
my $uri = $input =~ /^\d+$/
? $Index[ $input - 1 ] # remember, off by 1!
: $input;
my %files = reverse $Cb->list_custom_sources;
### it's an URI we know
### VMS can lower case all files, so make sure we check that too
my $local = $files{ $uri };
$local = $files{ lc $uri } if !$local && ON_VMS;
if( $local ) {
return wantarray
? ($uri, $local)
: $uri;
}
### couldn't resolve the input
error(loc("Unknown URI/index: '%1'", $input));
return;
}
sub _list_custom_sources {
my $class = shift;
my %files = $Cb->list_custom_sources;
$Shell->__print( loc("Your remote sources:"), $/ ) if keys %files;
my $i = 0;
while(my($local,$remote) = each %files) {
$Shell->__printf( " [%2d] %s\n", ++$i, $remote );
### remember, off by 1!
push @Index, $remote;
}
$Shell->__print( $/ );
}
sub _list_contents {
my $class = shift;
my $input = shift;
my ($uri,$local) = $class->_uri_from_cache( $input );
unless( $uri ) {
error(loc("--contents needs URI parameter"));
return;
}
my $fh = OPEN_FILE->( $local ) or return;
$Shell->__printf( " %s", $_ ) for sort <$fh>;
$Shell->__print( $/ );
}
sub custom_source {
my $class = shift;
my $shell = shift; $Shell = $shell; # available to all methods now
my $cb = shift; $Cb = $cb; # available to all methods now
my $cmd = shift;
my $input = shift || '';
my $opts = shift || {};
### show a list
if( $opts->{'list'} ) {
$class->_list_custom_sources;
} elsif ( $opts->{'contents'} ) {
$class->_list_contents( $input );
} elsif ( $opts->{'add'} ) {
unless( $input ) {
error(loc("--add needs URI parameter"));
return;
}
$cb->add_custom_source( uri => $input )
and $shell->__print(loc("Added remote source '%1'", $input), $/);
$Shell->__print($/, loc("Remote source contains:"), $/, $/);
$class->_list_contents( $input );
} elsif ( $opts->{'remove'} ) {
my($uri,$local) = $class->_uri_from_cache( $input );
unless( $uri ) {
error(loc("--remove needs URI parameter"));
return;
}
1 while unlink $local;
$shell->__print( loc("Removed remote source '%1'", $uri), $/ );
} elsif ( $opts->{'update'} ) {
### did we get input? if so, it's a remote part
my $uri = $class->_uri_from_cache( $input );
$cb->update_custom_source( $uri ? ( remote => $uri ) : () )
and do { $shell->__print( loc("Updated remote sources"), $/ ) };
} elsif ( $opts->{'write'} ) {
$cb->write_custom_source_index( path => $input ) and
$shell->__print( loc("Wrote remote source index for '%1'", $input), $/);
} else {
error(loc("Unrecognized command, see '%1' for help", '/? cs'));
}
return;
}
sub custom_source_help {
return loc(
$/ .
' # Plugin to manage custom sources from the default shell' . $/ .
" # See the 'CUSTOM MODULE SOURCES' section in the " . $/ .
' # CPANPLUS::Backend documentation for details.' . $/ .
' /cs --list # list available sources' . $/ .
' /cs --add URI # add source' . $/ .
' /cs --remove URI | INDEX # remove source' . $/ .
' /cs --contents URI | INDEX # show packages from source'. $/ .
' /cs --update [URI | INDEX] # update source index' . $/ .
' /cs --write PATH # write source index' . $/
);
}
1;

View File

@@ -0,0 +1,136 @@
=head1 NAME
CPANPLUS::Shell::Default::Plugins::HOWTO -- documentation on how to write your own plugins
=head1 SYNOPSIS
package CPANPLUS::Shell::Default::Plugins::MyPlugin;
### return command => method mapping
sub plugins { ( myplugin1 => 'mp1', myplugin2 => 'mp2' ) }
### method called when the command '/myplugin1' is issued
sub mp1 { .... }
### method called when the command '/? myplugin1' is issued
sub mp1_help { return "Help Text" }
=head1 DESCRIPTION
This pod text explains how to write your own plugins for
C<CPANPLUS::Shell::Default>.
=head1 HOWTO
=head2 Registering Plugin Modules
Plugins are detected by using C<Module::Pluggable>. Every module in
the C<CPANPLUS::Shell::Default::Plugins::*> namespace is considered a
plugin, and is attempted to be loaded.
Therefor, any plugin must be declared in that namespace, in a corresponding
C<.pm> file.
=head2 Registering Plugin Commands
To register any plugin commands, a list of key value pairs must be returned
by a C<plugins> method in your package. The keys are the commands you wish
to register, the values are the methods in the plugin package you wish to have
called when the command is issued.
For example, a simple 'Hello, World!' plugin:
package CPANPLUS::Shell::Default::Plugins::HW;
sub plugins { return ( helloworld => 'hw' ) };
sub hw { print "Hello, world!\n" }
When the user in the default shell now issues the C</helloworld> command,
this command will be dispatched to the plugin, and its C<hw> method will
be called
=head2 Registering Plugin Help
To provide usage information for your plugin, the user of the default shell
can type C</? PLUGIN_COMMAND>. In that case, the function C<PLUGIN_COMMAND_help>
will be called in your plugin package.
For example, extending the above example, when a user calls C</? helloworld>,
the function C<hw_help> will be called, which might look like this:
sub hw_help { " /helloworld # prints "Hello, world!\n" }
If you don't provide a corresponding _help function to your commands, the
default shell will handle it gracefully, but the user will be stuck without
usage information on your commands, so it's considered undesirable to omit
the help functions.
=head2 Arguments to Plugin Commands
Any plugin function will receive the following arguments when called, which
are all positional:
=over 4
=item Classname -- The name of your plugin class
=item Shell -- The CPANPLUS::Shell::Default object
=item Backend -- The CPANPLUS::Backend object
=item Command -- The command issued by the user
=item Input -- The input string from the user
=item Options -- A hashref of options provided by the user
=back
For example, the following command:
/helloworld bob --nofoo --bar=2 joe
Would yield the following arguments:
sub hw {
my $class = shift; # CPANPLUS::Shell::Default::Plugins::HW
my $shell = shift; # CPANPLUS::Shell::Default object
my $cb = shift; # CPANPLUS::Backend object
my $cmd = shift; # 'helloworld'
my $input = shift; # 'bob joe'
my $opts = shift; # { foo => 0, bar => 2 }
....
}
=head1 BUG REPORTS
Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
=head1 AUTHOR
This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
=head1 COPYRIGHT
The CPAN++ interface (of which this module is a part of) is copyright (c)
2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
This library is free software; you may redistribute and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
L<CPANPLUS::Shell::Default>, L<CPANPLUS::Shell>, L<cpanp>
=cut
# Local variables:
# c-indentation-style: bsd
# c-basic-offset: 4
# indent-tabs-mode: nil
# End:
# vim: expandtab shiftwidth=4:

View File

@@ -0,0 +1,189 @@
package CPANPLUS::Shell::Default::Plugins::Remote;
use strict;
use Module::Load;
use Params::Check qw[check];
use CPANPLUS::Error qw[error msg];
use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
use vars qw[$VERSION];
$VERSION = "0.9910";
=head1 NAME
CPANPLUS::Shell::Default::Plugins::Remote - connect to a remote CPANPLUS
=head1 SYNOPSIS
CPAN Terminal> /connect localhost 1337 --user=foo --pass=bar
...
CPAN Terminal@localhost> /disconnect
=head1 DESCRIPTION
This is a C<CPANPLUS::Shell::Default> plugin that allows you to connect
to a machine running an instance of C<CPANPLUS::Daemon>, allowing remote
usage of the C<CPANPLUS Shell>.
A sample session, updating all modules on a remote machine, might look
like this:
CPAN Terminal> /connect --user=my_user --pass=secret localhost 1337
Connection accepted
Successfully connected to 'localhost' on port '11337'
Note that no output will appear until a command has completed
-- this may take a while
CPAN Terminal@localhost> o; i *
[....]
CPAN Terminal@localhost> /disconnect
CPAN Terminal>
=cut
### store the original prompt here, so we can restore it on disconnect
my $Saved_Prompt;
sub plugins { ( connect => 'connect', disconnect => 'disconnect' ) }
sub connect {
my $class = shift;
my $shell = shift;
my $cb = shift;
my $cmd = shift;
my $input = shift || '';
my $opts = shift || {};
my $conf = $cb->configure_object;
my $user; my $pass;
{ local $Params::Check::ALLOW_UNKNOWN = 1;
my $tmpl = {
user => { default => 'cpanpd', store => \$user },
pass => { required => 1, store => \$pass },
};
check( $tmpl, $opts ) or return;
}
my @parts = split /\s+/, $input;
my $host = shift @parts || 'localhost';
my $port = shift @parts || '1337';
load IO::Socket;
my $remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port,
) or (
error( loc( "Cannot connect to port '%1' ".
"on host '%2'", $port, $host ) ),
return
);
my $con = {
connection => $remote,
username => $user,
password => $pass,
};
### store the connection
$shell->remote( $con );
my($status,$buffer) = $shell->__send_remote_command(
"VERSION=$CPANPLUS::Shell::Default::VERSION");
if( $status ) {
print "\n$buffer\n\n";
print loc( "Successfully connected to '%1' on port '%2'",
$host, $port );
print "\n\n";
print loc( "Note that no output will appear until a command ".
"has completed\n-- this may take a while" );
print "\n\n";
### save the original prompt
$Saved_Prompt = $shell->prompt;
$shell->prompt( $shell->brand .'@'. $host .':'. $port .'> ' );
} else {
print "\n$buffer\n\n";
print loc( "Failed to connect to '%1' on port '%2'",
$host, $port );
print "\n\n";
$shell->remote( undef );
}
}
sub disconnect {
my $class = shift;
my $shell = shift;
print "\n", ( $shell->remote
? loc( "Disconnecting from remote host" )
: loc( "Not connected to remote host" )
), "\n\n";
$shell->remote( undef );
$shell->prompt( $Saved_Prompt );
}
sub connect_help {
return loc(
" /connect [HOST PORT] # Connect to the remote machine,\n" .
" # defaults taken from your config\n" .
" --user=USER # Optional username\n" .
" --pass=PASS # Optional password" );
}
sub disconnect_help {
return loc(
" /disconnect # Disconnect from the remote server" );
}
1;
=pod
=head1 BUG REPORTS
Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
=head1 AUTHOR
This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
=head1 COPYRIGHT
The CPAN++ interface (of which this module is a part of) is copyright (c)
2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
This library is free software; you may redistribute and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
L<CPANPLUS::Shell::Default>, L<CPANPLUS::Shell>, L<cpanp>
=cut
# Local variables:
# c-indentation-style: bsd
# c-basic-offset: 4
# indent-tabs-mode: nil
# End:
# vim: expandtab shiftwidth=4:

View File

@@ -0,0 +1,110 @@
package CPANPLUS::Shell::Default::Plugins::Source;
use strict;
use CPANPLUS::Error qw[error msg];
use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext';
use vars qw[$VERSION];
$VERSION = "0.9910";
=head1 NAME
CPANPLUS::Shell::Default::Plugins::Source - read in CPANPLUS commands
=head1 SYNOPSIS
CPAN Terminal> /source /tmp/list_of_commands /tmp/more_commands
=head1 DESCRIPTION
This is a C<CPANPLUS::Shell::Default> plugin that works just like
your unix shells source(1) command; it reads in a file that has
commands in it to execute, and then executes them.
A sample file might look like this:
# first, update all the source files
x --update_source
# find all of my modules that are on the CPAN
# test them, and store the error log
a ^KANE$'
t *
p /home/kane/cpan-autotest/log
# and inform us we're good to go
! print "Autotest complete, log stored; please enter your commands!"
Note how empty lines, and lines starting with a '#' are being skipped
in the execution.
=cut
sub plugins { return ( source => 'source' ) }
sub source {
my $class = shift;
my $shell = shift;
my $cb = shift;
my $cmd = shift;
my $input = shift || '';
my $opts = shift || {};
my $verbose = $cb->configure_object->get_conf('verbose');
for my $file ( split /\s+/, $input ) {
my $fh = FileHandle->new("$file") or(
error(loc("Could not open file '%1': %2", $file, $!)),
next
);
while( my $line = <$fh> ) {
chomp $line;
next if $line !~ /\S+/; # skip empty/whitespace only lines
next if $line =~ /^#/; # skip comments
msg(loc("Dispatching '%1'", $line), $verbose);
return 1 if $shell->dispatch_on_input( input => $line );
}
}
}
sub source_help {
return loc(' /source FILE [FILE ..] '.
'# read in commands from the specified file' ),
}
1;
=pod
=head1 BUG REPORTS
Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
=head1 AUTHOR
This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
=head1 COPYRIGHT
The CPAN++ interface (of which this module is a part of) is copyright (c)
2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
This library is free software; you may redistribute and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
L<CPANPLUS::Shell::Default>, L<CPANPLUS::Shell>, L<cpanp>
=cut
# Local variables:
# c-indentation-style: bsd
# c-basic-offset: 4
# indent-tabs-mode: nil
# End:
# vim: expandtab shiftwidth=4: