Add latest upstream builder to add support for GitLfsBuilder
This commit is contained in:
parent
0e72e6adf9
commit
df761bd552
|
@ -0,0 +1,18 @@
|
||||||
|
# Import our builders so they can be referenced in config as tito.builder.Class
|
||||||
|
# regardless of which submodule they're in.
|
||||||
|
|
||||||
|
# flake8: noqa
|
||||||
|
|
||||||
|
from fws_tito.builder.main import \
|
||||||
|
Builder, \
|
||||||
|
NoTgzBuilder, \
|
||||||
|
GemBuilder, \
|
||||||
|
UpstreamBuilder, \
|
||||||
|
SatelliteBuilder, \
|
||||||
|
MockBuilder, \
|
||||||
|
BrewDownloadBuilder, \
|
||||||
|
GitAnnexBuilder, \
|
||||||
|
GitLfsBuilder, \
|
||||||
|
MeadBuilder
|
||||||
|
|
||||||
|
from fws_tito.builder.fetch import FetchBuilder
|
|
@ -0,0 +1,212 @@
|
||||||
|
# Copyright (c) 2008-2014 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# This software is licensed to you under the GNU General Public License,
|
||||||
|
# version 2 (GPLv2). There is NO WARRANTY for this software, express or
|
||||||
|
# implied, including the implied warranties of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
|
||||||
|
# along with this software; if not, see
|
||||||
|
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
|
||||||
|
#
|
||||||
|
# Red Hat trademarks are not licensed under GPLv2. No permission is
|
||||||
|
# granted to use or replicate Red Hat trademarks that are incorporated
|
||||||
|
# in this software or its documentation.
|
||||||
|
|
||||||
|
import re
|
||||||
|
import os.path
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
from tito.builder.main import BuilderBase
|
||||||
|
from tito.config_object import ConfigObject
|
||||||
|
from tito.common import error_out, debug, get_spec_version_and_release, \
|
||||||
|
get_class_by_name
|
||||||
|
|
||||||
|
|
||||||
|
class FetchBuilder(ConfigObject, BuilderBase):
|
||||||
|
"""
|
||||||
|
A separate Builder class for projects whose source is not in git. Source
|
||||||
|
is fetched via a configurable strategy, which also determines what version
|
||||||
|
and release to insert into the spec file.
|
||||||
|
|
||||||
|
Cannot build past tags.
|
||||||
|
"""
|
||||||
|
# TODO: test only for now, setup a tagger to fetch sources and store in git annex,
|
||||||
|
# then we can do official builds as well.
|
||||||
|
REQUIRED_ARGS = []
|
||||||
|
|
||||||
|
def __init__(self, name=None, tag=None, build_dir=None,
|
||||||
|
config=None, user_config=None,
|
||||||
|
args=None, **kwargs):
|
||||||
|
|
||||||
|
BuilderBase.__init__(self, name=name, build_dir=build_dir,
|
||||||
|
config=config,
|
||||||
|
user_config=user_config, args=args, **kwargs)
|
||||||
|
|
||||||
|
if tag:
|
||||||
|
error_out("FetchBuilder does not support building specific tags.")
|
||||||
|
|
||||||
|
if not config.has_option("builder",
|
||||||
|
"fetch_strategy"):
|
||||||
|
print("WARNING: no fetch_strategy specified in tito.props"
|
||||||
|
", assuming ArgSourceStrategy.")
|
||||||
|
if not config.has_section("builder"):
|
||||||
|
config.add_section("builder")
|
||||||
|
config.set('builder', 'fetch_strategy',
|
||||||
|
'tito.builder.fetch.ArgSourceStrategy')
|
||||||
|
|
||||||
|
self.build_tag = '%s-%s' % (self.project_name,
|
||||||
|
get_spec_version_and_release(self.start_dir, '%s.spec' % self.project_name))
|
||||||
|
|
||||||
|
def tgz(self):
|
||||||
|
self.ran_tgz = True
|
||||||
|
self._create_build_dirs()
|
||||||
|
|
||||||
|
print("Fetching sources...")
|
||||||
|
source_strat_class = get_class_by_name(self.config.get(
|
||||||
|
'builder', 'fetch_strategy'))
|
||||||
|
source_strat = source_strat_class(self)
|
||||||
|
source_strat.fetch()
|
||||||
|
self.sources = source_strat.sources
|
||||||
|
self.spec_file = source_strat.spec_file
|
||||||
|
|
||||||
|
def _get_rpmbuild_dir_options(self):
|
||||||
|
return ('--define "_topdir %s" --define "_sourcedir %s" --define "_builddir %s" '
|
||||||
|
'--define "_srcrpmdir %s" --define "_rpmdir %s" ' % (
|
||||||
|
self.rpmbuild_dir,
|
||||||
|
self.rpmbuild_sourcedir, self.rpmbuild_builddir,
|
||||||
|
self.rpmbuild_basedir, self.rpmbuild_basedir))
|
||||||
|
|
||||||
|
|
||||||
|
class SourceStrategy(object):
|
||||||
|
"""
|
||||||
|
Base class for source strategies. These are responsible for fetching the
|
||||||
|
sources the builder will use, and determining what version/release we're
|
||||||
|
building.
|
||||||
|
|
||||||
|
This is created and run in the tgz step of the builder. It will be passed
|
||||||
|
a reference to the builder calling it, which will be important for accessing
|
||||||
|
a lot of required information.
|
||||||
|
|
||||||
|
Ideally sources and the spec file to be used should be copied into
|
||||||
|
builder.rpmbuild_sourcedir, which will be cleaned up automatically after
|
||||||
|
the builder runs.
|
||||||
|
"""
|
||||||
|
def __init__(self, builder):
|
||||||
|
"""
|
||||||
|
Defines fields that should be set when a sub-class runs fetch.
|
||||||
|
"""
|
||||||
|
self.builder = builder
|
||||||
|
|
||||||
|
# Full path to the spec file we'll actually use to build, should be a
|
||||||
|
# copy, never a live spec file in a git repo as sometimes it will be
|
||||||
|
# modified:
|
||||||
|
self.spec_file = None
|
||||||
|
|
||||||
|
# Will contain the full path to each source we gather:
|
||||||
|
self.sources = []
|
||||||
|
|
||||||
|
# The version we're building:
|
||||||
|
self.version = None
|
||||||
|
|
||||||
|
# The release we're building:
|
||||||
|
self.release = None
|
||||||
|
|
||||||
|
def fetch(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
class ArgSourceStrategy(SourceStrategy):
|
||||||
|
"""
|
||||||
|
Assumes the builder was passed an explicit argument specifying which source
|
||||||
|
file(s) to use.
|
||||||
|
"""
|
||||||
|
def fetch(self):
|
||||||
|
|
||||||
|
# Assuming we're still in the start directory, get the absolute path
|
||||||
|
# to all sources specified:
|
||||||
|
# TODO: support passing of multiple sources here.
|
||||||
|
# TODO: error out if not present
|
||||||
|
manual_sources = [self.builder.args['source'][0]]
|
||||||
|
debug("Got sources: %s" % manual_sources)
|
||||||
|
|
||||||
|
# Copy the live spec from our starting location. Unlike most builders,
|
||||||
|
# we are not using a copy from a past git commit.
|
||||||
|
self.spec_file = os.path.join(self.builder.rpmbuild_sourcedir,
|
||||||
|
'%s.spec' % self.builder.project_name)
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(self.builder.start_dir, '%s.spec' %
|
||||||
|
self.builder.project_name),
|
||||||
|
self.spec_file)
|
||||||
|
print(" %s.spec" % self.builder.project_name)
|
||||||
|
|
||||||
|
# TODO: Make this a configurable strategy:
|
||||||
|
i = 0
|
||||||
|
replacements = []
|
||||||
|
for s in manual_sources:
|
||||||
|
base_name = os.path.basename(s)
|
||||||
|
dest_filepath = os.path.join(self.builder.rpmbuild_sourcedir,
|
||||||
|
base_name)
|
||||||
|
shutil.copyfile(s, dest_filepath)
|
||||||
|
self.sources.append(dest_filepath)
|
||||||
|
|
||||||
|
# Add a line to replace in the spec for each source:
|
||||||
|
source_regex = re.compile("^(source%s:\s*)(.+)$" % i, re.IGNORECASE)
|
||||||
|
new_line = "Source%s: %s\n" % (i, base_name)
|
||||||
|
replacements.append((source_regex, new_line))
|
||||||
|
|
||||||
|
# Replace version and release in spec:
|
||||||
|
version_regex = re.compile("^(version:\s*)(.+)$", re.IGNORECASE)
|
||||||
|
release_regex = re.compile("^(release:\s*)(.+)$", re.IGNORECASE)
|
||||||
|
|
||||||
|
(self.version, self.release) = self._get_version_and_release()
|
||||||
|
print("Building version: %s" % self.version)
|
||||||
|
print("Building release: %s" % self.release)
|
||||||
|
replacements.append((version_regex, "Version: %s\n" % self.version))
|
||||||
|
replacements.append((release_regex, "Release: %s\n" % self.release))
|
||||||
|
|
||||||
|
self.replace_in_spec(replacements)
|
||||||
|
|
||||||
|
def _get_version_and_release(self):
|
||||||
|
"""
|
||||||
|
Get the version and release from the builder.
|
||||||
|
Sources are configured at this point.
|
||||||
|
"""
|
||||||
|
# Assuming source0 is a tar.gz we can extract a version and possibly
|
||||||
|
# release from:
|
||||||
|
base_name = os.path.basename(self.sources[0])
|
||||||
|
debug("Extracting version/release from: %s" % base_name)
|
||||||
|
|
||||||
|
# usually a source tarball won't have a release, that is an RPM concept.
|
||||||
|
# Don't forget dist!
|
||||||
|
release = "1%{?dist}"
|
||||||
|
|
||||||
|
# Example filename: tito-0.4.18.tar.gz:
|
||||||
|
simple_version_re = re.compile(".*-(.*).(tar.gz|tgz|zip|bz2)")
|
||||||
|
match = re.search(simple_version_re, base_name)
|
||||||
|
if match:
|
||||||
|
version = match.group(1)
|
||||||
|
else:
|
||||||
|
error_out("Unable to determine version from file: %s" % base_name)
|
||||||
|
|
||||||
|
return (version, release)
|
||||||
|
|
||||||
|
def replace_in_spec(self, replacements):
|
||||||
|
"""
|
||||||
|
Replace lines in the spec file using the given replacements.
|
||||||
|
|
||||||
|
Replacements are a tuple of a regex to look for, and a new line to
|
||||||
|
substitute in when the regex matches.
|
||||||
|
|
||||||
|
Replaces all lines with one pass through the file.
|
||||||
|
"""
|
||||||
|
in_f = open(self.spec_file, 'r')
|
||||||
|
out_f = open(self.spec_file + ".new", 'w')
|
||||||
|
for line in in_f.readlines():
|
||||||
|
for line_regex, new_line in replacements:
|
||||||
|
match = re.match(line_regex, line)
|
||||||
|
if match:
|
||||||
|
line = new_line
|
||||||
|
out_f.write(line)
|
||||||
|
|
||||||
|
in_f.close()
|
||||||
|
out_f.close()
|
||||||
|
shutil.move(self.spec_file + ".new", self.spec_file)
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue