bluto

Release package and announcement generator
Info | Log | Files | Refs | README | LICENSE

commit d77e7de8320ef675bc2600e77724f981e18b5068
parent 573bca1ac7b2b8410b382ddb12d98924150e27a9
Author: lash <dev@holbrook.no>
Date:   Wed, 19 Jun 2024 15:17:33 +0100

Factor out config process, add create archive

Diffstat:
ABluto.pm | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ABluto/Archive.pm | 48++++++++++++++++++++++++++++++++++++++++++++++++
ABluto/Git.pm | 5+++++
ABluto/RSS.pm | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mto_std.pl | 185+++----------------------------------------------------------------------------
5 files changed, 274 insertions(+), 179 deletions(-)

diff --git a/Bluto.pm b/Bluto.pm @@ -0,0 +1,139 @@ +package Bluto; + +use File::Basename qw/ basename /; +use SemVer; + +use Log::Term::Ansi qw/error info debug warn trace/; +use Bluto::Archive; + +use constant { VCS_TAG_PREFIX => 'v' }; + +my %config; +my @m_tech; +my @m_url; +my @m_vcs; +my @m_src; +my @m_author_maintainer = [undef, undef]; +my @m_author_origin = [undef, undef]; +my %m_main = ( + name => undef, + slug => undef, + version => undef, + summary => undef, + license => undef, + tag_prefix => VCS_TAG_PREFIX, + changelog => '', + time => undef, + tech_main => undef, + tech => \@m_tech, + vcs => \@m_vcs, + url => \@m_url, + src => \@m_src, + author_maintainer => \@m_author_maintainer, + author_origin => \@m_author_origin, +); +my $have_version_match = undef; + +sub from_config { + my $cfg = shift; + my $src_dir = shift; + my $version; + if (defined $cfg->{version}) { + $version = $cfg->{version}; + } else { + $fn = File::Spec->catfile($src_dir, 'VERSION'); + open(my $f, "<$fn") or error("no version file found") && return undef; + $version = <$f>; + close($f); + $version = SemVer->new($version); + } + info('using version ' . $version); + + $m_main{name} = $cfg->param('main.name'); + #$m_main{version} = $cfg->param('main.version'); + $m_main{version} = $version; + $m_main{slug} = $cfg->param('main.slug'); + $m_main{summary} = $cfg->param('main.summary'); + $m_main{license} = $cfg->param('main.license'); + $m_main{author_maintainer}[0] = $cfg->param('author:maintainer.name') . " <" . $cfg->param('author:maintainer.email') . ">"; + $m_main{author_maintainer}[1] = $cfg->param('author:maintainer.pgp'); + + my $feed_file = File::Spec->catfile( $feed_dir, $m_main{slug} ) . ".rss"; + + if (!defined $cfg->param('author:origin')) { + $m_main{author_origin}[0] = $m_main{author_maintainer}[0]; + $m_main{author_origin}[1] = $m_main{author_maintainer}[1]; + } + + if (defined $cfg->param('vcs.tag_prefix')) { + $m_main{tag_prefix} = $cfg->param('vcs.tag_prefix'); + + } + + foreach my $v ( $cfg->param('locate.url') ) { + warn('not checking url formatting for ' . $v); + push(@m_url, $v); + } + + foreach my $v ( $cfg->param('locate.vcs') ) { + warn('not checking git formatting for ' . $v); + push(@m_vcs, $v); + } + + foreach my $k ($cfg->vars()) { + if ($k =~ /^changelog\.(.+)$/) { + if ($m_main{version} eq $1) { + if (defined $have_version_match) { + croak('already have version defined for ' . $1); + } + debug('found version match in changelog for ' . $1); + + $have_version_match = SemVer->new($1); + } + } + } + + + my $targz = Bluto::Archive::create($m_main{slug}, $m_main{version}, $m_main{tag_prefix}, $src_dir); + if (!defined $targz) { + return undef; + } + my @targz_stat = stat ( $targz ); + $m_main{time} = DateTime->from_epoch( epoch => $targz_stat[9] )->stringify(); + foreach my $v ( $cfg->param('locate.tgzbase') ) { + warn('not checking targz base formatting for ' . $v); + my $src = $m_main{slug} . '/' . basename($targz); + push(@m_src, $v . '/' . $src); + } + + # process changelog entry + my $body = ''; + if (!defined $have_version_match) { + error("no changelog found for version " . $m_main{version}); + return undef; + } else { + # TODO: else should look for targz filename dot txt and include literal + if ($cfg->param('changelog.' . $have_version_match) =~ '^sha256:(.*)$' ) { + my $fp = File::Spec->catfile ( $content_dir, $1 ); + debug('resolve sha256 content ' . $1 . ' for ' . $have_version_match . ' from ' . $fp); + open(my $f, "<$fp") or die ('cannot open content read from: ' . $fp); + while (<$f>) { + $m_main{changelog} .= $_; + } + } + } + + + return $have_version_match; +} + +sub get_announcement() { + my $tt = Template->new({ + INCLUDE_PATH => '.', + INTERPOLATE => 1, + }); + my $out; + $tt->process('base.tt', \%m_main, \$out) or croak($tt->error()); +} + +1; diff --git a/Bluto/Archive.pm b/Bluto/Archive.pm @@ -0,0 +1,48 @@ +package Bluto::Archive; + +use Cwd; +use Log::Term::Ansi qw/error info debug warn trace/; + +sub create { + my $slug = shift; + my $version = shift; + my $git_prefix = shift; + my $src_dir = shift; + + my $old_dir = cwd; + + chdir($src_dir); + + my $targz = $slug . '-' . $version . '.tar.gz'; + my $targz_local = File::Spec->catfile($src_dir, $targz); + if (! -f $targz_local ) { + #croak("no package file found, looked for: " . $targz); + debug("no package file found, looked for: " . $targz); + + my @cmd = ('git', 'archive', $git_prefix . $version, '--format', 'tar.gz', '-o', $targz); + system(@cmd); + if ($?) { + error("package file generation fail: " . $e); + unlink($targz); + return undef; + } + +# my $cmd = Git::Repository::Command(['git', 'archive', '--format=tar.gz', '-o', $targz]); +# my $e = $cmd->stderr(); +# $cmd->close(); +# if ($cmd->exit()) { +# error("package file generation fail: " . $e); +# } + + if (! -f $targz_local ) { + error("package generation reported ok but still no file"); + return undef; + } + } + + chdir($old_dir); + + return $targz_local; +} + +1; diff --git a/Bluto/Git.pm b/Bluto/Git.pm @@ -0,0 +1,5 @@ +package Bluto::Git; + +use Git::Repository::Command; + +1; diff --git a/Bluto/RSS.pm b/Bluto/RSS.pm @@ -0,0 +1,76 @@ +package Bluto::RSS; + +use DateTime; + +use XML::RSS; +use Template; + +use Log::Term::Ansi qw/error info debug warn trace/; + + +sub to_file() { + my $rss_title = $m_main{slug} . ' ' . $m_main{version}; + my $rss; + $rss = XML::RSS->new; + if ( -f $feed_file ) { + info('found existing feed file ' . $feed_file); + $rss->parsefile( $feed_file ); + foreach my $v ( @{$rss->{items}} ) { + debug('rss contains: ' . $v->{title}); + if ($v->{title} eq $rss_title) { + die('already have rss entry for ' . $rss_title); + } + } + } else { + info('starting new feed file ' . $feed_file); + $rss = XML::RSS->new(version => '1.0'); + $rss->channel ( + title => $m_main{name}, + link => $m_main{git_upstream}, + description => $m_main{summary}, + dc => { + date => DateTime->now()->stringify(), + creator => $m_main{author_maintainer}, + publisher => "$0 " . SemVer->new(VERSION). " (perl $^V)", + }, + # subject => "Linux Software", + # creator => 'scoop@freshmeat.net', + # publisher => 'scoop@freshmeat.net', + # rights => 'Copyright 1999, Freshmeat.net', + # language => 'en-us', + # }, + # taxo => [ + # 'http://dmoz.org/Computers/Internet', + # 'http://dmoz.org/Computers/PC' + # ] + ); + } + + # check if we already have the title + foreach my $item ( $rss->{items}) { + if ( defined $item->[0] && $item->[0]{title} eq $rss_title ) { + die('already have published record for ' . $rss_title); + } + } + + $rss->add_item ( + title => $rss_title, + link => $targz, + description => $out, + dc => { + date => $m_main{time}, + }, + # dc => { + # subject => "X11/Utilities", + # creator => "David Allen (s2mdalle at titan.vcu.edu)", + # }, + # taxo => [ + # 'http://dmoz.org/Computers/Internet', + # 'http://dmoz.org/Computers/PC' + # ] + ); + + $rss->save($feed_file); +} + +1; diff --git a/to_std.pl b/to_std.pl @@ -11,10 +11,6 @@ use File::Temp qw/ tempdir /; use File::Basename qw/ dirname /; use File::Spec qw/ catfile /; use Cwd qw/ getcwd abs_path /; -use Template; -use SemVer; -use XML::RSS; -use DateTime; # external imports use Config::Simple; @@ -22,35 +18,14 @@ use Config::Simple; # local imports use lib dirname(abs_path($0)); use Log::Term::Ansi qw/error info debug warn trace/; +use Bluto; +use Bluto::RSS; sub croak { die(shift); } # TODO: export to perl modules -my %config; -my @m_tech; -my @m_url; -my @m_vcs; -my @m_src; -my @m_author_maintainer = [undef, undef]; -my @m_author_origin = [undef, undef]; -my %m_main = ( - name => undef, - slug => undef, - version => undef, - summary => undef, - license => undef, - changelog => '', - time => undef, - tech_main => undef, - tech => \@m_tech, - vcs => \@m_vcs, - url => \@m_url, - src => \@m_src, - author_maintainer => \@m_author_maintainer, - author_origin => \@m_author_origin, -); my $src_dir = File::Spec->catfile(getcwd, '.bluto'); my $out_dir = getcwd; @@ -70,158 +45,10 @@ my $fn = File::Spec->catfile($src_dir, 'bluto.ini'); debug("import from " . $fn); my $cfg = new Config::Simple($fn); -my $version; -if (defined $cfg->{version}) { - $version = $cfg->{version}; -} else { - $fn = File::Spec->catfile($src_dir, 'VERSION'); - open(my $f, "<$fn") or die("no version file found"); - $version = <$f>; - close($f); - $version = SemVer->new($version); -} -info('using version ' . $version); - -$m_main{name} = $cfg->param('main.name'); -#$m_main{version} = $cfg->param('main.version'); -$m_main{version} = $version; -$m_main{slug} = $cfg->param('main.slug'); -$m_main{summary} = $cfg->param('main.summary'); -$m_main{license} = $cfg->param('main.license'); -$m_main{author_maintainer}[0] = $cfg->param('author:maintainer.name') . " <" . $cfg->param('author:maintainer.email') . ">"; -$m_main{author_maintainer}[1] = $cfg->param('author:maintainer.pgp'); - -my $feed_file = File::Spec->catfile( $feed_dir, $m_main{slug} ) . ".rss"; - -if (!defined $cfg->param('author:origin')) { - $m_main{author_origin}[0] = $m_main{author_maintainer}[0]; - $m_main{author_origin}[1] = $m_main{author_maintainer}[1]; -} - -foreach my $v ( $cfg->param('locate.url') ) { - warn('not checking url formatting for ' . $v); - push(@m_url, $v); -} - -foreach my $v ( $cfg->param('locate.vcs') ) { - warn('not checking git formatting for ' . $v); - push(@m_vcs, $v); -} - -my $have_version_match = undef; -foreach my $k ($cfg->vars()) { - if ($k =~ /^changelog\.(.+)$/) { - if ($m_main{version} eq $1) { - if (defined $have_version_match) { - croak('already have version defined for ' . $1); - } - debug('found version match in changelog for ' . $1); - - $have_version_match = SemVer->new($1); - } - } -} -my $targz = $m_main{slug} . '-' . $have_version_match . '.tar.gz'; -my $targz_local = File::Spec->catfile($src_dir, $targz); -if (! -f $targz_local ) { - #croak("no package file found, looked for: " . $targz); - debug("no package file found, looked for: " . $targz); -} -my @targz_stat = stat ( $targz_local ); -$m_main{time} = DateTime->from_epoch( epoch => $targz_stat[9] )->stringify(); -foreach my $v ( $cfg->param('locate.tgzbase') ) { - warn('not checking targz base formatting for ' . $v); - my $src = $m_main{slug} . '/' . $targz; - push(@m_src, $v . '/' . $src); -} - -my @change = $cfg->vars(); - +my $version = Bluto::from_config($cfg, $src_dir); -# process changelog entry -my $body = ''; -if (!defined $have_version_match) { - croak("no changelog found for version " . $m_main{version}); -} else { - # TODO: else should look for targz filename dot txt and include literal - if ($cfg->param('changelog.' . $have_version_match) =~ '^sha256:(.*)$' ) { - my $fp = File::Spec->catfile ( $content_dir, $1 ); - debug('resolve sha256 content ' . $1 . ' for ' . $have_version_match . ' from ' . $fp); - open(my $f, "<$fp") or die ('cannot open content read from: ' . $fp); - while (<$f>) { - $m_main{changelog} .= $_; - } - } +if (!defined $version) { + die("config processing failed"); } - -my $tt = Template->new({ - INCLUDE_PATH => '.', - INTERPOLATE => 1, - }); -my $out; -$tt->process('base.tt', \%m_main, \$out) or croak($tt->error()); - - -my $rss_title = $m_main{slug} . ' ' . $m_main{version}; -my $rss; -$rss = XML::RSS->new; -if ( -f $feed_file ) { - info('found existing feed file ' . $feed_file); - $rss->parsefile( $feed_file ); - foreach my $v ( @{$rss->{items}} ) { - debug('rss contains: ' . $v->{title}); - if ($v->{title} eq $rss_title) { - die('already have rss entry for ' . $rss_title); - } - } -} else { - info('starting new feed file ' . $feed_file); - $rss = XML::RSS->new(version => '1.0'); - $rss->channel ( - title => $m_main{name}, - link => $m_main{git_upstream}, - description => $m_main{summary}, - dc => { - date => DateTime->now()->stringify(), - creator => $m_main{author_maintainer}, - publisher => "$0 " . SemVer->new(VERSION). " (perl $^V)", - }, - # subject => "Linux Software", - # creator => 'scoop@freshmeat.net', - # publisher => 'scoop@freshmeat.net', - # rights => 'Copyright 1999, Freshmeat.net', - # language => 'en-us', - # }, - # taxo => [ - # 'http://dmoz.org/Computers/Internet', - # 'http://dmoz.org/Computers/PC' - # ] - ); -} - -# check if we already have the title -foreach my $item ( $rss->{items}) { - if ( defined $item->[0] && $item->[0]{title} eq $rss_title ) { - die('already have published record for ' . $rss_title); - } -} - -$rss->add_item ( - title => $rss_title, - link => $targz, - description => $out, - dc => { - date => $m_main{time}, - }, -# dc => { - # subject => "X11/Utilities", - # creator => "David Allen (s2mdalle at titan.vcu.edu)", - # }, - # taxo => [ - # 'http://dmoz.org/Computers/Internet', - # 'http://dmoz.org/Computers/PC' - # ] -); - -$rss->save($feed_file); +#my @change = $cfg->vars();