[Checkins] SVN: zc.buildout/branches/tlotze-download-api/ merged trunk at rev. 102040
Thomas Lotze
tl at gocept.com
Mon Jul 20 12:57:13 EDT 2009
Log message for revision 102041:
merged trunk at rev. 102040
Changed:
U zc.buildout/branches/tlotze-download-api/CHANGES.txt
U zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.py
U zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.txt
-=-
Modified: zc.buildout/branches/tlotze-download-api/CHANGES.txt
===================================================================
--- zc.buildout/branches/tlotze-download-api/CHANGES.txt 2009-07-20 15:52:36 UTC (rev 102040)
+++ zc.buildout/branches/tlotze-download-api/CHANGES.txt 2009-07-20 16:57:13 UTC (rev 102041)
@@ -4,6 +4,9 @@
1.3.1 (unreleased)
==================
+- Added annotate command for annotated sections. Displays sections key-value pairs
+ along with the value origin.
+
- Added a download API that handles the download cache, offline mode etc and
is meant to be reused by recipes.
Modified: zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.py 2009-07-20 15:52:36 UTC (rev 102040)
+++ zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.py 2009-07-20 16:57:13 UTC (rev 102041)
@@ -28,7 +28,9 @@
import ConfigParser
import UserDict
import glob
+import copy
+
import pkg_resources
import zc.buildout
import zc.buildout.download
@@ -65,7 +67,48 @@
def __str__(self):
return "The referenced section, %r, was not defined." % self[0]
-_buildout_default_options = {
+
+def _annotate_section(section, note):
+ for key in section:
+ section[key] = (section[key], note)
+ return section
+
+def _annotate(data, note):
+ for key in data:
+ data[key] = _annotate_section(data[key], note)
+ return data
+
+def _print_annotate(data):
+ sections = data.keys()
+ sections.sort()
+ print
+ print "Annotated sections"
+ print "="*len("Annotated sections")
+ for section in sections:
+ print
+ print '[%s]' % section
+ keys = data[section].keys()
+ keys.sort()
+ for key in keys:
+ value, files = data[section][key]
+ print "%s=%s" % (key, value)
+ for file in files.split():
+ print " " + file
+ print
+ print
+
+def _unannotate_section(section):
+ for key in section:
+ value, note = section[key]
+ section[key] = value
+ return section
+
+def _unannotate(data):
+ for key in data:
+ data[key] = _unannotate_section(data[key])
+ return data
+
+_buildout_default_options = _annotate_section({
'eggs-directory': 'eggs',
'develop-eggs-directory': 'develop-eggs',
'bin-directory': 'bin',
@@ -75,8 +118,9 @@
'executable': sys.executable,
'log-level': 'INFO',
'log-format': '',
- }
+ }, 'DEFAULT_VALUE')
+
class Buildout(UserDict.DictMixin):
def __init__(self, config_file, cloptions,
@@ -101,17 +145,18 @@
# Sigh. this model of a buildout nstance
# with methods is breaking down :(
config_file = None
- data['buildout']['directory'] = '.'
+ data['buildout']['directory'] = ('.', 'COMPUTED_VALUE')
else:
raise zc.buildout.UserError(
"Couldn't open %s" % config_file)
if config_file:
- data['buildout']['directory'] = os.path.dirname(config_file)
+ data['buildout']['directory'] = (os.path.dirname(config_file),
+ 'COMPUTED_VALUE')
else:
base = None
- override = dict((option, value)
+ override = dict((option, (value, 'COMMAND_LINE_VALUE'))
for section, option, value in cloptions
if section == 'buildout')
@@ -133,9 +178,10 @@
options = data.get(section)
if options is None:
options = data[section] = {}
- options[option] = value
+ options[option] = value, "COMMAND_LINE_VALUE"
- self._raw = data
+ self._annotated = copy.deepcopy(data)
+ self._raw = _unannotate(data)
self._data = {}
self._parts = []
# provide some defaults before options are parsed
@@ -890,6 +936,9 @@
runsetup = setup # backward compat.
+ def annotate(self, args):
+ _print_annotate(self._annotated)
+
def __getitem__(self, section):
__doing__ = 'Getting section %s.', section
try:
@@ -1180,8 +1229,9 @@
Recursively open other files based on buildout options found.
"""
_update_section(dl_options, override)
+ _dl_options = _unannotate_section(dl_options.copy())
download = zc.buildout.download.Download(
- dl_options, cache=dl_options.get('extends-cache'), fallback=True,
+ _dl_options, cache=_dl_options.get('extends-cache'), fallback=True,
hash_name=True)
if _isurl(filename):
fp = open(download(filename))
@@ -1218,6 +1268,8 @@
extended_by = options.pop('extended-by', extended_by)
result[section] = options
+ result = _annotate(result, filename)
+
if root_config_file and 'buildout' in result:
dl_options = _update_section(dl_options, result['buildout'])
@@ -1267,14 +1319,21 @@
def _update_section(s1, s2):
for k, v in s2.items():
+ v2, note2 = v
if k.endswith('+'):
key = k.rstrip(' +')
- s2[key] = "\n".join(s1.get(key, "").split('\n') + s2[k].split('\n'))
+ v1, note1 = s1.get(key, ("", ""))
+ newnote = ' +'.join((note1, note2)).strip()
+ s2[key] = "\n".join((v1).split('\n') +
+ v2.split('\n')), newnote
del s2[k]
elif k.endswith('-'):
key = k.rstrip(' -')
- s2[key] = "\n".join([v for v in s1.get(key, "").split('\n')
- if v not in s2[k].split('\n')])
+ v1, note1 = s1.get(key, ("", ""))
+ newnote = ' -'.join((note1, note2)).strip()
+ s2[key] = ("\n".join(
+ [v for v in v1.split('\n')
+ if v not in v2.split('\n')]), newnote)
del s2[k]
s1.update(s2)
@@ -1437,6 +1496,13 @@
The script can be given either as a script path or a path to a
directory containing a setup.py script.
+ annotate
+
+ Display annotated sections. All sections are displayed, sorted
+ alphabetically. For each section, all key-value pairs are displayed,
+ sorted alphabetically, along with the origin of the value (file name or
+ COMPUTED_VALUE, DEFAULT_VALUE, COMMAND_LINE_VALUE).
+
"""
def _help():
print _usage
@@ -1456,7 +1522,7 @@
if args[0][0] == '-':
op = orig_op = args.pop(0)
op = op[1:]
- while op and op[0] in 'vqhWUoOnND':
+ while op and op[0] in 'vqhWUoOnNDA':
if op[0] == 'v':
verbosity += 10
elif op[0] == 'q':
@@ -1525,6 +1591,7 @@
command = args.pop(0)
if command not in (
'install', 'bootstrap', 'runsetup', 'setup', 'init',
+ 'annotate',
):
_error('invalid command:', command)
else:
@@ -1558,7 +1625,7 @@
finally:
- logging.shutdown()
+ logging.shutdown()
if sys.version_info[:2] < (2, 4):
def reversed(iterable):
Modified: zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.txt
===================================================================
--- zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.txt 2009-07-20 15:52:36 UTC (rev 102040)
+++ zc.buildout/branches/tlotze-download-api/src/zc/buildout/buildout.txt 2009-07-20 16:57:13 UTC (rev 102041)
@@ -707,6 +707,54 @@
keep section and option names simple, sticking to alphanumeric
characters, hyphens, and periods.
+Annotated sections
+------------------
+
+When used with the `annotate` command, buildout displays annotated sections.
+All sections are displayed, sorted alphabetically. For each section,
+all key-value pairs are displayed, sorted alphabetically, along with
+the origin of the value (file name or COMPUTED_VALUE, DEFAULT_VALUE,
+COMMAND_LINE_VALUE).
+
+ >>> print system(buildout+ ' annotate'), # doctest: +ELLIPSIS
+ <BLANKLINE>
+ Annotated sections
+ ==================
+ <BLANKLINE>
+ [buildout]
+ bin-directory=bin
+ DEFAULT_VALUE
+ develop=recipes
+ .../_TEST_/sample-buildout/buildout.cfg
+ develop-eggs-directory=develop-eggs
+ DEFAULT_VALUE
+ directory=.../_TEST_/sample-buildout
+ COMPUTED_VALUE
+ eggs-directory=eggs
+ DEFAULT_VALUE
+ executable=...
+ DEFAULT_VALUE
+ installed=.installed.cfg
+ DEFAULT_VALUE
+ log-format=
+ DEFAULT_VALUE
+ log-level=INFO
+ DEFAULT_VALUE
+ parts=data-dir
+ .../_TEST_/sample-buildout/buildout.cfg
+ parts-directory=parts
+ DEFAULT_VALUE
+ python=buildout
+ DEFAULT_VALUE
+ <BLANKLINE>
+ [data-dir]
+ path=foo bins
+ .../_TEST_/sample-buildout/buildout.cfg
+ recipe=recipes:mkdir
+ .../_TEST_/sample-buildout/buildout.cfg
+ <BLANKLINE>
+ <BLANKLINE>
+
Variable substitutions
----------------------
@@ -1025,6 +1073,46 @@
['a1 a2/na3 a4/na5', 'b1 b2 b3 b4', 'c1 c2/nc3 c4 c5', 'h1 h2']
Develop: '/sample-buildout/demo'
+Annotated sections output shows which files are responsible for which
+operations.
+
+ >>> print system(os.path.join('bin', 'buildout') + ' annotate'), # doctest: +ELLIPSIS
+ <BLANKLINE>
+ Annotated sections
+ ==================
+ ...
+ <BLANKLINE>
+ [part1]
+ option=a1 a2
+ a3 a4
+ a5
+ .../_TEST_/sample-buildout/base.cfg
+ +.../_TEST_/sample-buildout/extension1.cfg
+ +.../_TEST_/sample-buildout/extension2.cfg
+ recipe=
+ .../_TEST_/sample-buildout/base.cfg
+ <BLANKLINE>
+ [part2]
+ option=b1 b2 b3 b4
+ .../_TEST_/sample-buildout/base.cfg
+ -.../_TEST_/sample-buildout/extension1.cfg
+ -.../_TEST_/sample-buildout/extension2.cfg
+ recipe=
+ .../_TEST_/sample-buildout/base.cfg
+ <BLANKLINE>
+ [part3]
+ option=c1 c2
+ c3 c4 c5
+ .../_TEST_/sample-buildout/base.cfg
+ +.../_TEST_/sample-buildout/extension1.cfg
+ recipe=
+ .../_TEST_/sample-buildout/base.cfg
+ <BLANKLINE>
+ [part4]
+ option=h1 h2
+ .../_TEST_/sample-buildout/extension1.cfg
+ ...
+
Cleanup.
>>> os.remove(os.path.join(sample_buildout, 'base.cfg'))
More information about the Checkins
mailing list