mirror of
https://github.com/rpm-software-management/tito.git
synced 2025-02-23 12:12:47 +00:00
add new build class distributionbuilder
This commit is contained in:
parent
8c812d0854
commit
64fdac6c79
5 changed files with 223 additions and 30 deletions
139
bin/generate-patches.pl
Executable file
139
bin/generate-patches.pl
Executable file
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
use Getopt::Long ();
|
||||
use IPC::Open3 ();
|
||||
|
||||
my $target_directory;
|
||||
|
||||
sub usage {
|
||||
die "Usage: $0 -d target_directory package_name start_version_release end_version_release [commit_id]\n";
|
||||
}
|
||||
|
||||
sub check_git_tag {
|
||||
my $tag = join_tag_parts(@_);
|
||||
my ($wtr, $rdr);
|
||||
|
||||
my $pid = IPC::Open3::open3($wtr, $rdr, undef, 'git', 'tag', '-l', $tag);
|
||||
close($wtr);
|
||||
my $check = <$rdr>;
|
||||
close($rdr);
|
||||
if (waitpid($pid, 0) < 0) {
|
||||
die "Error checking for tag [$tag], process died: $!\n";
|
||||
}
|
||||
if (not defined $check) {
|
||||
return;
|
||||
}
|
||||
chomp $check;
|
||||
if ($check eq $tag) {
|
||||
return 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sub split_version_to_parts {
|
||||
my $version = shift;
|
||||
my @parts1 = split /-/, $version;
|
||||
my @parts2;
|
||||
for my $p (@parts1) {
|
||||
push @parts2, [ split /\./, $p ];
|
||||
}
|
||||
return @parts2;
|
||||
}
|
||||
|
||||
sub join_tag_parts {
|
||||
my @parts = @_;
|
||||
for my $p (@parts) {
|
||||
if (ref $p) {
|
||||
$p = join '.', @$p;
|
||||
}
|
||||
}
|
||||
return join '-', @parts;
|
||||
}
|
||||
|
||||
if (not Getopt::Long::GetOptions('dir=s' => \$target_directory)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if (not defined $target_directory) {
|
||||
usage();
|
||||
}
|
||||
|
||||
my ($package, $start_version, $end_version, $commit_id) = @ARGV;
|
||||
|
||||
if (not defined $end_version) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if (not -d $target_directory) {
|
||||
die "The target directory [$target_directory] does not exist.\n";
|
||||
}
|
||||
|
||||
if (not check_git_tag($package, $start_version)) {
|
||||
die "Start tag [$package-$start_version] does not exist.\n";
|
||||
}
|
||||
if (not check_git_tag($package, $end_version)) {
|
||||
die "End tag [$package-$end_version] does not exist.\n";
|
||||
}
|
||||
|
||||
my @start_version = split_version_to_parts($start_version);
|
||||
my @end_version = split_version_to_parts($end_version);
|
||||
|
||||
if (@start_version != 2) {
|
||||
die "Start version needs to have two segments (version-release).\n";
|
||||
}
|
||||
if ("@{$start_version[1]}" ne "1") {
|
||||
die "The start second segment (release) has to be 1.\n";
|
||||
}
|
||||
if (@end_version < @start_version) {
|
||||
die "End version needs to have the same or more segments than the start version..\n";
|
||||
}
|
||||
if ("@{$start_version[0]}" ne "@{$end_version[0]}") {
|
||||
die "The first segment (version) has to match.\n";
|
||||
}
|
||||
|
||||
my @path;
|
||||
|
||||
unshift @path, join_tag_parts($package, @end_version);
|
||||
while ("@{$end_version[1]}" ne "1") {
|
||||
my @release = @{$end_version[1]};
|
||||
if ($release[-1] eq '0') {
|
||||
splice @release, $#release;
|
||||
} elsif ($release[-1] =~ /^[0-9]+$/) {
|
||||
$release[-1] -= 1;
|
||||
} else {
|
||||
# drop non-numerical segment
|
||||
splice @release, $#release;
|
||||
}
|
||||
$end_version[1] = \@release;
|
||||
my $tag = join_tag_parts($package, @end_version);
|
||||
if (check_git_tag($tag)) {
|
||||
unshift @path, $tag;
|
||||
}
|
||||
}
|
||||
|
||||
while (@end_version > @start_version) {
|
||||
splice @end_version, $#end_version;
|
||||
my $tag = join_tag_parts($package, @end_version);
|
||||
if (check_git_tag($tag)) {
|
||||
unshift @path, $tag;
|
||||
}
|
||||
}
|
||||
|
||||
for (my $i = 0; $i < @path - 1; $i++) {
|
||||
my $patch_name = "$path[$i]-to-$path[$i + 1].patch";
|
||||
system "git diff --relative $path[$i]..$path[$i + 1] > $target_directory/$patch_name";
|
||||
print "$patch_name\n";
|
||||
}
|
||||
|
||||
if (defined $commit_id) {
|
||||
my $patch_name = "$path[$#path]-to-$package-git-$commit_id.patch";
|
||||
system "git diff --relative $path[$#path]..$commit_id > $target_directory/$patch_name";
|
||||
if (-s "$target_directory/$patch_name") {
|
||||
print "$patch_name\n";
|
||||
} else {
|
||||
unlink "$target_directory/$patch_name";
|
||||
}
|
||||
}
|
1
setup.py
1
setup.py
|
@ -40,6 +40,7 @@ setup(
|
|||
'bin/bump-version.pl',
|
||||
'bin/tar-fixup-stamp-comment.pl',
|
||||
'bin/test-setup-specfile.pl',
|
||||
'bin/generate-patches.pl'
|
||||
],
|
||||
|
||||
classifiers = [
|
||||
|
|
|
@ -933,37 +933,10 @@ class UpstreamBuilder(NoTgzBuilder):
|
|||
|
||||
self.patch_upstream()
|
||||
|
||||
def patch_upstream(self):
|
||||
def _patch_upstream(self):
|
||||
""" Insert patches into the spec file we'll be building
|
||||
returns (patch_number, patch_insert_index, patch_apply_index, lines)
|
||||
"""
|
||||
Generate patches for any differences between our tag and the
|
||||
upstream tag, and apply them into an exported copy of the
|
||||
spec file.
|
||||
"""
|
||||
patch_filename = "%s-to-%s-%s.patch" % (self.upstream_tag,
|
||||
self.project_name, self.build_version)
|
||||
patch_file = os.path.join(self.rpmbuild_gitcopy,
|
||||
patch_filename)
|
||||
patch_dir = self.git_root
|
||||
if self.relative_project_dir != "/":
|
||||
patch_dir = os.path.join(self.git_root,
|
||||
self.relative_project_dir)
|
||||
os.chdir(patch_dir)
|
||||
debug("patch dir = %s" % patch_dir)
|
||||
print("Generating patch [%s]" % patch_filename)
|
||||
debug("Patch: %s" % patch_file)
|
||||
patch_command = "git diff --relative %s..%s > %s" % \
|
||||
(self.upstream_tag, self.git_commit_id,
|
||||
patch_file)
|
||||
debug("Generating patch with: %s" % patch_command)
|
||||
output = run_command(patch_command)
|
||||
print(output)
|
||||
# Creating two copies of the patch here in the temp build directories
|
||||
# just out of laziness. Some builders need sources in SOURCES and
|
||||
# others need them in the git copy. Being lazy here avoids one-off
|
||||
# hacks and both copies get cleaned up anyhow.
|
||||
run_command("cp %s %s" % (patch_file, self.rpmbuild_sourcedir))
|
||||
|
||||
# Insert patches into the spec file we'll be building:
|
||||
f = open(self.spec_file, 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
@ -998,11 +971,47 @@ class UpstreamBuilder(NoTgzBuilder):
|
|||
debug("patch_apply_index = %s" % patch_apply_index)
|
||||
if patch_insert_index == 0 or patch_apply_index == 0:
|
||||
error_out("Unable to insert PatchX or %patchX lines in spec file")
|
||||
return (patch_number, patch_insert_index, patch_apply_index, lines)
|
||||
|
||||
def patch_upstream(self):
|
||||
"""
|
||||
Generate patches for any differences between our tag and the
|
||||
upstream tag, and apply them into an exported copy of the
|
||||
spec file.
|
||||
"""
|
||||
patch_filename = "%s-to-%s-%s.patch" % (self.upstream_tag,
|
||||
self.project_name, self.build_version)
|
||||
patch_file = os.path.join(self.rpmbuild_gitcopy,
|
||||
patch_filename)
|
||||
patch_dir = self.git_root
|
||||
if self.relative_project_dir != "/":
|
||||
patch_dir = os.path.join(self.git_root,
|
||||
self.relative_project_dir)
|
||||
os.chdir(patch_dir)
|
||||
debug("patch dir = %s" % patch_dir)
|
||||
print("Generating patch [%s]" % patch_filename)
|
||||
debug("Patch: %s" % patch_file)
|
||||
patch_command = "git diff --relative %s..%s > %s" % \
|
||||
(self.upstream_tag, self.git_commit_id,
|
||||
patch_file)
|
||||
debug("Generating patch with: %s" % patch_command)
|
||||
output = run_command(patch_command)
|
||||
print(output)
|
||||
# Creating two copies of the patch here in the temp build directories
|
||||
# just out of laziness. Some builders need sources in SOURCES and
|
||||
# others need them in the git copy. Being lazy here avoids one-off
|
||||
# hacks and both copies get cleaned up anyhow.
|
||||
run_command("cp %s %s" % (patch_file, self.rpmbuild_sourcedir))
|
||||
|
||||
(patch_number, patch_insert_index, patch_apply_index, lines) = self._patch_upstream()
|
||||
|
||||
lines.insert(patch_insert_index, "Patch%s: %s\n" % (patch_number,
|
||||
patch_filename))
|
||||
lines.insert(patch_apply_index, "%%patch%s -p1\n" % (patch_number))
|
||||
self._write_spec(lines)
|
||||
|
||||
def _write_spec(self, lines):
|
||||
""" Write 'lines' to self.spec_file """
|
||||
# Now write out the modified lines to the spec file copy:
|
||||
f = open(self.spec_file, 'w')
|
||||
for line in lines:
|
||||
|
|
43
src/tito/distributionbuilder.py
Normal file
43
src/tito/distributionbuilder.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
import os
|
||||
|
||||
from tito.builder import UpstreamBuilder
|
||||
from tito.common import debug, run_command
|
||||
|
||||
class DistributionBuilder(UpstreamBuilder):
|
||||
""" This class is used for building packages for distributions.
|
||||
Parent class UpstreamBuilder build one big patch from upstream and create e.g.:
|
||||
Patch0: foo-1.2.13-1-to-foo-1.2.13-3-sat.patch
|
||||
This class create one patch per each release. E.g.:
|
||||
Patch0: foo-1.2.13-1-to-foo-1.2.13-2-sat.patch
|
||||
Patch1: foo-1.2.13-2-to-foo-1.2.13-3-sat.patch
|
||||
"""
|
||||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None, dist=None,
|
||||
test=False, offline=False, auto_install=False,
|
||||
rpmbuild_options=None):
|
||||
UpstreamBuilder.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
global_config, user_config, dist, test, offline, auto_install, rpmbuild_options)
|
||||
self.patch_files = []
|
||||
|
||||
def patch_upstream(self):
|
||||
""" Create one patch per each release """
|
||||
os.chdir(os.path.join(self.git_root, self.relative_project_dir))
|
||||
debug("Running /usr/bin/generate-patches.pl -d %s %s %s-1 %s %s" \
|
||||
% self.rpmbuild_gitcopy, self.project_name, self.upstream_version, self.build_version, self.git_commit_id)
|
||||
output = run_command("/usr/bin/generate-patches.pl -d %s %s %s-1 %s %s" \
|
||||
% self.rpmbuild_gitcopy, self.project_name, self.upstream_version, self.build_version, self.git_commit_id)
|
||||
self.patch_files = output.split("\n")
|
||||
for p_file in self.patch_files:
|
||||
run_command("cp %s/%s %s" % (self.rpmbuild_gitcopy, p_file, self.rpmbuild_sourcedir))
|
||||
|
||||
(patch_number, patch_insert_index, patch_apply_index, lines) = self._patch_upstream()
|
||||
|
||||
for patch in self.patch_files:
|
||||
lines.insert(patch_insert_index, "Patch%s: %s\n" % (patch_number, patch))
|
||||
lines.insert(patch_apply_index, "%%patch%s -p1\n" % (patch_number))
|
||||
patch_number += 1
|
||||
patch_insert_index += 1
|
||||
patch_apply_index += 2
|
||||
self._write_spec(lines)
|
||||
|
||||
|
|
@ -60,6 +60,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%{_bindir}/bump-version.pl
|
||||
%{_bindir}/tar-fixup-stamp-comment.pl
|
||||
%{_bindir}/test-setup-specfile.pl
|
||||
%{_bindir}/generate-patches.pl
|
||||
%dir %{python_sitelib}/tito
|
||||
%{python_sitelib}/tito/*
|
||||
%{python_sitelib}/tito-*.egg-info
|
||||
|
|
Loading…
Add table
Reference in a new issue