summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2015-02-18 10:15:31 +1100
committerChris Johns <chrisj@rtems.org>2015-02-18 10:27:02 +1100
commitd7550652cb2b23b7105e2dabe1e13fb1b18d5215 (patch)
tree0f020698dd57ddd19ae2ff24ea3d6f6b98373bec
parent616892914e5362506af208e069dd69d83e5ec357 (diff)
downloadrtems-source-builder-d7550652cb2b23b7105e2dabe1e13fb1b18d5215.tar.bz2
Add options support for --with/--without processing. Add --with-download support.
You can now test downloading by using --dry-run and --with-download. Print the redirect if one is taken.
-rw-r--r--source-builder/sb/download.py131
-rw-r--r--source-builder/sb/options.py49
2 files changed, 144 insertions, 36 deletions
diff --git a/source-builder/sb/download.py b/source-builder/sb/download.py
index 9490aa0..17d1d7e 100644
--- a/source-builder/sb/download.py
+++ b/source-builder/sb/download.py
@@ -36,6 +36,16 @@ import log
import path
import sources
+def _do_download(opts):
+ download = True
+ if opts.dry_run():
+ download = False
+ wa = opts.with_arg('download')
+ if wa is not None:
+ if wa[0] == 'with_download' and wa[1] == 'yes':
+ download = True
+ return download
+
def _humanize_bytes(bytes, precision = 1):
abbrevs = (
(1 << 50L, 'PB'),
@@ -102,7 +112,56 @@ def _hash_check(file_, absfile, macros, remove = True):
log.warning('%s: no hash found' % (file_))
return not failed
-def _http_parser(source, config, opts):
+def _local_path(source, pathkey, config):
+ for p in config.define(pathkey).split(':'):
+ local = path.join(path.abspath(p), source['file'])
+ if source['local'] is None:
+ source['local_prefix'] = path.abspath(p)
+ source['local'] = local
+ if path.exists(local):
+ source['local_prefix'] = path.abspath(p)
+ source['local'] = local
+ _hash_check(source['file'], local, config.macros)
+ break
+
+def _http_parser(source, pathkey, config, opts):
+ #
+ # Hack for gitweb.cgi patch downloads. We rewrite the various fields.
+ #
+ if 'gitweb.cgi' in source['url']:
+ url = source['url']
+ if '?' not in url:
+ raise error.general('invalid gitweb.cgi request: %s' % (url))
+ req = url.split('?')[1]
+ if len(req) == 0:
+ raise error.general('invalid gitweb.cgi request: %s' % (url))
+ #
+ # The gitweb.cgi request should have:
+ # p=<what>
+ # a=patch
+ # h=<hash>
+ # so extract the p and h parts to make the local name.
+ #
+ p = None
+ a = None
+ h = None
+ for r in req.split(';'):
+ if '=' not in r:
+ raise error.general('invalid gitweb.cgi path: %s' % (url))
+ rs = r.split('=')
+ if rs[0] == 'p':
+ p = rs[1].replace('.', '-')
+ elif rs[0] == 'a':
+ a = rs[1]
+ elif rs[0] == 'h':
+ h = rs[1]
+ if p is None or h is None:
+ raise error.general('gitweb.cgi path missing p or h: %s' % (url))
+ source['file'] = '%s-%s.patch' % (p, h)
+ #
+ # Check local path
+ #
+ _local_path(source, pathkey, config)
#
# Is the file compressed ?
#
@@ -120,10 +179,18 @@ def _http_parser(source, config, opts):
source['compressed-type'] = 'xz'
source['compressed'] = '%{__xz} -dc'
-def _patchworks_parser(source, config, opts):
+def _patchworks_parser(source, pathkey, config, opts):
+ #
+ # Check local path
+ #
+ _local_path(source, pathkey, config)
source['url'] = 'http%s' % (source['path'][2:])
-def _git_parser(source, config, opts):
+def _git_parser(source, pathkey, config, opts):
+ #
+ # Check local path
+ #
+ _local_path(source, pathkey, config)
#
# Symlink.
#
@@ -137,7 +204,11 @@ def _git_parser(source, config, opts):
path.join(source['local_prefix'], 'git', source['file'])
source['symlink'] = source['local']
-def _cvs_parser(source, config, opts):
+def _cvs_parser(source, pathkey, config, opts):
+ #
+ # Check local path
+ #
+ _local_path(source, pathkey, config)
#
# Symlink.
#
@@ -185,7 +256,11 @@ def _cvs_parser(source, config, opts):
else:
source['symlink'] = source['local']
-def _file_parser(source, config, opts):
+def _file_parser(source, pathkey, config, opts):
+ #
+ # Check local path
+ #
+ _local_path(source, pathkey, config)
#
# Symlink.
#
@@ -217,22 +292,12 @@ def parse_url(url, pathkey, config, opts):
# Get the file. Checks the local source directory first.
#
source['local'] = None
- for p in config.define(pathkey).split(':'):
- local = path.join(path.abspath(p), source['file'])
- if source['local'] is None:
- source['local_prefix'] = path.abspath(p)
- source['local'] = local
- if path.exists(local):
- source['local_prefix'] = path.abspath(p)
- source['local'] = local
- _hash_check(source['file'], local, config.macros)
- break
- source['script'] = ''
for p in parsers:
if url.startswith(p):
source['type'] = p
- if parsers[p](source, config, opts):
+ if parsers[p](source, pathkey, config, opts):
break
+ source['script'] = ''
return source
def _http_downloader(url, local, config, opts):
@@ -246,7 +311,7 @@ def _http_downloader(url, local, config, opts):
dst = os.path.relpath(path.host(local))
log.notice('download: %s -> %s' % (url, dst))
failed = False
- if not opts.dry_run():
+ if _do_download(opts):
_in = None
_out = None
_length = None
@@ -258,7 +323,10 @@ def _http_downloader(url, local, config, opts):
_wipe_output = False
try:
try:
+ _in = None
_in = urllib2.urlopen(url)
+ if url != _in.geturl():
+ log.notice(' redirect: %s' % (_in.geturl()))
_out = open(path.host(local), 'wb')
try:
_length = int(_in.info().getheader('Content-Length').strip())
@@ -300,12 +368,15 @@ def _http_downloader(url, local, config, opts):
msg = 'download: %s: error' % (url)
log.stderr(msg)
log.notice(msg)
+ if _in is not None:
+ _in.close()
if _out is not None:
_out.close()
raise
if _out is not None:
_out.close()
if _in is not None:
+ _in.close()
del _in
if not failed:
if not path.isfile(local):
@@ -338,7 +409,7 @@ def _git_downloader(url, local, config, opts):
us[0] = _as[1] + url_base
if not repo.valid():
log.notice('git: clone: %s -> %s' % (us[0], rlp))
- if not opts.dry_run():
+ if _do_download(opts):
repo.clone(us[0], local)
else:
repo.clean(['-f', '-d'])
@@ -350,28 +421,28 @@ def _git_downloader(url, local, config, opts):
if len(_as) != 2:
raise error.general('invalid git branch/checkout: %s' % (_as))
log.notice('git: checkout: %s => %s' % (us[0], _as[1]))
- if not opts.dry_run():
+ if _do_download(opts):
repo.checkout(_as[1])
elif _as[0] == 'pull':
log.notice('git: pull: %s' % (us[0]))
- if not opts.dry_run():
+ if _do_download(opts):
repo.pull()
elif _as[0] == 'submodule':
if len(_as) != 2:
raise error.general('invalid git submodule: %s' % (_as))
log.notice('git: submodule: %s <= %s' % (us[0], _as[1]))
- if not opts.dry_run():
+ if _do_download(opts):
repo.submodule(_as[1])
elif _as[0] == 'fetch':
log.notice('git: fetch: %s -> %s' % (us[0], rlp))
- if not opts.dry_run():
+ if _do_download(opts):
repo.fetch()
elif _as[0] == 'reset':
arg = []
if len(_as) > 1:
arg = ['--%s' % (_as[1])]
log.notice('git: reset: %s' % (us[0]))
- if not opts.dry_run():
+ if _do_download(opts):
repo.reset(arg)
elif _as[0] == 'protocol':
pass
@@ -409,20 +480,20 @@ def _cvs_downloader(url, local, config, opts):
if not path.isdir(local):
log.notice('Creating source directory: %s' % \
(os.path.relpath(path.host(local))))
- if not opts.dry_run():
+ if _do_download(opts):
path.mkdir(local)
log.notice('cvs: checkout: %s -> %s' % (us[0], rlp))
- if not opts.dry_run():
+ if _do_download(opts):
repo.checkout(':%s' % (us[0][6:]), module, tag, date)
for a in us[1:]:
_as = a.split('=')
if _as[0] == 'update':
log.notice('cvs: update: %s' % (us[0]))
- if not opts.dry_run():
+ if _do_download(opts):
repo.update()
elif _as[0] == 'reset':
log.notice('cvs: reset: %s' % (us[0]))
- if not opts.dry_run():
+ if _do_download(opts):
repo.reset()
return True
@@ -445,7 +516,7 @@ def get_file(url, local, opts, config):
log.notice('Creating source directory: %s' % \
(os.path.relpath(path.host(path.dirname(local)))))
log.output('making dir: %s' % (path.host(path.dirname(local))))
- if not opts.dry_run():
+ if _do_download(opts):
path.mkdir(path.dirname(local))
if not path.exists(local) and opts.download_disabled():
raise error.general('source not found: %s' % (path.host(local)))
@@ -472,5 +543,5 @@ def get_file(url, local, opts, config):
if url.startswith(dl):
if downloaders[dl](url, local, config, opts):
return
- if not opts.dry_run():
+ if _do_download(opts):
raise error.general('downloading %s: all paths have failed, giving up' % (url))
diff --git a/source-builder/sb/options.py b/source-builder/sb/options.py
index a468694..663c7f0 100644
--- a/source-builder/sb/options.py
+++ b/source-builder/sb/options.py
@@ -190,7 +190,7 @@ class command_line:
def help(self):
print '%s: [options] [args]' % (self.command_name)
- print 'RTEMS Source Builder, an RTEMS Tools Project (c) 2012-2013 Chris Johns'
+ print 'RTEMS Source Builder, an RTEMS Tools Project (c) 2012-2015 Chris Johns'
print 'Options and arguments:'
print '--force : Force the build to proceed'
print '--quiet : Quiet output (not used)'
@@ -427,14 +427,49 @@ class command_line:
def params(self):
return self.opts['params']
+ def parse_args(self, arg, error = True):
+ for a in range(0, len(self.args)):
+ if self.args[a].startswith(arg):
+ lhs = None
+ rhs = None
+ if '=' in self.args[a]:
+ eqs = self.args[a].split('=')
+ lhs = eqs[0]
+ if len(eqs) > 2:
+ rhs = '='.join(eqs[1:])
+ else:
+ rhs = eqs[1]
+ else:
+ lhs = self.args[a]
+ a += 1
+ if a >= len(self.args):
+ return [arg, None]
+ rhs = self.args[a]
+ return [lhs, rhs]
+ a += 1
+ return None
+
def get_arg(self, arg):
if self.optargs is None or arg not in self.optargs:
raise error.internal('bad arg: %s' % (arg))
- for a in self.args:
- sa = a.split('=')
- if sa[0].startswith(arg):
- return sa
- return None
+ return self.parse_args(arg)
+
+ def with_arg(self, label):
+ for pre in ['with', 'without']:
+ arg_str = '--%s-%s' % (pre, label)
+ arg_label = '%s_%s' % (pre, label)
+ arg = self.parse_args(arg_str, error = False)
+ if arg is not None:
+ if arg[1] is None:
+ result = 'yes'
+ else:
+ result = arg[1]
+ break
+ if pre == 'with':
+ result = 'yes'
+ else:
+ result = 'no'
+ return [arg_label, result]
def get_config_files(self, config):
#
@@ -570,6 +605,8 @@ def run(args):
log.notice(str(_opts))
log.notice('Defaults:')
log.notice(str(_opts.defaults))
+ log.notice('with-opt1: %r' % (_opts.with_arg('opt1')))
+ log.notice('without-opt2: %r' % (_opts.with_arg('opt2')))
except error.general, gerr:
print gerr
sys.exit(1)