Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:adrianSuSE
build
spec_add_patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File spec_add_patch of Package build
#!/usr/bin/perl -w # vim:sw=4:et # Author: Dirk Mueller ################################################################ # # Copyright (c) 1995-2014 SUSE Linux Products GmbH # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or 3 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program (see the file COPYING); if not, write to the # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # ################################################################ use strict; sub helpexit { print "$0: <patches...> [file.spec]\n"; exit 1; } my $specname; my %diffs; for my $arg (@ARGV) { if ($arg =~ /\.spec$/) { helpexit() if $specname; $specname = $arg; next; } $diffs{$arg} = 1; } sub find_specfile() { opendir(D, "."); my @specs = grep { /\.spec$/ } readdir(D); closedir(D); # choose the one with the shortest name (heuristic) $specname = ( sort { length($a) - length($b) } @specs)[0]; } if (!defined($specname) || ! -f $specname) { &find_specfile(); } open(S, '<', $specname) or die; my $ifdef_level = 0; my $in_prep = 0; my $in_global = 1; my $autopatch = 0; my $last_patch_in_prep_index = 0; my $last_patch_in_global_index = 0; my $last_source_in_global_index = 0; my @c = (); my $index = 0; # first read the specfile, parse useful information while(<S>) { if(/^\s*%\s*endif/) { $ifdef_level--; $last_patch_in_prep_index = $index if ($in_prep && $ifdef_level == 0); } die if ($ifdef_level < 0); $ifdef_level++ if(/^\s*%\s*if/); if ($ifdef_level == 0 && !$in_prep && $in_global && /^\%(?:prep|build|install|package|description|doc)/) { $in_global = 0; } if (!$in_prep && /^%prep/i) { $in_prep = 1; die if ($in_global); } if ($in_prep && /^%auto(patch|setup)\b/) { $autopatch = 1; } if ($in_prep && /^%setup\b/) { $last_patch_in_prep_index = $index; } if ($in_prep && /^\%(?:build|install|package|description|doc)/) { $in_prep = 0; } die if (($in_prep + $in_global) > 1); if ($in_global && /^Patch(?:\d+)?:\s+(.+)/) { $last_patch_in_global_index = $index; if ($diffs{$1}) { print "$1 already in, skipped."; delete $diffs{$1}; } } if ($in_global && $ifdef_level == 0 && /^Source(?:\d+)?:/) { $last_source_in_global_index = $index; } if ($in_prep && $ifdef_level == 0 && /^\%patch/) { $last_patch_in_prep_index = $index; } push(@c, $_); $index++; } close(S); # append after last Source if this spec doesn't have any Patches if ($last_patch_in_global_index == 0) { $last_patch_in_global_index = $last_source_in_global_index; } die if ($ifdef_level > 0); die if ($in_global || $in_prep); die if ($last_patch_in_prep_index == 0 && !$autopatch); die if ($last_patch_in_global_index == 0); #print "adding Patch: $diffname to line $last_patch_in_global_index\n"; #print "adding %patch to line $last_patch_in_prep_index\n"; # determine patch number my $patchnum = 0; $patchnum = $1+1 if ($c[$last_patch_in_global_index] =~ /Patch(\d+):/); $patchnum = 1 if ($c[$last_patch_in_global_index] =~ /Patch:/); for my $diffname (keys %diffs) { # determine strip level my $striplevel = ""; open(P, '<', $diffname) or die "$diffname: $!\n"; while(<P>) { # Check if either the --- filename starts with 'a/' or the +++ # filename starts with 'b/', or either starts with a package # name/version prefix. We have to check for either, because either # of them could be /dev/null if a file is being added or # deleted. $striplevel = " -p1" if m,^--- a/, or m,^\+\+\+ b/, or m,^(---|\+\+\+) [^/]+-\d+\.,; last if (/^@@ -\d/); } close(P); print "Adding patch$striplevel $diffname to $specname\n"; splice @c, $last_patch_in_prep_index+1, 0, ("\%patch$patchnum$striplevel\n") unless $autopatch; splice @c, $last_patch_in_global_index+1, 0, (sprintf "Patch%s:%s%s\n", $patchnum, ' ' x (10-length($patchnum)), $diffname); ++$last_patch_in_global_index; $last_patch_in_prep_index+=2; # actually line number ++$patchnum; } open(O, '>', "$specname.new") or die; print O @c; close(O); system("diff", "-u", $specname, "$specname.new"); rename("$specname.new", $specname);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor