Skip to content

Commit

Permalink
feat: another way to test packages in dev stage.
Browse files Browse the repository at this point in the history
Let's say we have a package `helloworld` in D:\dev\helloworld(a pure python package, and no version specified) want to test, but don't want to move it to any package repository or package filters, instead call this package like this:
`rez-env helloworld pkg1 pkg2 ... -d D:\dev`, helloworld will be resolved to D:\dev\helloworld, but pkg1 and pkg2 resolved to a repository path in rez config. or if is also in D:\dev folder.
  • Loading branch information
frankchen211 committed Mar 20, 2022
1 parent 87ee4e6 commit 5f94b9c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
11 changes: 11 additions & 0 deletions src/rez/cli/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ def setup_parser(parser, completions=False):
parser.add_argument(
"--paths", type=str, default=None,
help="set package search path (use %r separator)" % os.pathsep)
parser.add_argument(
"-d", "--dev-paths", type=str, default=None,
help="search packages from these dev paths if found, otherwise from formal search path,"
"normally for testing purpose, non-version packages (use %r separator)." % os.pathsep)
parser.add_argument(
"-t", "--time", type=str,
help="ignore packages released after the given time. Supported formats "
Expand Down Expand Up @@ -157,6 +161,13 @@ def command(opts, parser, extra_arg_groups=None):
request = opts.PKG
t = get_epoch_time_from_str(opts.time) if opts.time else None

if opts.dev_paths:
for path in opts.dev_paths.split(os.pathsep):
path = os.path.abspath(path)
for idx, pkg in enumerate(request):
if pkg in os.listdir(path):
request[idx] = '{}@{}'.format(pkg, os.path.join(path, pkg))

if opts.paths is None:
pkg_paths = (config.nonlocal_packages_path
if opts.no_local else None)
Expand Down
16 changes: 11 additions & 5 deletions src/rez/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,14 +464,20 @@ def __init__(self, package_name, solver):
self.package_name = package_name
self.solver = solver

self.entries = []

request_package = solver.request_list.get(package_name)
if request_package and request_package.request_path:
# it seems DeveloperPackage can't be used in this way
# self.entries.append([get_developer_package(request_package.request_path), False])
paths = [os.path.dirname(os.path.abspath(request_package.request_path))]
else:
paths = self.solver.package_paths
# note: we do not apply package filters here, because doing so might
# cause package loads (eg, timestamp rules). We only apply filters
# during an intersection, which minimises the amount of filtering.
#
self.entries = []

for package in iter_packages(self.package_name,
paths=self.solver.package_paths):
for package in iter_packages(self.package_name, paths=paths):
package.set_context(solver.context)
self.entries.append([package, False])

Expand All @@ -497,7 +503,7 @@ def get_intersection(self, range_):
if value is None:
continue # package was blocked by package filters

if package.version not in range_:
if not range_.is_a_folder() and package.version not in range_:
continue

if isinstance(value, list):
Expand Down
9 changes: 8 additions & 1 deletion src/rez/vendor/version/requirement.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the Rez Project

import os.path

from rez.vendor.version.version import Version, VersionRange
from rez.vendor.version.util import _Common
Expand Down Expand Up @@ -132,6 +132,7 @@ def __init__(self, s, invalid_bound_error=True):
self.negate_ = False
self.conflict_ = False
self._str = None
self._request_path = None
self.sep_ = '-'
if s is None:
return
Expand All @@ -152,6 +153,8 @@ def __init__(self, s, invalid_bound_error=True):
if req_str[0] in ('-', '@', '#'):
self.sep_ = req_str[0]
req_str = req_str[1:]
if os.path.exists(os.path.abspath(req_str)):
self._request_path = req_str

self.range_ = VersionRange(
req_str, invalid_bound_error=invalid_bound_error)
Expand Down Expand Up @@ -184,6 +187,10 @@ def name(self):
"""Name of the required object."""
return self.name_

@property
def request_path(self):
return self._request_path

@property
def range(self):
"""VersionRange of the requirement."""
Expand Down
10 changes: 10 additions & 0 deletions src/rez/vendor/version/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import copy
import string
import re
import os


re_token = re.compile(r"[a-zA-Z0-9_]+")
Expand Down Expand Up @@ -859,10 +860,16 @@ def __init__(self, range_str='', make_token=AlphanumericVersionToken,
impossible range is given, such as '3+<2'.
"""
self._str = None
self._is_a_folder = False
self.bounds = [] # note: kept in ascending order
if range_str is None:
return

if os.path.isdir(range_str):
self._is_a_folder = True
self._str = range_str
return

try:
parser = _VersionRangeParser(range_str, make_token,
invalid_bound_error=invalid_bound_error)
Expand All @@ -884,6 +891,9 @@ def is_any(self):
that contains all versions."""
return (len(self.bounds) == 1) and (self.bounds[0] == _Bound.any)

def is_a_folder(self):
return self._is_a_folder

def lower_bounded(self):
"""Returns True if the range has a lower bound (that is not the empty
version)."""
Expand Down

0 comments on commit 5f94b9c

Please sign in to comment.