Commit 746b78d6 authored by Monty Taylor's avatar Monty Taylor

Clean up hacking and path issues with d2to1

We imported in another code base. It takes a little bit of path
adjusting to get things right.

Change-Id: Ifb96652c822d5d243a6bedb77bc34e919be2d3a8
parent 295dbe1d
# Format is:
# <preferred e-mail> <other e-mail 1>
# <preferred e-mail> <other e-mail 2>
Davanum Srinivas <dims@linux.vnet.ibm.com> <davanum@gmail.com>
Erik M. Bray <embray@stsci.edu> Erik Bray <embray@stsci.edu>
Zhongyue Luo <zhongyue.nah@intel.com> <lzyeval@gmail.com>
......@@ -13,9 +13,20 @@ it's simple and repeatable. If you want to do things differently, cool! But
you've already got the power of python at your fingertips, so you don't
really need PBR.
PBR builds on top of `d2to1` to provide for declarative configuration. It
then filters the `setup.cfg` data through a setup hook to fill in default
values and provide more sensible behaviors.
PBR builds on top of the work that `d2to1` started to provide for declarative
configuration. `d2to1` is itself an implementation of the ideas behind
`distutils2`. Although `distutils2` is now abandoned in favor of work towards
PEP 426 and Metadata 2.0, declarative config is still a great idea and
specifically important in trying to distribute setup code as a library
when that library itself will alter how the setup is processed. As Metadata
2.0 and other modern Python packaging PEPs come out, `pbr` aims to support
them as quickly as possible.
`pbr` reads and then filters the `setup.cfg` data through a setup hook to
fill in default values and provide more sensible behaviors, and then feeds
the results in as the arguments to a call to `setup.py` - so the heavy
lifting of handling python packaging needs is still being done by
`setuptools`.
Behaviors
=========
......@@ -124,11 +135,11 @@ The minimal setup.py should look something like this::
from setuptools import setup
setup(
setup_requires=['d2to1', 'pbr'],
d2to1=True,
setup_requires=['pbr'],
pbr=True,
)
Note that it's important to specify `d2to1=True` or else the pbr functionality
Note that it's important to specify `pbr=True` or else the pbr functionality
will not be enabled.
It should also work fine if additional arguments are passed to `setup()`,
......
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
from distutils import core
from distutils import errors
import os
import sys
import warnings
from distutils.core import Distribution as _Distribution
from distutils.errors import DistutilsFileError, DistutilsSetupError
from setuptools.dist import _get_unpatched
from setuptools import dist
from .extern import six
from .util import DefaultGetDict, IgnoreDict, cfg_to_args
from pbr.d2to1 import util
_Distribution = _get_unpatched(_Distribution)
core.Distribution = dist._get_unpatched(core.Distribution)
if sys.version_info[0] == 3:
string_type = str
integer_types = int
else:
string_type = basestring
integer_types = (int, long)
def d2to1(dist, attr, value):
"""Implements the actual d2to1 setup() keyword. When used, this should be
def pbr(dist, attr, value):
"""Implements the actual pbr setup() keyword. When used, this should be
the only keyword in your setup() aside from `setup_requires`.
If given as a string, the value of d2to1 is assumed to be the relative path
If given as a string, the value of pbr is assumed to be the relative path
to the setup.cfg file to use. Otherwise, if it evaluates to true, it
simply assumes that d2to1 should be used, and the default 'setup.cfg' is
simply assumes that pbr should be used, and the default 'setup.cfg' is
used.
This works by reading the setup.cfg file, parsing out the supported
......@@ -33,20 +78,20 @@ def d2to1(dist, attr, value):
if not value:
return
if isinstance(value, six.string_types):
if isinstance(value, string_type):
path = os.path.abspath(value)
else:
path = os.path.abspath('setup.cfg')
if not os.path.exists(path):
raise DistutilsFileError(
raise errors.DistutilsFileError(
'The setup.cfg file %s does not exist.' % path)
# Converts the setup.cfg file to setup() arguments
try:
attrs = cfg_to_args(path)
except:
attrs = util.cfg_to_args(path)
except Exception:
e = sys.exc_info()[1]
raise DistutilsSetupError(
raise errors.DistutilsSetupError(
'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
# Repeat some of the Distribution initialization code with the newly
......@@ -54,7 +99,7 @@ def d2to1(dist, attr, value):
if attrs:
# Skips 'options' and 'licence' support which are rarely used; may add
# back in later if demanded
for key, val in six.iteritems(attrs):
for key, val in attrs.items():
if hasattr(dist.metadata, 'set_' + key):
getattr(dist.metadata, 'set_' + key)(val)
elif hasattr(dist.metadata, key):
......@@ -66,10 +111,10 @@ def d2to1(dist, attr, value):
warnings.warn(msg)
# Re-finalize the underlying Distribution
_Distribution.finalize_options(dist)
core.Distribution.finalize_options(dist)
# This bit comes out of distribute/setuptools
if isinstance(dist.metadata.version, six.integer_types + (float,)):
if isinstance(dist.metadata.version, integer_types + (float,)):
# Some people apparently take "version number" too literally :)
dist.metadata.version = str(dist.metadata.version)
......@@ -79,4 +124,4 @@ def d2to1(dist, attr, value):
# their options. Now it will be a defaultdict that returns IgnoreDicts for
# the each command's options so we can pass through the unsupported options
ignore = ['pre_hook.*', 'post_hook.*']
dist.command_options = DefaultGetDict(lambda: IgnoreDict(ignore))
dist.command_options = util.DefaultGetDict(lambda: util.IgnoreDict(ignore))
try:
__version__ = __import__('pkg_resources').get_distribution('d2to1').version
except:
__version__ = ''
This diff is collapsed.
from __future__ import with_statement
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
import os
import shutil
import subprocess
import sys
import tempfile
import pkg_resources
from .util import rmtree, open_config
D2TO1_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
os.pardir, os.pardir))
def fake_d2to1_dist():
# Fake a d2to1 distribution from the d2to1 package that these tests reside
# in and make sure it's active on the path with the appropriate entry
# points installed
class _FakeProvider(pkg_resources.EmptyProvider):
"""A fake metadata provider that does almost nothing except to return
entry point metadata.
"""
import fixtures
import testtools
def has_metadata(self, name):
return name == 'entry_points.txt'
def get_metadata(self, name):
if name == 'entry_points.txt':
return '[distutils.setup_keywords]\nd2to1 = d2to1.core:d2to1\n'
else:
return ''
sys.path.insert(0, D2TO1_DIR)
if 'd2to1' in sys.modules:
del sys.modules['d2to1']
if 'd2to1' in pkg_resources.working_set.by_key:
del pkg_resources.working_set.by_key['d2to1']
dist = pkg_resources.Distribution(location=D2TO1_DIR, project_name='d2to1',
metadata=_FakeProvider())
pkg_resources.working_set.add(dist)
class D2to1TestCase(object):
def setup(self):
self.temp_dir = tempfile.mkdtemp(prefix='d2to1-test-')
class D2to1TestCase(testtools.TestCase):
def setUp(self):
super(D2to1TestCase, self).setUp()
self.temp_dir = self.useFixture(fixtures.TempDir()).path
self.package_dir = os.path.join(self.temp_dir, 'testpackage')
shutil.copytree(os.path.join(os.path.dirname(__file__), 'testpackage'),
self.package_dir)
self.oldcwd = os.getcwd()
self.addCleanup(os.chdir, os.getcwd())
os.chdir(self.package_dir)
def teardown(self):
os.chdir(self.oldcwd)
def tearDown(self):
# Remove d2to1.testpackage from sys.modules so that it can be freshly
# re-imported by the next test
for k in list(sys.modules):
if (k == 'd2to1_testpackage' or
k.startswith('d2to1_testpackage.')):
k.startswith('d2to1_testpackage.')):
del sys.modules[k]
rmtree(self.temp_dir)
super(D2to1TestCase, self).tearDown()
def run_setup(self, *args):
cmd = ('-c',
'import sys;sys.path.insert(0, %r);'
'from d2to1.tests import fake_d2to1_dist;'
'from d2to1.extern.six import exec_;'
'fake_d2to1_dist();exec_(open("setup.py").read())' % D2TO1_DIR)
return self._run_cmd(sys.executable, cmd + args)
def run_svn(self, *args):
return self._run_cmd('svn', args)
return self._run_cmd(sys.executable, ('setup.py',) + args)
def _run_cmd(self, cmd, args):
"""
"""Run a command in the root of the test working copy.
Runs a command, with the given argument list, in the root of the test
working copy--returns the stdout and stderr streams and the exit code
from the subprocess.
......
from . import D2to1TestCase
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
from testtools import content
class TestCommands(D2to1TestCase):
from pbr.d2to1 import tests
class TestCommands(tests.D2to1TestCase):
def test_custom_build_py_command(self):
"""
"""Test custom build_py command.
Test that a custom subclass of the build_py command runs when listed in
the commands [global] option, rather than the normal build command.
"""
stdout, _, return_code = self.run_setup('build_py')
assert 'Running custom build_py command.' in stdout
assert return_code == 0
stdout, stderr, return_code = self.run_setup('build_py')
self.addDetail('stdout', content.text_content(stdout))
self.addDetail('stderr', content.text_content(stderr))
self.assertIn('Running custom build_py command.', stdout)
self.assertEqual(return_code, 0)
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
import glob
import os
import tarfile
from . import D2to1TestCase
VERSION = '0.1.dev'
from pbr.d2to1 import tests
class TestCore(D2to1TestCase):
def test_setup_py_version(self):
"""
Test that the `./setup.py --version` command returns the correct
value without balking.
"""
self.run_setup('egg_info')
stdout, _, _ = self.run_setup('--version')
assert stdout == VERSION
class TestCore(tests.D2to1TestCase):
def test_setup_py_keywords(self):
"""
"""setup.py --keywords.
Test that the `./setup.py --keywords` command returns the correct
value without balking.
"""
......@@ -30,9 +59,7 @@ class TestCore(D2to1TestCase):
assert stdout == 'packaging,distutils,setuptools'
def test_sdist_extra_files(self):
"""
Test that the extra files are correctly added.
"""
"""Test that the extra files are correctly added."""
stdout, _, return_code = self.run_setup('sdist', '--formats=gztar')
......
from __future__ import with_statement
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
import os
import textwrap
from . import D2to1TestCase
from .util import open_config
from pbr.d2to1 import tests
from pbr.d2to1.tests import util
class TestHooks(D2to1TestCase):
def setup(self):
super(TestHooks, self).setup()
with open_config(os.path.join(self.package_dir, 'setup.cfg')) as cfg:
class TestHooks(tests.D2to1TestCase):
def setUp(self):
super(TestHooks, self).setUp()
with util.open_config(
os.path.join(self.package_dir, 'setup.cfg')) as cfg:
cfg.set('global', 'setup-hooks',
'd2to1_testpackage._setup_hooks.test_hook_1\n'
'd2to1_testpackage._setup_hooks.test_hook_2')
......@@ -20,7 +59,8 @@ class TestHooks(D2to1TestCase):
'd2to1_testpackage._setup_hooks.test_post_hook')
def test_global_setup_hooks(self):
"""
"""Test setup_hooks.
Test that setup_hooks listed in the [global] section of setup.cfg are
executed in order.
"""
......@@ -30,7 +70,8 @@ class TestHooks(D2to1TestCase):
assert return_code == 0
def test_command_hooks(self):
"""
"""Test command hooks.
Simple test that the appropriate command hooks run at the
beginning/end of the appropriate command.
"""
......@@ -45,7 +86,7 @@ class TestHooks(D2to1TestCase):
running build_ext
running pre_hook d2to1_testpackage._setup_hooks.test_pre_hook for command build_ext
build_ext pre-hook
""") in stdout
""") in stdout # flake8: noqa
assert stdout.endswith('build_ext post-hook')
assert return_code == 0
......
from distutils.command.build_py import build_py
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
from distutils.command import build_py
def test_hook_1(config):
......@@ -9,12 +49,12 @@ def test_hook_2(config):
print('test_hook_2')
class test_command(build_py):
class test_command(build_py.build_py):
command_name = 'build_py'
def run(self):
print('Running custom build_py command.')
return build_py.run(self)
return build_py.build_py.run(self)
def test_pre_hook(cmdobj):
......
This diff is collapsed.
#!/usr/bin/env python
try:
from setuptools import setup
except ImportError:
from distribute_setup import use_setuptools
use_setuptools()
from setuptools import setup
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
setup(
setup_requires=['d2to1'],
d2to1=True,
import setuptools
setuptools.setup(
setup_requires=['pbr'],
pbr=True,
)
from __future__ import with_statement
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (C) 2013 Association of Universities for Research in Astronomy
# (AURA)
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of AURA and its representatives may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
import contextlib
import os
import shutil
import stat
from ..extern.six import moves as m
ConfigParser = m.configparser.ConfigParser
try:
import configparser
except ImportError:
import ConfigParser as configparser
@contextlib.contextmanager
def open_config(filename):
cfg = ConfigParser()
cfg = configparser.ConfigParser()
cfg.read(filename)
yield cfg
with open(filename, 'w') as fp:
......@@ -20,9 +59,9 @@ def open_config(filename):
def rmtree(path):
"""
shutil.rmtree() with error handler for 'access denied' from trying to
delete read-only files.
"""shutil.rmtree() with error handler.
Handle 'access denied' from trying to delete read-only files.
"""
def onerror(func, path, exc_info):
......
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.