import-checker: make imported_modules yield absolute dotted_name_of_path
This patch makes `imported_modules()` always yield absolute
`dotted_name_of_path()`-ed name by strict detection with
`fromlocal()`.
This change improves circular detection in some points:
- locally defined modules, of which name collides against one of
standard library, can be examined correctly
For example, circular import related to `commands` is overlooked
before this patch.
- names not useful for circular detection are ignored
Names below are also yielded before this patch:
- module names of standard library (= not locally defined one)
- non-module names (e.g. `node.nullid` of `from node import nullid`)
These redundant names decrease performance of circular detection.
For example, with files at
1ef96a3b8b89, average loops per file in
`checkmod()` is reduced from 165 to 109.
- `__init__` can be handled correctly in `checkmod()`
For example, current implementation has problems below:
- `from xxx import yyy` doesn't recognize `xxx.__init__` as imported
- `xxx.__init__` imported via `import xxx` is treated as `xxx`,
and circular detection is aborted, because `key` of such
module name is not `xxx` but `xxx.__init__`
- it is easy to enhance for `from . import xxx` style or so (in the
future)
Module name detection in `imported_modules()` can use information
in `ast.ImportFrom` fully.
It is assumed that all locally defined modules are correctly specified
to `import-checker.py` at once.
Strictly speaking, when `from foo.bar.baz import module1` imports
`foo.bar.baz.module1` module, current `imported_modules()` yields only
`foo.bar.baz.__init__`, even though also `foo.__init__` and
`foo.bar.__init__` should be yielded to detect circular import
exactly.
But this limitation is reasonable one for improvement in this patch,
because current `__init__` files in Mercurial seems to be implemented
carefully.
#!/bin/sh -eu
# This function exists to set up the DOCKER variable and verify that
# it's the binary we expect. It also verifies that the docker service
# is running on the system and we can talk to it.
function checkdocker() {
if which docker.io >> /dev/null 2>&1 ; then
DOCKER=docker.io
elif which docker >> /dev/null 2>&1 ; then
DOCKER=docker
else
echo "Error: docker must be installed"
exit 1
fi
$DOCKER -h 2> /dev/null | grep -q Jansens && { echo "Error: $DOCKER is the Docking System Tray - install docker.io instead"; exit 1; }
$DOCKER version | grep -q "^Client version:" || { echo "Error: unexpected output from \"$DOCKER version\""; exit 1; }
$DOCKER version | grep -q "^Server version:" || { echo "Error: could not get docker server version - check it is running and your permissions"; exit 1; }
}
# Construct a container and leave its name in $CONTAINER for future use.
function initcontainer() {
[ "$1" ] || { echo "Error: platform name must be specified"; exit 1; }
DFILE="$ROOTDIR/contrib/docker/$1"
[ -f "$DFILE" ] || { echo "Error: docker file $DFILE not found"; exit 1; }
CONTAINER="hg-dockerrpm-$1"
DBUILDUSER=build
(
cat $DFILE
if [ $(uname) = "Darwin" ] ; then
# The builder is using boot2docker on OS X, so we're going to
# *guess* the uid of the user inside the VM that is actually
# running docker. This is *very likely* to fail at some point.
echo RUN useradd $DBUILDUSER -u 1000
else
echo RUN groupadd $DBUILDUSER -g `id -g`
echo RUN useradd $DBUILDUSER -u `id -u` -g $DBUILDUSER
fi
) | $DOCKER build --tag $CONTAINER -
}