pax_global_header00006660000000000000000000000064123007340750014513gustar00rootroot0000000000000052 comment=8be0e15c55dabc2cd7590926bf19ce69855b0588 specgen-0.0.4/000075500000000000000000000000001230073407500131365ustar00rootroot00000000000000specgen-0.0.4/.gear/000075500000000000000000000000001230073407500141325ustar00rootroot00000000000000specgen-0.0.4/.gear/rules000064400000000000000000000000071230073407500152040ustar00rootroot00000000000000tar: . specgen-0.0.4/.gitignore000064400000000000000000000000201230073407500151160ustar00rootroot00000000000000*~ .*.swp *.bak specgen-0.0.4/Makefile.PL000064400000000000000000000017331230073407500151140ustar00rootroot00000000000000use ExtUtils::MakeMaker; # we need to create the .spec so MM doesn't complain it's missing # from the kit, but it must have an old timestamp or else make # refuses to make it WriteMakefile NAME => "specgen", VERSION_FROM => "specgen", $] < 5.005 ? () : ( AUTHOR => 'Denis Smirnov ', # ABSTRACT_FROM => "specgen", ), EXE_FILES => [ "specgen" ], PREREQ_PM => { # e.g., Module::Name => 1.1 'ExtUtils::MakeMaker' => 5.4302, # 'DBI' => 0, # 'DBD::Pg' => 0, }, dist => { COMPRESS => "gzip -9 -vf", }, ; __END__ package MY; sub processPL { my $self = shift; my $block = $self->SUPER::processPL(@_); # "Version:" in spec needs to match # "$VERSION" from VERSION_FROM $block =~ s%(spec.PL\s*)$%$1 \$\(VERSION_FROM\)%m; $block; } sub libscan { my $self = shift; my $path = shift; ($path =~ / \bCVS\b | \~$ /x) ? undef : $path; } 1; specgen-0.0.4/lib/000075500000000000000000000000001230073407500137045ustar00rootroot00000000000000specgen-0.0.4/lib/Specgen/000075500000000000000000000000001230073407500152705ustar00rootroot00000000000000specgen-0.0.4/lib/Specgen/spec.pm000064400000000000000000000223071230073407500165640ustar00rootroot00000000000000package Specgen::spec; use Specgen::utils; use strict; require Exporter; our @ISA = qw(Exporter); our $VERSION = '0.01'; our @EXPORT = qw(&parse_spec &dump_spec &add_subpackage &spec_body_rewrite); sub spec_optimize_name($) { my $spec = shift; my $n; return $1 if $spec->{name} =~ /^$spec->{basename}-(.+)$/; return '-n ' . $spec->{name}; } sub section_if_exists($$) { my $s = shift; my $sect = shift; my $rc = ''; if ( defined $s->{sections}->{$sect} ) { $rc .= "\n%$sect\n"; $rc .= $s->{sections}->{$sect} if defined $s->{sections}->{$sect}; } foreach my $spec ( sort { $a->{name} cmp $b->{name} } @{ $s->{subpackages} } ) { unless ( not_null( \( $spec->{sections}->{$sect} ) ) ) { # %files section _must_ exists for all subpackages next unless $sect eq 'files'; $spec->{sections}->{$sect} = ''; } my $n = spec_optimize_name($spec); $rc .= "\n%ifarch " . $spec->{if_arch} if defined $spec->{if_arch}; $rc .= "\n%if_with " . $spec->{if_with} if defined $spec->{if_with}; $rc .= "\n%$sect $n\n"; $rc .= $spec->{sections}->{$sect}; $rc .= "%endif\n" if defined $spec->{if_with}; $rc .= "%endif\n" if defined $spec->{if_arch}; } return $rc; } # Разбиваем спек-файл на строки sub parse_spec_strings($) { my $t = shift; my @tmp = split( "\n", $t ); my @out; # skip empty strings while ( defined $tmp[0] and $tmp[0] =~ /^\s*$/ ) { shift(@tmp); } my %rc; my @if; my $mode = 1; foreach (@tmp) { my @if_tmp = @if; my %line; if ( $_ =~ /^%if_?arch\s+([^\s]+)/ ) { $rc{ifarch} = $1, $mode = 0, next if $mode; push @if, "%ifarch $1"; } elsif ( $_ =~ /^%if_?narch\s+([^\s]+)/ ) { push @if, "%ifnarch $1"; } elsif ( $_ =~ /^%if_with\s+([^\s]+)/ ) { $rc{ifwith} = $1, $mode = 0, next if $mode; push @if, "%if_with $1"; } elsif ( $_ =~ /^%endif\s*$/ ) { pop @if; } else { $mode = 0; } $line{text} = $_; $line{if} = \@if_tmp; push @out, \%line; } $rc{lines} = \@out; my @rc = ( \@tmp, \%rc, \@out ); return @rc; } sub parse_spec($) { my %spec; my $t = shift; # разбиваем на строки my ( $tmp, $specinfo, $lines ) = parse_spec_strings($t); my @tmp = @$tmp; $spec{if_with} = $specinfo->{ifwith} if defined $specinfo->{ifwith}; $spec{if_arch} = $specinfo->{ifarch} if defined $specinfo->{ifarch}; # разбиваем на секции $t = ''; my $section = ''; my $params = ''; my @text; foreach my $str (@$lines) { my $s = $str->{text}; $s =~ s/\s+$//; next if $s =~ /^\#/; next if $s eq '' and $section ne 'changelog'; if ( $s =~ /%(changelog|preun|pre|post|files|install|build|prep)\s*$/ ) { $section = $1; $params = ''; next; } elsif ( $s =~ /%description\s*(?:-l\s*([^\s]+))?\s*$/ ) { $section = 'description'; $params = $1 || 'default'; } elsif ( $section eq '' ) { $spec{name} = $1, next if $s =~ s/^Name:\s*(.*)$//im; $spec{version} = $1, next if $s =~ s/^Version:\s*(.*)$//im; $spec{release} = $1, next if $s =~ s/^Release:\s*(.*)$//im; $spec{license} = $1, next if $s =~ s/^License:\s*(.*)$//im; $spec{group} = $1, next if $s =~ s/^Group:\s*(.*)$//im; $spec{buildarch} = $1, next if $s =~ s/^BuildArch:\s*(.*)$//im; $spec{summary} = $1, next if $s =~ s/^Summary:\s*(.*)$//im; $str->{text} =~ s/\s+$//; push @text, $str; } else { if ( $section eq 'description' ) { $spec{description}->{$params} .= $s . "\n"; } else { $spec{sections}->{$section} .= $s . "\n"; } } } # parse %files section if ( defined $spec{sections}->{files} ) { my $f = $spec{sections}->{files}; my @f = split( /\n/, $f ); my @f2; local $_; foreach (@f) { my $is_dir = 0; my $attr = ''; s/^\s+//; $is_dir = 1 if s/^%dir\s*//; $attr = $1 if s/^%attr\(([^\)]+)\)\s*//; $is_dir = 1 if s/^%dir\s*//; $is_dir = 1 if s/\/$//; $_ = "\%attr($attr) $_" if $attr ne ''; $_ = "\%dir $_" if $is_dir != 0; push @f2, $_; } $spec{sections}->{files} = join( "\n", @f2 ) . "\n"; } $spec{description}->{default} = $spec{summary} unless defined $spec{description}->{default}; # cleanup body @tmp = split( "\n", $t ); $t = ''; foreach my $str (@text) { my $s = $str->{text}; next if $s =~ /^\#/; next if $s eq ''; if ( $s =~ /^BuildPreReq:/ ) { push @{ $spec{BuildPreReq} }, $str; next; } if ( $s =~ /^BuildRequires:/ ) { push @{ $spec{BuildRequires} }, $str; next; } $t .= $s . "\n"; } $spec{text} = $t; return \%spec; } sub dump_spec($) { my $t = shift; my $rc = ''; sub t($$$) { my $t = shift; my $c = shift; my $f = shift; return '' unless defined $t->{$f}; return "$c: " . $t->{$f} . "\n"; } $rc = '#' . ('=' x 76) ."\n"; $rc .= "# Please do not edit!\n"; $rc .= "# Created by specgen utility from files in specs/ subdir\n"; $rc .= '#' . ('=' x 76) ."\n"; $rc .= t( $t, 'Name', 'name' ); $rc .= t( $t, 'Summary', 'summary' ); $rc .= t( $t, 'Version', 'version' ); $rc .= t( $t, 'Release', 'release' ); $rc .= t( $t, 'License', 'license' ); $rc .= t( $t, 'Group', 'group' ); $rc .= t( $t, 'BuildArch', 'buildarch' ); sub dump_requires($) { my $t = shift; my $rc = ''; foreach ( @{ $t->{BuildRequires} } ) { my $s = $_->{text}; my $if = $_->{if}; my $l = @$if; foreach my $i (@$if) { $rc .= $i . "\n"; } $rc .= $s . "\n"; $rc .= "\%endif\n" while $l--; } foreach ( @{ $t->{BuildPreReq} } ) { my $s = $_->{text}; my $if = $_->{if}; my $l = @$if; foreach my $i (@$if) { $rc .= $i . "\n"; } $rc .= $s . "\n"; $rc .= "\%endif\n" while $l--; } return $rc; } $rc .= dump_requires($t); foreach my $spec ( @{ $t->{subpackages} } ) { $rc .= dump_requires($spec); } $rc .= $t->{text} . "\n"; sub dump_description($$) { my $spec = shift; my $n = shift; my $rc; my $dhash = $spec->{description}; foreach my $k ( sort keys %$dhash ) { my $desc = $dhash->{$k}; $rc .= "\n%description"; $rc .= " $n" unless $n eq ''; $rc .= " -l $k" unless $k eq 'default'; $rc .= "\n"; $rc .= $desc . "\n"; } return $rc; } foreach my $spec ( sort { $a->{name} cmp $b->{name} } @{ $t->{subpackages} } ) { my $n = spec_optimize_name($spec); $rc .= "\n%ifarch " . $spec->{if_arch} if defined $spec->{if_arch}; $rc .= "\n%if_with " . $spec->{if_with} if defined $spec->{if_with}; $rc .= "\n%package $n\n"; $rc .= "Summary: " . $spec->{summary} . "\n"; $rc .= "Group: " . $spec->{group} . "\n"; $rc .= t( $spec, 'BuildArch', 'buildarch' ); $rc .= $spec->{text}; $rc .= dump_description( $spec, $n ); $rc .= "%endif\n" if defined $spec->{if_with}; $rc .= "%endif\n" if defined $spec->{if_arch}; } $rc .= dump_description( $t, '' ); # %files sections $rc .= section_if_exists( $t, 'prep' ); $rc .= section_if_exists( $t, 'build' ); $rc .= section_if_exists( $t, 'install' ); $rc .= section_if_exists( $t, 'preun' ); $rc .= section_if_exists( $t, 'pre' ); $rc .= section_if_exists( $t, 'post' ); $rc .= section_if_exists( $t, 'files' ); $rc .= "\n%changelog\n" . $t->{sections}->{changelog} . "\n"; return $rc; } sub add_subpackage($$) { my $spec = shift; my $add = shift; $add->{basename} = $spec->{name}; push @{ $spec->{subpackages} }, $add; } sub spec_body_rewrite($) { my $spec = shift; # rewrite body my @tmp = split( "\n", $spec->{text} ); $spec->{text} = ''; foreach my $s (@tmp) { $s =~ s/\s+$//; next if $s =~ /^\#/; next if $s eq ''; if ( $s =~ /^[a-zA-Z\(\)]+:.*$/ ) { $spec->{text} .= $s . "\n"; } elsif ( $s =~ /^%/ ) { $spec->{text} .= $s . "\n"; } else { $spec->{text} .= "Requires: " . $s . "\n"; } } } 1; specgen-0.0.4/lib/Specgen/utils.pm000064400000000000000000000010631230073407500167660ustar00rootroot00000000000000package Specgen::utils; use strict; require Exporter; our @ISA = qw(Exporter); our $VERSION = '0.01'; our @EXPORT = qw(&readfile &file_write ¬_null); sub readfile($) { my $tmp; my $fh; open( $fh, "< $_[0]" ) || die; local $/; $tmp = <$fh>; close($fh); return $tmp; } sub file_write($$) { my $fn = shift; my $txt = shift; my $fh; open( $fh, "> $fn" ); print $fh $txt; close($fh); } sub not_null($) { my $a = shift; return 0 if not defined $$a; return 0 if $$a eq ''; return 1; } 1; specgen-0.0.4/specgen000075500000000000000000000022141230073407500145070ustar00rootroot00000000000000#!/usr/bin/perl -w use strict; use Specgen::utils; use Specgen::spec; sub spec_load($) { my $name = shift; my $t = readfile($name); $name =~ s/^(.*\/)?specs\///; $name =~ s/\//-/g; $name =~ s/\.spec$//; my $spec = parse_spec($t); $spec->{name} = $name unless defined $spec->{name}; $spec->{text} =~ s/\s+$//s; return $spec; } my @specs; my $main; sub read_specs($); sub read_specs($) { my $dir = shift; my @dirs; foreach my $name ( glob("$dir/*") ) { if ( -d $name ) { push @dirs, $name; next; } next unless $name =~ /\.spec$/; my $spec = spec_load($name); $spec->{description}->{default} =~ s/%summary/$spec->{summary}/; if ( defined $spec->{sections}->{changelog} ) { $main = $spec; } else { push @specs, $spec; } } read_specs($_) foreach @dirs; } read_specs("specs"); foreach my $spec (@specs) { spec_body_rewrite($spec); $spec->{group} = $main->{group} unless defined $spec->{group}; add_subpackage( $main, $spec ); } file_write( $main->{name} . ".spec", dump_spec($main) ); specgen-0.0.4/specgen.spec000064400000000000000000000017161230073407500154430ustar00rootroot00000000000000Name: specgen Version: 0.0.4 Release: alt1 BuildArch: noarch Summary: Create spec file from multiple specs Group: Development/Other License: GPL Url: http://sisyphus.ru/ru/srpm/Sisyphus/specgen Packager: Denis Smirnov Source: %name-%version.tar # Automatically added by buildreq on Fri Sep 18 2009 (-bb) BuildRequires: perl-devel %description %summary %prep %setup %build %perl_vendor_build %install %perl_vendor_install %files %_bindir/* %perl_vendor_privlib/Specgen #perl_vendor_archlib/* #perl_vendor_autolib/* #perl_vendor_man3dir/* %changelog * Tue Feb 18 2014 Denis Smirnov 0.0.4-alt1 - add comment to autogenerated specs * Sun Jul 25 2010 Denis Smirnov 0.0.3-alt1 - some more fixes * Sun Jul 25 2010 Denis Smirnov 0.0.2-alt1 - more correct support for ifarch/if_with * Wed Dec 02 2009 Denis Smirnov 0.0.1-alt1 - first build for Sisyphus