Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.buildout
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
6
Merge Requests
6
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
slapos.buildout
Commits
ecb15c89
Commit
ecb15c89
authored
Mar 28, 2017
by
Godefroid Chapelle
Committed by
GitHub
Mar 28, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #378 from buildout/annotate_verbose
verbose mode and select sections for annotate command
parents
d6fba392
35ffe41f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
477 additions
and
80 deletions
+477
-80
.gitignore
.gitignore
+1
-0
CHANGES.rst
CHANGES.rst
+3
-1
doc/reference.rst
doc/reference.rst
+13
-0
src/zc/buildout/buildout.py
src/zc/buildout/buildout.py
+199
-58
src/zc/buildout/buildout.txt
src/zc/buildout/buildout.txt
+260
-20
src/zc/buildout/tests.py
src/zc/buildout/tests.py
+1
-1
No files found.
.gitignore
View file @
ecb15c89
.installed.cfg
.installed.cfg
bin/
bin/
build/
build/
include/
develop-eggs/
develop-eggs/
eggs/
eggs/
parts/
parts/
...
...
CHANGES.rst
View file @
ecb15c89
...
@@ -4,7 +4,9 @@ Change History
...
@@ -4,7 +4,9 @@ Change History
2.9.3
(
unreleased
)
2.9.3
(
unreleased
)
==================
==================
-
Nothing
changed
yet
.
-
Add
more
verbosity
to
``
annotate
``
results
with
``-
v
``
-
Select
one
or
more
sections
with
arguments
after
``
buildout
annotate
``.
2.9.2
(
2017
-
03
-
06
)
2.9.2
(
2017
-
03
-
06
)
...
...
doc/reference.rst
View file @
ecb15c89
...
@@ -117,6 +117,19 @@ where they came from. Try it!
...
@@ -117,6 +117,19 @@ where they came from. Try it!
..
_bootstrap
-
command
:
..
_bootstrap
-
command
:
..
code
-
block
::
console
buildout
-
v
annotate
Increase
the
verbosity
of
the
output
to
display
all
steps
that
compute
the
final
values
used
by
buildout
.
..
code
-
block
::
console
buildout
annotate
versions
You
can
pass
one
or
more
section
names
as
arguments
to
display
annotation
only
for
the
given
sections
.
bootstrap
bootstrap
_________
_________
...
...
src/zc/buildout/buildout.py
View file @
ecb15c89
...
@@ -75,49 +75,172 @@ class MissingSection(zc.buildout.UserError, KeyError):
...
@@ -75,49 +75,172 @@ class MissingSection(zc.buildout.UserError, KeyError):
return
"The referenced section, %r, was not defined."
%
self
.
args
[
0
]
return
"The referenced section, %r, was not defined."
%
self
.
args
[
0
]
def
_annotate_section
(
section
,
not
e
):
def
_annotate_section
(
section
,
sourc
e
):
for
key
in
section
:
for
key
in
section
:
section
[
key
]
=
(
section
[
key
],
not
e
)
section
[
key
]
=
SectionKey
(
section
[
key
],
sourc
e
)
return
section
return
section
class
SectionKey
(
object
):
def
__init__
(
self
,
value
,
source
):
self
.
history
=
[]
self
.
value
=
value
self
.
addToHistory
(
"SET"
,
value
,
source
)
@
property
def
source
(
self
):
return
self
.
history
[
-
1
].
source
def
overrideValue
(
self
,
sectionkey
):
self
.
value
=
sectionkey
.
value
if
sectionkey
.
history
[
-
1
].
operation
not
in
[
'ADD'
,
'REMOVE'
]:
self
.
addToHistory
(
"OVERRIDE"
,
sectionkey
.
value
,
sectionkey
.
source
)
def
setDirectory
(
self
,
value
):
self
.
value
=
value
self
.
addToHistory
(
"DIRECTORY"
,
value
,
self
.
source
)
def
addToValue
(
self
,
added
,
source
):
subvalues
=
self
.
value
.
split
(
'
\
n
'
)
+
added
.
split
(
'
\
n
'
)
self
.
value
=
"
\
n
"
.
join
(
subvalues
)
self
.
addToHistory
(
"ADD"
,
added
,
source
)
def
removeFromValue
(
self
,
removed
,
source
):
subvalues
=
[
v
for
v
in
self
.
value
.
split
(
'
\
n
'
)
if
v
not
in
removed
.
split
(
'
\
n
'
)
]
self
.
value
=
"
\
n
"
.
join
(
subvalues
)
self
.
addToHistory
(
"REMOVE"
,
removed
,
source
)
def
addToHistory
(
self
,
operation
,
value
,
source
):
item
=
HistoryItem
(
operation
,
value
,
source
)
self
.
history
.
append
(
item
)
def
printAll
(
self
,
key
,
basedir
,
verbose
):
self
.
printKeyAndValue
(
key
)
if
verbose
:
self
.
printVerbose
(
basedir
)
else
:
self
.
printTerse
(
basedir
)
def
printKeyAndValue
(
self
,
key
):
lines
=
self
.
value
.
splitlines
()
if
len
(
lines
)
<=
1
:
args
=
[
key
,
"="
]
if
self
.
value
:
args
.
append
(
" "
)
args
.
append
(
self
.
value
)
print_
(
*
args
,
sep
=
''
)
else
:
print_
(
key
,
"= "
,
lines
[
0
],
sep
=
''
)
for
line
in
lines
[
1
:]:
print_
(
line
)
def
printVerbose
(
self
,
basedir
):
print_
()
for
item
in
reversed
(
self
.
history
):
item
.
printAll
(
basedir
)
print_
()
def
printTerse
(
self
,
basedir
):
toprint
=
[]
history
=
copy
.
deepcopy
(
self
.
history
)
while
history
:
next
=
history
.
pop
()
if
next
.
operation
in
[
"ADD"
,
"REMOVE"
]:
next
.
printShort
(
toprint
,
basedir
)
else
:
next
.
printShort
(
toprint
,
basedir
)
break
for
line
in
reversed
(
toprint
):
if
line
.
strip
():
print_
(
line
)
def
__repr__
(
self
):
return
"<SectionKey value=%s source=%s>"
%
(
" "
.
join
(
self
.
value
.
split
(
'
\
n
'
)),
self
.
source
)
class
HistoryItem
(
object
):
def
__init__
(
self
,
operation
,
value
,
source
):
self
.
operation
=
operation
self
.
value
=
value
self
.
source
=
source
def
printShort
(
self
,
toprint
,
basedir
):
source
=
self
.
source_for_human
(
basedir
)
if
self
.
operation
in
[
"OVERRIDE"
,
"SET"
,
"DIRECTORY"
]:
toprint
.
append
(
" "
+
source
)
elif
self
.
operation
==
"ADD"
:
toprint
.
append
(
"+= "
+
source
)
elif
self
.
operation
==
"REMOVE"
:
toprint
.
append
(
"-= "
+
source
)
def
printOperation
(
self
):
lines
=
self
.
value
.
splitlines
()
if
len
(
lines
)
<=
1
:
print_
(
" "
,
self
.
operation
,
"VALUE ="
,
self
.
value
)
else
:
print_
(
" "
,
self
.
operation
,
"VALUE ="
)
for
line
in
lines
:
print_
(
" "
,
" "
,
line
)
def
printSource
(
self
,
basedir
):
if
self
.
source
in
(
'DEFAULT_VALUE'
,
'COMPUTED_VALUE'
,
'COMMAND_LINE_VALUE'
):
prefix
=
"AS"
else
:
prefix
=
"IN"
print_
(
" "
,
prefix
,
self
.
source_for_human
(
basedir
))
def
source_for_human
(
self
,
basedir
):
if
self
.
source
.
startswith
(
basedir
):
return
os
.
path
.
relpath
(
self
.
source
,
basedir
)
else
:
return
self
.
source
def
printAll
(
self
,
basedir
):
self
.
printSource
(
basedir
)
self
.
printOperation
()
def
__repr__
(
self
):
return
"<HistoryItem operation=%s value=%s source=%s>"
%
(
self
.
operation
,
" "
.
join
(
self
.
value
.
split
(
'
\
n
'
)),
self
.
source
)
def
_annotate
(
data
,
note
):
def
_annotate
(
data
,
note
):
for
key
in
data
:
for
key
in
data
:
data
[
key
]
=
_annotate_section
(
data
[
key
],
note
)
data
[
key
]
=
_annotate_section
(
data
[
key
],
note
)
return
data
return
data
def
_print_annotate
(
data
):
def
_print_annotate
(
data
,
verbose
,
chosen_sections
,
basedir
):
sections
=
list
(
data
.
keys
())
sections
=
list
(
data
.
keys
())
sections
.
sort
()
sections
.
sort
()
print_
()
print_
()
print_
(
"Annotated sections"
)
print_
(
"Annotated sections"
)
print_
(
"="
*
len
(
"Annotated sections"
))
print_
(
"="
*
len
(
"Annotated sections"
))
for
section
in
sections
:
for
section
in
sections
:
print_
()
if
(
not
chosen_sections
)
or
(
section
in
chosen_sections
):
print_
(
'[%s]'
%
section
)
print_
()
keys
=
list
(
data
[
section
].
keys
())
print_
(
'[%s]'
%
section
)
keys
.
sort
()
keys
=
list
(
data
[
section
].
keys
())
for
key
in
keys
:
keys
.
sort
()
value
,
notes
=
data
[
section
][
key
]
for
key
in
keys
:
keyvalue
=
"%s= %s"
%
(
key
,
value
)
sectionkey
=
data
[
section
][
key
]
print_
(
keyvalue
)
sectionkey
.
printAll
(
key
,
basedir
,
verbose
)
line
=
' '
for
note
in
notes
.
split
():
if
note
==
'[+]'
:
line
=
'+= '
elif
note
==
'[-]'
:
line
=
'-= '
else
:
print_
(
line
,
note
)
line
=
' '
print_
()
def
_unannotate_section
(
section
):
def
_unannotate_section
(
section
):
for
key
in
section
:
for
key
in
section
:
value
,
note
=
section
[
key
]
section
[
key
]
=
section
[
key
].
value
section
[
key
]
=
value
return
section
return
section
def
_unannotate
(
data
):
def
_unannotate
(
data
):
for
key
in
data
:
for
key
in
data
:
data
[
key
]
=
_unannotate_section
(
data
[
key
])
data
[
key
]
=
_unannotate_section
(
data
[
key
])
...
@@ -164,6 +287,7 @@ _buildout_default_options = _annotate_section({
...
@@ -164,6 +287,7 @@ _buildout_default_options = _annotate_section({
'use-dependency-links'
:
'true'
,
'use-dependency-links'
:
'true'
,
},
'DEFAULT_VALUE'
)
},
'DEFAULT_VALUE'
)
class
Buildout
(
DictMixin
):
class
Buildout
(
DictMixin
):
def
__init__
(
self
,
config_file
,
cloptions
,
def
__init__
(
self
,
config_file
,
cloptions
,
...
@@ -173,12 +297,13 @@ class Buildout(DictMixin):
...
@@ -173,12 +297,13 @@ class Buildout(DictMixin):
__doing__
=
'Initializing.'
__doing__
=
'Initializing.'
# default options
# default options
data
=
dict
(
buildout
=
_buildout_default_options
.
copy
())
_buildout_default_options_copy
=
copy
.
deepcopy
(
_buildout_default_options
)
data
=
dict
(
buildout
=
_buildout_default_options_copy
)
self
.
_buildout_dir
=
os
.
getcwd
()
self
.
_buildout_dir
=
os
.
getcwd
()
if
config_file
and
not
_isurl
(
config_file
):
if
config_file
and
not
_isurl
(
config_file
):
config_file
=
os
.
path
.
abspath
(
config_file
)
config_file
=
os
.
path
.
abspath
(
config_file
)
base
=
os
.
path
.
dirname
(
config_file
)
if
not
os
.
path
.
exists
(
config_file
):
if
not
os
.
path
.
exists
(
config_file
):
if
command
==
'init'
:
if
command
==
'init'
:
self
.
_init_config
(
config_file
,
args
)
self
.
_init_config
(
config_file
,
args
)
...
@@ -186,7 +311,8 @@ class Buildout(DictMixin):
...
@@ -186,7 +311,8 @@ class Buildout(DictMixin):
# Sigh. This model of a buildout instance
# Sigh. This model of a buildout instance
# with methods is breaking down. :(
# with methods is breaking down. :(
config_file
=
None
config_file
=
None
data
[
'buildout'
][
'directory'
]
=
(
'.'
,
'COMPUTED_VALUE'
)
data
[
'buildout'
][
'directory'
]
=
SectionKey
(
'.'
,
'COMPUTED_VALUE'
)
else
:
else
:
raise
zc
.
buildout
.
UserError
(
raise
zc
.
buildout
.
UserError
(
"Couldn't open %s"
%
config_file
)
"Couldn't open %s"
%
config_file
)
...
@@ -195,19 +321,16 @@ class Buildout(DictMixin):
...
@@ -195,19 +321,16 @@ class Buildout(DictMixin):
"%r already exists."
%
config_file
)
"%r already exists."
%
config_file
)
if
config_file
:
if
config_file
:
data
[
'buildout'
][
'directory'
]
=
(
os
.
path
.
dirname
(
config_file
),
data
[
'buildout'
][
'directory'
]
=
SectionKey
(
'COMPUTED_VALUE'
)
os
.
path
.
dirname
(
config_file
),
'COMPUTED_VALUE'
)
else
:
base
=
None
cloptions
=
dict
(
cloptions
=
dict
(
(
section
,
dict
((
option
,
(
value
,
'COMMAND_LINE_VALUE'
))
(
section
,
dict
((
option
,
SectionKey
(
value
,
'COMMAND_LINE_VALUE'
))
for
(
_
,
option
,
value
)
in
v
))
for
(
_
,
option
,
value
)
in
v
))
for
(
section
,
v
)
in
itertools
.
groupby
(
sorted
(
cloptions
),
for
(
section
,
v
)
in
itertools
.
groupby
(
sorted
(
cloptions
),
lambda
v
:
v
[
0
])
lambda
v
:
v
[
0
])
)
)
override
=
c
loptions
.
get
(
'buildout'
,
{}).
copy
(
)
override
=
c
opy
.
deepcopy
(
cloptions
.
get
(
'buildout'
,
{})
)
# load user defaults, which override defaults
# load user defaults, which override defaults
if
user_defaults
:
if
user_defaults
:
...
@@ -218,32 +341,35 @@ class Buildout(DictMixin):
...
@@ -218,32 +341,35 @@ class Buildout(DictMixin):
os
.
path
.
expanduser
(
'~'
),
'.buildout'
)
os
.
path
.
expanduser
(
'~'
),
'.buildout'
)
user_config
=
os
.
path
.
join
(
buildout_home
,
'default.cfg'
)
user_config
=
os
.
path
.
join
(
buildout_home
,
'default.cfg'
)
if
os
.
path
.
exists
(
user_config
):
if
os
.
path
.
exists
(
user_config
):
data_buildout_copy
=
copy
.
deepcopy
(
data
[
'buildout'
])
_update
(
data
,
_open
(
os
.
path
.
dirname
(
user_config
),
user_config
,
_update
(
data
,
_open
(
os
.
path
.
dirname
(
user_config
),
user_config
,
[],
data
[
'buildout'
].
copy
()
,
override
,
[],
data
_buildout_copy
,
override
,
set
()))
set
()))
# load configuration files
# load configuration files
if
config_file
:
if
config_file
:
data_buildout_copy
=
copy
.
deepcopy
(
data
[
'buildout'
])
_update
(
data
,
_open
(
os
.
path
.
dirname
(
config_file
),
config_file
,
[],
_update
(
data
,
_open
(
os
.
path
.
dirname
(
config_file
),
config_file
,
[],
data
[
'buildout'
].
copy
()
,
override
,
set
()))
data
_buildout_copy
,
override
,
set
()))
# apply command-line options
# apply command-line options
_update
(
data
,
cloptions
)
_update
(
data
,
cloptions
)
# Set up versions section, if necessary
# Set up versions section, if necessary
if
'versions'
not
in
data
[
'buildout'
]:
if
'versions'
not
in
data
[
'buildout'
]:
data
[
'buildout'
][
'versions'
]
=
(
'versions'
,
'DEFAULT_VALUE'
)
data
[
'buildout'
][
'versions'
]
=
SectionKey
(
'versions'
,
'DEFAULT_VALUE'
)
if
'versions'
not
in
data
:
if
'versions'
not
in
data
:
data
[
'versions'
]
=
{}
data
[
'versions'
]
=
{}
# Default versions:
# Default versions:
versions_section_name
=
data
[
'buildout'
][
'versions'
]
[
0
]
versions_section_name
=
data
[
'buildout'
][
'versions'
]
.
value
if
versions_section_name
:
if
versions_section_name
:
versions
=
data
[
versions_section_name
]
versions
=
data
[
versions_section_name
]
else
:
else
:
versions
=
{}
versions
=
{}
versions
.
update
(
versions
.
update
(
dict
((
k
,
(
v
,
'DEFAULT_VALUE'
))
dict
((
k
,
SectionKey
(
v
,
'DEFAULT_VALUE'
))
for
(
k
,
v
)
in
(
for
(
k
,
v
)
in
(
# Prevent downgrading due to prefer-final:
# Prevent downgrading due to prefer-final:
(
'zc.buildout'
,
(
'zc.buildout'
,
...
@@ -262,7 +388,9 @@ class Buildout(DictMixin):
...
@@ -262,7 +388,9 @@ class Buildout(DictMixin):
# file location
# file location
for
name
in
(
'download-cache'
,
'eggs-directory'
,
'extends-cache'
):
for
name
in
(
'download-cache'
,
'eggs-directory'
,
'extends-cache'
):
if
name
in
data
[
'buildout'
]:
if
name
in
data
[
'buildout'
]:
origdir
,
src
=
data
[
'buildout'
][
name
]
sectionkey
=
data
[
'buildout'
][
name
]
origdir
=
sectionkey
.
value
src
=
sectionkey
.
source
if
'${'
in
origdir
:
if
'${'
in
origdir
:
continue
continue
if
not
os
.
path
.
isabs
(
origdir
):
if
not
os
.
path
.
isabs
(
origdir
):
...
@@ -270,7 +398,7 @@ class Buildout(DictMixin):
...
@@ -270,7 +398,7 @@ class Buildout(DictMixin):
'COMPUTED_VALUE'
,
'COMPUTED_VALUE'
,
'COMMAND_LINE_VALUE'
):
'COMMAND_LINE_VALUE'
):
if
'directory'
in
data
[
'buildout'
]:
if
'directory'
in
data
[
'buildout'
]:
basedir
=
data
[
'buildout'
][
'directory'
]
[
0
]
basedir
=
data
[
'buildout'
][
'directory'
]
.
value
else
:
else
:
basedir
=
self
.
_buildout_dir
basedir
=
self
.
_buildout_dir
else
:
else
:
...
@@ -285,7 +413,7 @@ class Buildout(DictMixin):
...
@@ -285,7 +413,7 @@ class Buildout(DictMixin):
if
not
os
.
path
.
isabs
(
absdir
):
if
not
os
.
path
.
isabs
(
absdir
):
absdir
=
os
.
path
.
join
(
basedir
,
absdir
)
absdir
=
os
.
path
.
join
(
basedir
,
absdir
)
absdir
=
os
.
path
.
abspath
(
absdir
)
absdir
=
os
.
path
.
abspath
(
absdir
)
data
[
'buildout'
][
name
]
=
(
absdir
,
src
)
sectionkey
.
setDirectory
(
absdir
)
self
.
_annotated
=
copy
.
deepcopy
(
data
)
self
.
_annotated
=
copy
.
deepcopy
(
data
)
self
.
_raw
=
_unannotate
(
data
)
self
.
_raw
=
_unannotate
(
data
)
...
@@ -365,7 +493,7 @@ class Buildout(DictMixin):
...
@@ -365,7 +493,7 @@ class Buildout(DictMixin):
versions
=
self
[
versions_section_name
]
versions
=
self
[
versions_section_name
]
else
:
else
:
# remove annotations
# remove annotations
versions
=
dict
((
k
,
v
[
0
]
)
for
(
k
,
v
)
in
versions
.
items
())
versions
=
dict
((
k
,
v
.
value
)
for
(
k
,
v
)
in
versions
.
items
())
options
[
'versions'
]
# refetching section name just to avoid a warning
options
[
'versions'
]
# refetching section name just to avoid a warning
self
.
versions
=
versions
self
.
versions
=
versions
zc
.
buildout
.
easy_install
.
default_versions
(
versions
)
zc
.
buildout
.
easy_install
.
default_versions
(
versions
)
...
@@ -1106,7 +1234,13 @@ class Buildout(DictMixin):
...
@@ -1106,7 +1234,13 @@ class Buildout(DictMixin):
runsetup
=
setup
# backward compat.
runsetup
=
setup
# backward compat.
def
annotate
(
self
,
args
=
None
):
def
annotate
(
self
,
args
=
None
):
_print_annotate
(
self
.
_annotated
)
verbose
=
self
[
'buildout'
].
get
(
'verbosity'
,
0
)
!=
0
section
=
None
if
args
is
None
:
sections
=
[]
else
:
sections
=
args
_print_annotate
(
self
.
_annotated
,
verbose
,
sections
,
self
.
_buildout_dir
)
def
print_options
(
self
,
base_path
=
None
):
def
print_options
(
self
,
base_path
=
None
):
for
section
in
sorted
(
self
.
_data
):
for
section
in
sorted
(
self
.
_data
):
...
@@ -1279,7 +1413,7 @@ class Options(DictMixin):
...
@@ -1279,7 +1413,7 @@ class Options(DictMixin):
result
.
update
(
self
.
_do_extend_raw
(
iname
,
raw
,
doing
))
result
.
update
(
self
.
_do_extend_raw
(
iname
,
raw
,
doing
))
result
=
_annotate_section
(
result
,
""
)
result
=
_annotate_section
(
result
,
""
)
data
=
_annotate_section
(
data
.
copy
(
),
""
)
data
=
_annotate_section
(
copy
.
deepcopy
(
data
),
""
)
_update_section
(
result
,
data
)
_update_section
(
result
,
data
)
result
=
_unannotate_section
(
result
)
result
=
_unannotate_section
(
result
)
result
.
pop
(
'<'
,
None
)
result
.
pop
(
'<'
,
None
)
...
@@ -1405,7 +1539,7 @@ class Options(DictMixin):
...
@@ -1405,7 +1539,7 @@ class Options(DictMixin):
return
len
(
self
.
keys
())
return
len
(
self
.
keys
())
def
copy
(
self
):
def
copy
(
self
):
result
=
self
.
_raw
.
copy
(
)
result
=
copy
.
deepcopy
(
self
.
_raw
)
result
.
update
(
self
.
_cooked
)
result
.
update
(
self
.
_cooked
)
result
.
update
(
self
.
_data
)
result
.
update
(
self
.
_data
)
return
result
return
result
...
@@ -1573,7 +1707,8 @@ def _open(base, filename, seen, dl_options, override, downloaded):
...
@@ -1573,7 +1707,8 @@ def _open(base, filename, seen, dl_options, override, downloaded):
Recursively open other files based on buildout options found.
Recursively open other files based on buildout options found.
"""
"""
_update_section
(
dl_options
,
override
)
_update_section
(
dl_options
,
override
)
_dl_options
=
_unannotate_section
(
dl_options
.
copy
())
dl_options_copy
=
copy
.
deepcopy
(
dl_options
)
_dl_options
=
_unannotate_section
(
dl_options_copy
)
newest
=
bool_option
(
_dl_options
,
'newest'
,
'false'
)
newest
=
bool_option
(
_dl_options
,
'newest'
,
'false'
)
fallback
=
newest
and
not
(
filename
in
downloaded
)
fallback
=
newest
and
not
(
filename
in
downloaded
)
download
=
zc
.
buildout
.
download
.
Download
(
download
=
zc
.
buildout
.
download
.
Download
(
...
@@ -1702,31 +1837,37 @@ def _update_section(s1, s2):
...
@@ -1702,31 +1837,37 @@ def _update_section(s1, s2):
# in section 2 overriding those in section 1. If there are += or -=
# in section 2 overriding those in section 1. If there are += or -=
# operators in section 2, process these to add or substract items (delimited
# operators in section 2, process these to add or substract items (delimited
# by newlines) from the preexisting values.
# by newlines) from the preexisting values.
s2
=
s2
.
copy
(
)
# avoid mutating the second argument, which is unexpected
s2
=
copy
.
deepcopy
(
s2
)
# avoid mutating the second argument, which is unexpected
# Sort on key, then on the addition or substraction operator (+ comes first)
# Sort on key, then on the addition or substraction operator (+ comes first)
for
k
,
v
in
sorted
(
s2
.
items
(),
key
=
lambda
x
:
(
x
[
0
].
rstrip
(
' +'
),
x
[
0
][
-
1
])):
for
k
,
v
in
sorted
(
s2
.
items
(),
key
=
lambda
x
:
(
x
[
0
].
rstrip
(
' +'
),
x
[
0
][
-
1
])):
v2
,
note2
=
v
if
k
.
endswith
(
'+'
):
if
k
.
endswith
(
'+'
):
key
=
k
.
rstrip
(
' +'
)
key
=
k
.
rstrip
(
' +'
)
implicit_value
=
SectionKey
(
""
,
"IMPLICIT_VALUE"
)
# Find v1 in s2 first; it may have been defined locally too.
# Find v1 in s2 first; it may have been defined locally too.
v1
,
note1
=
s2
.
get
(
key
,
s1
.
get
(
key
,
(
""
,
""
)))
section_key
=
s2
.
get
(
key
,
s1
.
get
(
key
,
implicit_value
))
newnote
=
' [+] '
.
join
((
note1
,
note2
)).
strip
()
section_key
.
addToValue
(
v
.
value
,
v
.
source
)
s2
[
key
]
=
"
\
n
"
.
join
((
v1
).
split
(
'
\
n
'
)
+
s2
[
key
]
=
section_key
v2
.
split
(
'
\
n
'
)),
newnote
del
s2
[
k
]
del
s2
[
k
]
elif
k
.
endswith
(
'-'
):
elif
k
.
endswith
(
'-'
):
key
=
k
.
rstrip
(
' -'
)
key
=
k
.
rstrip
(
' -'
)
implicit_value
=
SectionKey
(
""
,
"IMPLICIT_VALUE"
)
# Find v1 in s2 first; it may have been set by a += operation first
# Find v1 in s2 first; it may have been set by a += operation first
v1
,
note1
=
s2
.
get
(
key
,
s1
.
get
(
key
,
(
""
,
""
)))
section_key
=
s2
.
get
(
key
,
s1
.
get
(
key
,
implicit_value
))
newnote
=
' [-] '
.
join
((
note1
,
note2
)).
strip
()
section_key
.
removeFromValue
(
v
.
value
,
v
.
source
)
s2
[
key
]
=
(
"
\
n
"
.
join
(
s2
[
key
]
=
section_key
[
v
for
v
in
v1
.
split
(
'
\
n
'
)
if
v
not
in
v2
.
split
(
'
\
n
'
)]),
newnote
)
del
s2
[
k
]
del
s2
[
k
]
s1
.
update
(
s2
)
_update_verbose
(
s1
,
s2
)
return
s1
return
s1
def
_update_verbose
(
s1
,
s2
):
for
key
,
v2
in
s2
.
items
():
if
key
in
s1
:
v1
=
s1
[
key
]
v1
.
overrideValue
(
v2
)
else
:
s1
[
key
]
=
v2
def
_update
(
d1
,
d2
):
def
_update
(
d1
,
d2
):
for
section
in
d2
:
for
section
in
d2
:
if
section
in
d1
:
if
section
in
d1
:
...
...
src/zc/buildout/buildout.txt
View file @
ecb15c89
...
@@ -809,7 +809,7 @@ the origin of the value (file name or ``COMPUTED_VALUE``, ``DEFAULT_VALUE``,
...
@@ -809,7 +809,7 @@ the origin of the value (file name or ``COMPUTED_VALUE``, ``DEFAULT_VALUE``,
bin-directory= bin
bin-directory= bin
DEFAULT_VALUE
DEFAULT_VALUE
develop= recipes
develop= recipes
/sample-buildout/
buildout.cfg
buildout.cfg
develop-eggs-directory= develop-eggs
develop-eggs-directory= develop-eggs
DEFAULT_VALUE
DEFAULT_VALUE
directory= /sample-buildout
directory= /sample-buildout
...
@@ -833,7 +833,7 @@ the origin of the value (file name or ``COMPUTED_VALUE``, ``DEFAULT_VALUE``,
...
@@ -833,7 +833,7 @@ the origin of the value (file name or ``COMPUTED_VALUE``, ``DEFAULT_VALUE``,
offline= false
offline= false
DEFAULT_VALUE
DEFAULT_VALUE
parts= data-dir
parts= data-dir
/sample-buildout/
buildout.cfg
buildout.cfg
parts-directory= parts
parts-directory= parts
DEFAULT_VALUE
DEFAULT_VALUE
prefer-final= true
prefer-final= true
...
@@ -853,9 +853,178 @@ the origin of the value (file name or ``COMPUTED_VALUE``, ``DEFAULT_VALUE``,
...
@@ -853,9 +853,178 @@ the origin of the value (file name or ``COMPUTED_VALUE``, ``DEFAULT_VALUE``,
<BLANKLINE>
<BLANKLINE>
[data-dir]
[data-dir]
path= foo bins
path= foo bins
/sample-buildout/
buildout.cfg
buildout.cfg
recipe= recipes:mkdir
recipe= recipes:mkdir
/sample-buildout/buildout.cfg
buildout.cfg
<BLANKLINE>
[versions]
zc.buildout = >=1.99
DEFAULT_VALUE
zc.recipe.egg = >=1.99
DEFAULT_VALUE
<BLANKLINE>
The ``annotate`` command is sensitive to the verbosity flag.
You get more information about the way values are computed::
>>> print_(system(buildout+ ' -v annotate'), end='')
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
<BLANKLINE>
Annotated sections
==================
<BLANKLINE>
[buildout]
allow-hosts= *
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = *
<BLANKLINE>
allow-picked-versions= true
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = true
<BLANKLINE>
bin-directory= bin
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = bin
<BLANKLINE>
develop= recipes
<BLANKLINE>
IN buildout.cfg
SET VALUE = recipes
<BLANKLINE>
develop-eggs-directory= develop-eggs
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = develop-eggs
<BLANKLINE>
directory= /sample-buildout
<BLANKLINE>
AS COMPUTED_VALUE
SET VALUE = /sample-buildout
<BLANKLINE>
eggs-directory= /sample-buildout/eggs
<BLANKLINE>
AS DEFAULT_VALUE
DIRECTORY VALUE = /sample-buildout/eggs
AS DEFAULT_VALUE
SET VALUE = eggs
<BLANKLINE>
executable= ...
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = ...
<BLANKLINE>
find-links=
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE =
<BLANKLINE>
install-from-cache= false
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = false
<BLANKLINE>
installed= .installed.cfg
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = .installed.cfg
<BLANKLINE>
log-format=
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE =
<BLANKLINE>
log-level= INFO
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = INFO
<BLANKLINE>
newest= true
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = true
<BLANKLINE>
offline= false
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = false
<BLANKLINE>
parts= data-dir
<BLANKLINE>
IN buildout.cfg
SET VALUE = data-dir
<BLANKLINE>
parts-directory= parts
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = parts
<BLANKLINE>
prefer-final= true
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = true
<BLANKLINE>
python= buildout
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = buildout
<BLANKLINE>
show-picked-versions= false
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = false
<BLANKLINE>
socket-timeout=
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE =
<BLANKLINE>
update-versions-file=
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE =
<BLANKLINE>
use-dependency-links= true
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = true
<BLANKLINE>
verbosity= 10
<BLANKLINE>
AS COMMAND_LINE_VALUE
SET VALUE = 10
<BLANKLINE>
versions= versions
<BLANKLINE>
AS DEFAULT_VALUE
SET VALUE = versions
<BLANKLINE>
<BLANKLINE>
[data-dir]
path= foo bins
<BLANKLINE>
IN buildout.cfg
SET VALUE = foo bins
<BLANKLINE>
recipe= recipes:mkdir
<BLANKLINE>
IN buildout.cfg
SET VALUE = recipes:mkdir
<BLANKLINE>
<BLANKLINE>
[versions]
...
The output of the ``annotate`` command can be very long.
You can restrict the output to some sections by passing section names as arguments::
>>> print_(system(buildout+ ' annotate versions'), end='')
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
<BLANKLINE>
Annotated sections
==================
<BLANKLINE>
<BLANKLINE>
[versions]
[versions]
zc.buildout= >=1.99
zc.buildout= >=1.99
...
@@ -1384,42 +1553,42 @@ operations::
...
@@ -1384,42 +1553,42 @@ operations::
option= a1 a2
option= a1 a2
a3 a4
a3 a4
a5
a5
/sample-buildout/
base.cfg
base.cfg
+=
/sample-buildout/
extension1.cfg
+= extension1.cfg
+=
/sample-buildout/
extension2.cfg
+= extension2.cfg
recipe=
recipe=
/sample-buildout/
base.cfg
base.cfg
<BLANKLINE>
<BLANKLINE>
[part2]
[part2]
option= b1 b2 b3 b4
option= b1 b2 b3 b4
/sample-buildout/
base.cfg
base.cfg
-=
/sample-buildout/
extension1.cfg
-= extension1.cfg
-=
/sample-buildout/
extension2.cfg
-= extension2.cfg
recipe=
recipe=
/sample-buildout/
base.cfg
base.cfg
<BLANKLINE>
<BLANKLINE>
[part3]
[part3]
option= c1 c2
option= c1 c2
c3 c4 c5
c3 c4 c5
/sample-buildout/
base.cfg
base.cfg
+=
/sample-buildout/
extension1.cfg
+= extension1.cfg
recipe=
recipe=
/sample-buildout/
base.cfg
base.cfg
<BLANKLINE>
<BLANKLINE>
[part4]
[part4]
option= d2
option= d2
d3
d3
d1
d1
d4
d4
/sample-buildout/
base.cfg
base.cfg
+=
/sample-buildout/
extension1.cfg
+= extension1.cfg
-=
/sample-buildout/
extension1.cfg
-= extension1.cfg
recipe=
recipe=
/sample-buildout/
base.cfg
base.cfg
<BLANKLINE>
<BLANKLINE>
[part5]
[part5]
option= h1 h2
option= h1 h2
/sample-buildout/
extension1.cfg
extension1.cfg
[versions]
[versions]
zc.buildout= >=1.99
zc.buildout= >=1.99
DEFAULT_VALUE
DEFAULT_VALUE
...
@@ -1427,6 +1596,77 @@ operations::
...
@@ -1427,6 +1596,77 @@ operations::
DEFAULT_VALUE
DEFAULT_VALUE
<BLANKLINE>
<BLANKLINE>
With more verbosity::
>>> print_(system(os.path.join('bin', 'buildout') + ' -v annotate'), end='')
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
<BLANKLINE>
Annotated sections
==================
...
[part1]
option= a1 a2
a3 a4
a5
<BLANKLINE>
IN extension2.cfg
ADD VALUE = a5
IN extension1.cfg
ADD VALUE = a3 a4
IN base.cfg
SET VALUE = a1 a2
<BLANKLINE>
...
[part2]
option= b1 b2 b3 b4
<BLANKLINE>
IN extension2.cfg
REMOVE VALUE = b1 b2 b3
IN extension1.cfg
REMOVE VALUE = b1 b2
IN base.cfg
SET VALUE = b1 b2 b3 b4
<BLANKLINE>
...
[part3]
option=
c1 c2
c3 c4 c5
<BLANKLINE>
IN extension1.cfg
ADD VALUE = c3 c4 c5
IN base.cfg
SET VALUE = c1 c2
<BLANKLINE>
...
[part4]
option=
d2
d3
d1
d4
<BLANKLINE>
IN extension1.cfg
REMOVE VALUE = d5
IN extension1.cfg
ADD VALUE =
d1
d4
IN base.cfg
SET VALUE =
d2
d3
d5
<BLANKLINE>
...
[part5]
option= h1 h2
<BLANKLINE>
IN extension1.cfg
SET VALUE = h1 h2
<BLANKLINE>
...
Cleanup::
Cleanup::
>>> os.remove(os.path.join(sample_buildout, 'base.cfg'))
>>> os.remove(os.path.join(sample_buildout, 'base.cfg'))
...
...
src/zc/buildout/tests.py
View file @
ecb15c89
...
@@ -3539,7 +3539,7 @@ def test_suite():
...
@@ -3539,7 +3539,7 @@ def test_suite():
(re.compile('
setuptools
'), '
setuptools
'),
(re.compile('
setuptools
'), '
setuptools
'),
(re.compile('
Got
zc
.
recipe
.
egg
\
S
+
'), '
Got
zc
.
recipe
.
egg
'),
(re.compile('
Got
zc
.
recipe
.
egg
\
S
+
'), '
Got
zc
.
recipe
.
egg
'),
(re.compile(r'
zc
\
.(
buildout
|
recipe
\
.
egg
)
\
s
*=
>=
\
S
+
'),
(re.compile(r'
zc
\
.(
buildout
|
recipe
\
.
egg
)
\
s
*=
>=
\
S
+
'),
'
zc
.
\
1
=
>=
1.99
'),
'
zc
.
\
\
1
=
>=
1.99
'),
])
])
) + manuel.capture.Manuel(),
) + manuel.capture.Manuel(),
'
buildout
.
txt
',
'
buildout
.
txt
',
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment