#!/usr/bin/perl # $Id: youri-submit.in 1687 2007-06-28 22:44:07Z guillomovitch $ =head1 NAME youri-submit - package submission tool =head1 VERSION Version 2.0 =head1 SYNOPSIS youri-submit [options] youri-submit --list [target] youri-submit --help [category] [item] Options: --config use file as config file --skip-step skip step --define = pass additional values --clean delete package after success --verbose verbose run --test test run --list list items from given category --help [category] display contextual help =head1 DESCRIPTION B allows to submit packages to a repository. All packages given on command lines are passed to a list of test plugins, depending on given upload target. If none of them fails, all packages are passed to a list of action plugins, depending also on given upload target. =head1 OPTIONS =over =item B<--config> I Use given file as configuration, instead of normal one. =item B<--skip-step> I Skip step with given identity. =item B<--define> = Define additional parameters, to be used by plugins. =item B<--clean> Delete submited packages upon successfull submission. =item B<--verbose> Produce more verbose output (can be used more than once) =item B<--test> Don't perform any modification. =item B<--list> I List available items from given category and exits. Category must be either B, B or B. A target is needed for the two last ones. =item B<--help> I Display help for given category and exits. Category must be either B, B or B. An item is needed for the two last ones. If no category given, display standard help. =back =head1 CONFIGURATION Configuration is read from the first file found among: =over =item * the one specified by B<--config> option on command-line =item * $HOME/.youri/submit.conf =item * @sysconfdir@/youri/submit.conf =back The configuration file should be a YAML-format files, with the following mandatory top-level directives: =over =item B The definition of repository plugin to be used. =item B The list of available submission targets, each one being composed from the following keys: =over =item B The list of steps to use for this target. =back =item B The definitions of steps, indexed by their identity. =back =head1 SEE ALSO Youri::Config, for additional details about configuration file format. Each used plugin man page, for available options. =head1 COPYRIGHT AND LICENSE Copyright (C) 2002-2006, YOURI project This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use strict; use warnings; use lib '@perllibdir@'; use Youri::Config; use Youri::Utils 0.002; use Pod::Usage; my $config = Youri::Config->new( args => { 'skip-step' => '=s@', 'define' => '=s%', 'timestamp' => '!', 'clean' => '!', 'test' => '|t!', 'list' => '|l!' }, directories => [ "$ENV{HOME}/.youri", '@sysconfdir@/youri' ], file => 'submit.conf', ); if ($config->get_arg('list')) { my $category = $ARGV[0]; pod2usage(-verbose => 0, -message => "No category specified, aborting\n") unless $category; if ($category eq 'targets') { print join(' ', keys %{$config->get_param('targets')}); } elsif ($category eq 'steps') { my $target = $ARGV[1]; pod2usage(-verbose => 0, -message => "No target specified, aborting\n") unless $target; my $steps = $config->get_param('targets')->{$target}->{steps}; print join(' ', @{$steps}) if $steps; } else { pod2usage(-verbose => 0, -message => "Invalid category $category, aborting\n") } print "\n"; exit 0; } if ($config->get_arg('help')) { my $category = $ARGV[0]; my ($item, $section); if ($category eq 'repository') { $section = $config->get_param('repository'); pod2usage( -verbose => 0, -message => "No repository defined, aborting\n" ) unless $section; } elsif ($category eq 'step') { $item = $ARGV[1]; pod2usage( -verbose => 0, -message => "No item specified, aborting\n" ) unless $item; $section = $config->get_param('steps')->{$item}; pod2usage( -verbose => 0, -message => "No such step $item defined, aborting\n" ) unless $section; } else { pod2usage(-verbose => 0, -message => "Invalid category $category, aborting\n") } my $file = $section->{class} . '.pm'; $file =~ s/::/\//g; pod2usage( -verbose => 99, -sections => 'NAME|DESCRIPTION', -input => $file, -pathlist => \@INC ); } pod2usage(-verbose => 0, -message => "No target specified, aborting\n") unless @ARGV > 0; pod2usage(-verbose => 0, -message => "No packages specified, aborting\n") unless @ARGV > 1; # convenient global flags my $test = $config->get_arg('test'); my $verbose = $config->get_arg('verbose'); my $timestamp = $config->get_arg('timestamp'); # test target my $target = shift @ARGV; my $target_conf = $config->get_param('targets')->{$target}; # create repository my $repository; my $repository_conf = $config->get_param('repository'); die "No repository declared\n" unless $repository_conf; log_message("Creating repository", $timestamp) if $verbose; eval { $repository = create_instance( 'Youri::Repository', $repository_conf, { test => $test, verbose => $verbose > 0 ? $verbose - 1 : 0, targets => [ keys %{$config->get_param('targets')} ], } ); }; die "Failed to create repository: $@\n" if $@; # create packages my @packages; foreach my $file (@ARGV) { push( @packages, create_instance( 'Youri::Package', { class => $repository->get_package_class(), }, { file => $file } ) ); } # check all packages pass all tests my %errors; my $skip_step = $config->get_arg('skip-step'); my %skip_step = $skip_step ? map { $_ => 1 } @{$skip_step} : (); eval { foreach my $id (@{$target_conf->{steps}}) { next if $skip_step{$id}; my $step_conf = $config->get_param('steps')->{$id}; die "Invalid configuration, step $id is not defined\n" unless $step_conf; log_message("Creating step $id", $timestamp) if $verbose; my $step; $test = create_instance( 'Youri::Submit::Step', $step_conf, { id => $id, test => $test, verbose => $verbose > 0 ? $verbose - 1 : 0, } ); log_message("Running step $id", $timestamp) if $verbose; $step->run( \@packages $repository, $target, $config->get_arg('define'), ); } }; if ($@) { die "Error during submission: $@\n"; } if ($config->get_arg('clean')) { foreach my $package (@packages) { log_message("cleaning file $package", $timestamp) if $verbose; unlink $package->as_file(); } }