Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements #426: Allow to define multiple local/release folders #428

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
77f6b12
Fixes #422 - Infinite solve if variants can not be solved
May 16, 2017
ccffd2f
Fixes the tests.
May 16, 2017
3923329
Fixes the tests.
May 16, 2017
2689488
Merge branch 'master' of https://github.com/ToonBoxEntertainment/rez
May 16, 2017
f502806
Clean up
May 16, 2017
70e3d07
Implements #426: Allow to define multiple local/release folders
May 16, 2017
9cefc25
Implements #426: Allow to define multiple local/release folders
May 16, 2017
fa4271c
Implements packages paths based on dict with backwards compatibility.
Jun 30, 2017
74764d0
Added specific packages_path_index label is available.
Jun 30, 2017
7ec24e8
Add packages_path_label for non-local packages only if available.
Jun 30, 2017
08b0791
Proper default compatibilty for the label.
Jun 30, 2017
fb75c19
Implements packages paths based on dict with backwards compatibility.
Jun 30, 2017
5c1146d
Renamed packages_path_index to target_packages_path
Jul 11, 2017
90203b4
Added target_packages_path option to rez-bind.
Jul 11, 2017
0e42b63
Type in comment.
Jul 11, 2017
d6c0e51
Fixes is_local for target_packages_path.
Jul 11, 2017
e49f1cf
Fixes the target_packages_path label being correct even if the config…
Jul 11, 2017
71199f7
Use original config so changes do not affect the target_packages_path…
Jul 11, 2017
8cc9cc1
Fixes --no-local
Jul 11, 2017
f83168f
Another no-local issue.
Jul 11, 2017
42debb6
Merge tag '2.13.1' into issue_426
Jul 11, 2017
8d245a8
Merge branch 'master' into issue_426
bfloch Feb 23, 2018
4576803
Merge branch 'master' into issue_426
bfloch Mar 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/rez/cli/bind.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def setup_parser(parser, completions=False):
"-i", "--install-path", dest="install_path", type=str,
default=None, metavar="PATH",
help="install path, defaults to local package path")
parser.add_argument(
"-t", "--target-packages-path", dest="target_packages_path", type=str,
default=None, metavar="TARGET",
help="Sets the target_packages_path for the install")
parser.add_argument(
"--no-deps", dest="no_deps", action="store_true",
help="Do not bind dependencies")
Expand All @@ -39,6 +43,9 @@ def command(opts, parser, extra_arg_groups=None):
get_bind_modules, _print_package_list
from rez.utils.formatting import PackageRequest, columnise

if opts.target_packages_path:
config.target_packages_path = opts.target_packages_path

if opts.release:
install_path = config.release_packages_path
elif opts.install_path:
Expand Down
71 changes: 67 additions & 4 deletions src/rez/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ class OptionalDictOrDictList(Setting):
[dict])


class StrOrDict(Setting):
schema = Or(basestring,
dict)


class SuiteVisibility_(Str):
@cached_class_property
def schema(cls):
Expand Down Expand Up @@ -277,8 +282,9 @@ def _parse_env_var(self, value):
"implicit_styles": OptionalStrList,
"alias_styles": OptionalStrList,
"memcached_uri": OptionalStrList,
"local_packages_path": Str,
"release_packages_path": Str,
"local_packages_path": StrOrDict,
"release_packages_path": StrOrDict,
"target_packages_path": StrOrDict,
"dot_image_format": Str,
"build_directory": Str,
"documentation_url": Str,
Expand Down Expand Up @@ -518,12 +524,42 @@ def data(self):
pass # unknown key, just leave it unchanged
return d


@property
def local_packages_path(self):
"""Returns local_packages_path based on the package_paths_index"""
return self._packages_path('local')

@property
def release_packages_path(self):
"""Returns release_packages_path based on the package_paths_index"""
return self._packages_path('release')

@property
def local_target_packages_path(self):
"""Returns target_packages_path for local"""
return self._target_packages_path('local')

@property
def release_target_packages_path(self):
"""Returns target_packages_path for release"""
return self._target_packages_path('release')

@property
def nonlocal_packages_path(self):
"""Returns package search paths with local path removed."""
paths = self.packages_path[:]
if self.local_packages_path in paths:
paths.remove(self.local_packages_path)
local_packages_paths = config._data['local_packages_path']

if isinstance(local_packages_paths, basestring):
local_packages_paths = [local_packages_paths]
else:
local_packages_paths = local_packages_paths.values()

for local_packages_path in local_packages_paths:
local_packages_path = expand_system_vars(local_packages_path)
if local_packages_path in paths:
paths.remove(local_packages_path)
return paths

def get_completions(self, prefix):
Expand All @@ -549,6 +585,33 @@ def _get_plugin_completions(prefix_):
keys += _get_plugin_completions('')
return keys

def _packages_path(self, local_mode):
if isinstance(self._data[local_mode + '_packages_path'], basestring):
result = self._data[local_mode + '_packages_path']
else:
try:
result = self._data[local_mode + '_packages_path'][self._target_packages_path(local_mode)]
except KeyError as e:
raise ConfigurationError('Invalid target_packages_path "%s" for %s' % (e.message, local_mode))

return expand_system_vars(result)

def _target_packages_path(self, local_mode):
"""Returns the target_packages_path for the local_mode (local or release)"""
# Ignore _target_packages_path if non dict package path.
# Else an unnecessary exception might be raised.
if isinstance(self._data[local_mode + '_packages_path'], basestring):
return None

if isinstance(self.target_packages_path, basestring):
return self.target_packages_path

try:
result = self.target_packages_path[local_mode]
except KeyError as e:
raise ConfigurationError('target_packages_path missing %s' % e.message)
return result

def _uncache(self, key=None):
# deleting the attribute falls up back to the class attribute, which is
# the cached_property descriptor
Expand Down
52 changes: 47 additions & 5 deletions src/rez/packages_.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from rez.utils import reraise
from rez.utils.sourcecode import SourceCode
from rez.utils.data_utils import cached_property
from rez.utils.formatting import StringFormatMixin, StringFormatType
from rez.utils.formatting import StringFormatMixin, StringFormatType, expandvars
from rez.utils.filesystem import is_subdirectory
from rez.utils.schema import schema_keys
from rez.utils.resources import ResourceHandle, ResourceWrapper
from rez.exceptions import PackageFamilyNotFoundError, ResourceError
Expand Down Expand Up @@ -95,12 +96,53 @@ def config(self):
"""
return self.resource.config or config

@cached_property
def target_packages_path(self):
"""Returns the target_packages_path if available, else None"""

# Check both the local and release packages_paths
all_packages_paths = []
if "local_packages_path" in config._data:
all_packages_paths.append(config._data['local_packages_path'])
if "release_packages_path" in config._data:
all_packages_paths.append(config._data['release_packages_path'])

for current_packages_path in all_packages_paths:
if isinstance(current_packages_path, basestring):
packages_paths = { None: current_packages_path }
else:
# Assuming dict version of local_packages_path
packages_paths = current_packages_path

for target, local_packages_path in packages_paths.items():
local_packages_path = expandvars(local_packages_path)
local_repo = package_repository_manager.get_repository(
local_packages_path)
if self.resource._repository.uid == local_repo.uid:
return target
return None

@cached_property
def is_local(self):
"""Returns True if the package is in the local package repository"""
local_repo = package_repository_manager.get_repository(
self.config.local_packages_path)
return (self.resource._repository.uid == local_repo.uid)

# Use the original config data, not the property
original_local_packages_path = config._data['local_packages_path']

if isinstance(original_local_packages_path, basestring):
local_packages_paths = [original_local_packages_path]
else:
# Assuming dict version of local_packages_path
local_packages_paths = original_local_packages_path.values()

for local_packages_path in local_packages_paths:
local_packages_path = expandvars(local_packages_path)
local_repo = package_repository_manager.get_repository(
local_packages_path)
if self.resource._repository.uid == local_repo.uid:
return True

return False

def print_info(self, buf=None, format_=FileFormat.yaml,
skip_attributes=None, include_release=False):
Expand All @@ -117,7 +159,7 @@ def print_info(self, buf=None, format_=FileFormat.yaml,

# config is a special case. We only really want to show any config settings
# that were in the package.py, not the entire Config contents that get
# grafted onto the Package/Variant instance. However Variant has an empy
# grafted onto the Package/Variant instance. However Variant has an empty
# 'data' dict property, since it forwards data from its parent package.
data.pop("config", None)
if self.config:
Expand Down
7 changes: 6 additions & 1 deletion src/rez/resolved_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,8 +755,13 @@ def _rt(t):
col = critical

if pkg.is_local:
t.append('local')
if pkg.target_packages_path:
t.append('local: %s' % pkg.target_packages_path)
else:
t.append('local')
col = local
elif pkg.target_packages_path:
t.append(pkg.target_packages_path)

t = '(%s)' % ', '.join(t) if t else ''
rows.append((pkg.qualified_package_name, location, t))
Expand Down
28 changes: 25 additions & 3 deletions src/rez/rezconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,39 @@
# The package search path. Rez uses this to find packages. A package with the
# same name and version in an earlier path takes precedence.
packages_path = [
"~/packages", # locally installed pkgs, not yet deployed
"~/packages/int", # locally installed internal pkgs, not yet deployed
"~/packages/ext", # locally installed external pkgs, not yet deployed
"~/.rez/packages/int", # internally developed pkgs, deployed
"~/.rez/packages/ext", # external (3rd party) pkgs, such as houdini, boost
]

# The path that Rez will locally install packages to when rez-build is used
local_packages_path = "~/packages"
# The target_packages_path controls which path to use.
# Note: Can be a string for backwards compatibility.
local_packages_path = {
"internal": "~/packages/int",
"external": "~/packages/ext",
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a head's up - I can't accept this change, because it changes an existing default config value, which is a backwards compatibility issue. I will set these back to previous defaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems I never addressed this one. Must have slipped my sight.


# The path that Rez will deploy packages to when rez-release is used. For
# production use, you will probably want to change this to a site-wide location.
release_packages_path = "~/.rez/packages/int"
# The target_packages_path controls which path to use.
# Note: Can be a string for backwards compatibility.
release_packages_path = {
"internal": "~/.rez/packages/int",
"external": "~/.rez/packages/ext",
}

# Defines which local/release_packages_paths are enabled
# Feel free to override this within a package to build/release to different locations.
# Is ignored for *_packages_path that are strings for backwards compatibility.
target_packages_path = "external"
# May also be dict for specific control over local or release
# target_packages_path = {
# "local": "internal",
# "release": "external",
# }


# Where temporary files go. Defaults to appropriate path depending on your
# system - for example, *nix distributions will probably set this to "/tmp". It
Expand Down
2 changes: 1 addition & 1 deletion src/rez/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_1(self):

# check user path expansion
self.assertEqual(c.local_packages_path,
os.path.expanduser(os.path.join("~", "packages")))
os.path.expanduser(os.path.join("~", "packages", "ext")))

# check access to plugins settings common to a plugin type
self.assertEqual(c.plugins.release_vcs.tag_name, '{qualified_name}')
Expand Down
8 changes: 7 additions & 1 deletion src/rez/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,13 @@ def print_package_versions(self):
name = " %s" % pkg.qualified_name
col = local if pkg.is_local else None

label = "(local)" if pkg.is_local else ""
label = ""
if pkg.is_local:
if pkg.path_index:
label = "(local: %s)" % pkg.path_index
else:
label = "(local)"

rows.append((name, pkg.path, label))
colors.append(col)

Expand Down