Skip to content

Commit

Permalink
[catchup a.r.openerp-1.9] up to fix for Odoo setup.py
Browse files Browse the repository at this point in the history
Merge branch 'a.r.openerp-1.9'

Conflicts:
	CHANGES.rst
	anybox/recipe/odoo/base.py
	anybox/recipe/odoo/server.py
	anybox/recipe/odoo/tests/test_base.py
	anybox/recipe/odoo/tests/test_server.py
	anybox/recipe/odoo/vcs/git.py
  • Loading branch information
Georges Racinet committed Dec 2, 2014
2 parents 173effe + 2f9eb62 commit a2f7ef4
Show file tree
Hide file tree
Showing 22 changed files with 1,234 additions and 387 deletions.
15 changes: 12 additions & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,20 @@ with any higher released unstable versions.
1.9.0 (unreleased)
------------------
- rename to anybox.recipe.odoo
- launchpad #1214832 (related): introduction of explicit 'group'
option for standalone addons.
- launchpad #1332147: insensitivity to project name in setup.py
(openerp, odoo, whatever).
- launchpad #1332465: [git] support for shallow clones (--depth),
refactor to allow this consistently with detached head states,
branch changes, etc.
- launchpad #1358353: with github layout, respect ordering if the place of the
standards (non-base) addons is explicitely set as 'local' (allows to insert
overrides before them).
- launchpad #1391571 (related): revert used to fail with grouped
standalone addons
- launchpad #1391571 (related): revert used to fail if some sources
were 'local' or 'downloadable'.
- launchpad #1214832 (related): introduction of explicit 'group'
option for standalone addons.
- launchpad #1294020: vcs-revert=on-merge option, and implementation
for bzr
- launchpad #1274174: new feature for automatic merge of remote VCS
Expand All @@ -23,7 +32,7 @@ with any higher released unstable versions.
- launchpad #1232729: handling of server-wide modules by the recipe
- launchpad #1327609: support inline comments in multi-line options

1.8.6 (unreleased)
1.8.6 (2014-11-17)
------------------
- launchpad #1358353: with github layout, respect ordering if the place of the
standards (non-base) addons is explicitely set as 'local' (allows to insert
Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ Contributors:
* Stefan Rijnhart
* Stéphane Bidoul
* Sebastian Kennedy
* Laetitia Gangloff
81 changes: 59 additions & 22 deletions anybox/recipe/odoo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,24 +452,40 @@ def sandboxed_tar_extract(self, sandbox, tarfile, first=None):
def develop(self, src_directory):
"""Develop the specified source distribution.
Any call to zc.recipe.eggs will use that developped version.
develop() launches a subprocess, to which we need to forward
Any call to ``zc.recipe.eggs`` will use that developped version.
:meth:`develop` launches a subprocess, to which we need to forward
the paths to requirements via PYTHONPATH.
If setup_has_pil is True, an altered version of setup that does not
require it is produced to perform the develop.
:param setup_has_pil: if ``True``, an altered version of setup that
does not require PIL is produced to perform the
develop, so that installation can be done with
``Pillow`` instead. Recent enough versions of
OpenERP/Odoo are directly based on Pillow.
:returns: project name of the distribution that's been "developed"
This is useful for OpenERP/Odoo itself, whose project name
changed within the 8.0 stable branch.
"""
logger.debug("Developing %r", src_directory)
develop_dir = self.b_options['develop-eggs-directory']
pythonpath_bak = os.getenv('PYTHONPATH')
os.putenv('PYTHONPATH', ':'.join(self.recipe_requirements_paths))

zc.buildout.easy_install.develop(src_directory, develop_dir)
egg_link = zc.buildout.easy_install.develop(src_directory, develop_dir)

suffix = '.egg-link'

if pythonpath_bak is None:
os.unsetenv('PYTHONPATH')
else:
os.putenv('PYTHONPATH', pythonpath_bak)

if not egg_link.endswith(suffix):
raise RuntimeError(
"Development of OpenERP/Odoo distribution "
"produced an unexpected egg link: %r" % egg_link)

return os.path.basename(egg_link)[:-len(suffix)]

def parse_addons(self, options):
"""Parse the addons options into :attr:`sources`.
Expand All @@ -496,6 +512,10 @@ def parse_addons(self, options):
"Please check format " % line)

addons_dir = addons_dir.rstrip('/') # trailing / can be harmful
group = options.get('group')
if group:
split = os.path.split(addons_dir)
addons_dir = os.path.join(split[0], group, split[1])
self.sources[addons_dir] = (loc_type, location_spec, options)

def parse_merges(self, options):
Expand Down Expand Up @@ -576,12 +596,11 @@ def retrieve_addons(self):
options = dict(offline=self.offline,
clear_locks=self.vcs_clear_locks,
clean=self.clean)
if loc_type == 'git':
options['depth'] = self.options.get('git-depth')
options.update(addons_options)

group = addons_options.get('group')
# TODO forbid groupping in local addons
# the recipe should not consider it can have responsibility over
# this
group_dir = None
if group:
if loc_type == 'local':
Expand All @@ -595,11 +614,9 @@ def retrieve_addons(self):
"you create yourself the intermediate directory." % (
local_dir, ))

l0, l1 = os.path.split(local_dir)
group_dir = join(l0, group)
local_dir = join(group_dir, l1)
group_dir = os.path.dirname(local_dir)
if not os.path.exists(group_dir):
os.mkdir(group_dir)
os.makedirs(group_dir)
if loc_type != 'local':
for k, v in self.options.items():
if k.startswith(loc_type + '-'):
Expand Down Expand Up @@ -636,10 +653,11 @@ def retrieve_addons(self):
def revert_sources(self):
"""Revert all sources to the revisions specified in :attr:`sources`.
"""
for target, (vcs_type, vcs_spec, options) in self.sources.iteritems():
if vcs_type in ('local', 'downloadable'):
for target, desc in self.sources.iteritems():
if desc[0] in ('local', 'downloadable'):
continue

vcs_type, vcs_spec, options = desc
local_dir = self.openerp_dir if target is main_software else target
local_dir = self.make_absolute(local_dir)
repo = vcs.repo(vcs_type, local_dir, vcs_spec[0], **options)
Expand Down Expand Up @@ -779,6 +797,9 @@ def retrieve_main_software(self):
url, rev = source[1]
options = dict((k, v) for k, v in self.options.iteritems()
if k.startswith(type_spec + '-'))
if type_spec == 'git':
options['depth'] = options.pop('git-depth', None)

options.update(source[2])
if self.clean:
options['clean'] = True
Expand Down Expand Up @@ -1103,9 +1124,23 @@ def _extract_sources(self, out_conf, target_dir, extracted):
out_conf.set(self.name, 'version', 'local ' + rel_path)
continue

addons_line = ['local', local_path]
# stripping the group option that won't be usefult
# and actually harming for extracted buildout conf
options = source[2]
group = options.pop('group', None)
if group:
target_local_path = os.path.dirname(local_path)
if group != os.path.basename(target_local_path):
raise RuntimeError(
"Inconsistent configuration that "
"should not happen: group=%r, but resulting path %r "
"does not have it as its parent" % (group, local_path))
else:
target_local_path = local_path

addons_line = ['local', target_local_path]
addons_line.extend('%s=%s' % (opt, val)
for opt, val in source[2].items())
for opt, val in options.items())
addons_option.append(' '.join(addons_line))

abspath = self.make_absolute(local_path)
Expand Down Expand Up @@ -1225,8 +1260,6 @@ def _prepare_extracted_buildout(self, conf, target_dir):
exts.remove('gp.vcsdevelop')
conf.set('buildout', 'extensions', '\n'.join(exts))



def _install_script(self, name, content):
"""Install and register a scripbont with prescribed name and content.
Expand Down Expand Up @@ -1329,10 +1362,14 @@ def cleanup_openerp_dir(self):
These can be, e.g., forbidden by the freeze process."""

# GR TODO this will break with OSError if main package is renamed to
# 'odoo' we'll see then what the needed correction exactly is rather
# than swallowing the exception now
shutil.rmtree(join(self.openerp_dir, 'openerp.egg-info'))
# from here we can't guess whether it's 'openerp' or 'odoo'.
# Nothing guarantees that this method is called after develop().
# It is in practice now, but one day, the extraction as a separate
# script of freeze/extract will become a reality.
for proj_name in ('openerp', 'odoo'):
egg_info_dir = join(self.openerp_dir, proj_name + '.egg-info')
if os.path.exists(egg_info_dir):
shutil.rmtree(egg_info_dir)

def buildout_cfg_name(self, argv=None):
"""Return the name of the config file that's been called.
Expand Down
6 changes: 4 additions & 2 deletions anybox/recipe/odoo/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ def merge_requirements(self):
of adding Pillow, which is now in Odoo's ``setup.py``.
"""
openerp_dir = getattr(self, 'openerp_dir', None)
openerp_project_name = 'openerp'
if openerp_dir is not None: # happens in unit tests
self.develop(openerp_dir)
self.requirements.append('openerp')
openerp_project_name = self.develop(openerp_dir)
self.requirements.append(openerp_project_name)

if self.with_gunicorn:
self.requirements.extend(('psutil', 'gunicorn'))
Expand All @@ -93,6 +94,7 @@ def merge_requirements(self):
self.requirements.extend(devtools.requirements)

BaseRecipe.merge_requirements(self)
return openerp_project_name

def _create_default_config(self):
"""Have OpenERP generate its default config file.
Expand Down
77 changes: 76 additions & 1 deletion anybox/recipe/odoo/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,35 @@
import unittest
import sys
import shutil
import subprocess
from tempfile import mkdtemp
from UserDict import UserDict
from zc.buildout.easy_install import Installer

from . import vcs
from . import utils
from .base import BaseRecipe

COMMIT_USER_NAME = 'Test'
COMMIT_USER_EMAIL = 'test@example.org'
COMMIT_USER_FULL = '%s %s' % (COMMIT_USER_NAME, COMMIT_USER_EMAIL)


class TestingRecipe(BaseRecipe):
"""A subclass with just enough few defaults for unit testing."""

release_filenames = {'8.0': 'blob-%s.tgz'}
nightly_filenames = {'8.0': '8-0-nightly-%s.tbz'}
release_dl_url = {'8.0': 'http://release.odoo.test/src/'}

def __init__(self, buildout, name, options):
# we need to make buildout a regular object, because some subsystems
# will set extra attributes on it
if isinstance(buildout, dict):
buildout = UserDict(buildout)
super(TestingRecipe, self).__init__(buildout, name, options)


class FakeRepo(vcs.base.BaseRepo):

log = []
Expand Down Expand Up @@ -41,7 +60,7 @@ def get_update(self, revision):

def revert(self, revision):
self.revision = revision
self.log.append(('revert', revision))
self.log.append(('revert', revision, self.target_dir))

def parents(self, pip_compatible=False):
return [self.revision]
Expand All @@ -65,6 +84,33 @@ def clear_vcs_log():
FakeRepo.log = []


class PersistentRevFakeRepo(FakeRepo):
"""A variant of FakeRepo that still needs the directory structure around.
Makes for a more realistic test of some conditions.
In particular, reproduced launchpad #TODO
"""

current_revisions = {}

@property
def revision(self):
return self.__class__.current_revisions.get(self.target_dir, 'fakerev')

@revision.setter
def revision(self, v):
self.__class__.current_revisions[self.target_dir] = v

def uncommitted_changes(self):
"""This needs the directory to really exist and is controllable."""
files = set(os.listdir(self.target_dir))
files.discard('.fake')
return bool(files)


vcs.SUPPORTED['pr_fakevcs'] = PersistentRevFakeRepo


class RecipeTestCase(unittest.TestCase):
"""A base setup for tests of recipe classes"""

Expand Down Expand Up @@ -108,7 +154,36 @@ def _obtain(inst, requirement, source=None):
return inst._orig_obtain(requirement, source=source)
Installer._obtain = _obtain

def make_recipe(self, name='openerp', **options):
self.recipe = TestingRecipe(self.buildout, name, options)

def tearDown(self):
clear_vcs_log()
shutil.rmtree(self.buildout_dir)
Installer._obtain = Installer._orig_obtain

# leftover egg-info at root of the source dir (frequent cwd)
# impairs use of this very same source dir for real-life testing
# with a 'develop' option.
egg_info = 'Babel.egg-info'
if os.path.isdir(egg_info):
shutil.rmtree(egg_info)

def build_babel_egg(self):
"""build an egg for fake babel in buildout's eggs directory.
Require the test case to already have a ``test_dir`` attribute
(typically set on class with the dirname of the test)
"""
subprocess.check_call(
[sys.executable, 'setup.py',
'bdist_egg',
'-d', self.recipe.b_options['eggs-directory'],
'-b', os.path.join(self.buildout_dir, 'build')],
cwd=os.path.join(self.test_dir, 'fake_babel'),
stdout=subprocess.PIPE)

def fill_working_set(self):
self.build_babel_egg()
self.recipe.options['eggs'] = 'Babel'
self.recipe.install_requirements() # to get 'ws' attribute
2 changes: 1 addition & 1 deletion anybox/recipe/odoo/tests/fake_babel/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[egg_info]
tag_date = 0
tag_build =
tag_build = -dev
1 change: 1 addition & 0 deletions anybox/recipe/odoo/tests/odoo-project-renaming/odoo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/usr/bin/env python
2 changes: 2 additions & 0 deletions anybox/recipe/odoo/tests/odoo-project-renaming/openerp-gevent
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env python

2 changes: 2 additions & 0 deletions anybox/recipe/odoo/tests/odoo-project-renaming/openerp-server
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env python

Empty file.
Loading

0 comments on commit a2f7ef4

Please sign in to comment.