-
-
Notifications
You must be signed in to change notification settings - Fork 632
This adds support for "extras". #18
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Copyright 2017 The Bazel Authors. All rights reserved. | ||
# | ||
# 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. | ||
package(default_visibility = ["//visibility:public"]) | ||
|
||
licenses(["notice"]) # Apache 2.0 | ||
|
||
load("@examples_extras//:requirements.bzl", "requirement") | ||
load("//python:python.bzl", "py_test") | ||
|
||
py_test( | ||
name = "extras_test", | ||
srcs = ["extras_test.py"], | ||
deps = [ | ||
requirement("google-cloud-language"), | ||
# Make sure that we can resolve the "extra" dependency | ||
requirement("googleapis-common-protos[grpc]"), | ||
], | ||
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Copyright 2017 The Bazel Authors. All rights reserved. | ||
# | ||
# 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. | ||
|
||
import unittest | ||
|
||
|
||
# The test is the build itself, which should not work if extras are missing. | ||
class ExtrasTest(unittest.TestCase): | ||
def test_nothing(self): | ||
pass | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
google-cloud-language==0.27.0 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright 2017 The Bazel Authors. All rights reserved. | ||
# | ||
# 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. | ||
|
||
import pip | ||
import unittest | ||
|
||
|
||
class VersionTest(unittest.TestCase): | ||
|
||
def test_version(self): | ||
self.assertEqual(pip.__version__, '9.0.1') | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ | |
import json | ||
import os | ||
import pkgutil | ||
import pkg_resources | ||
import re | ||
import shutil | ||
import sys | ||
|
@@ -78,36 +79,7 @@ def pip_main(argv): | |
argv = ["--disable-pip-version-check", "--cert", cert_path] + argv | ||
return pip.main(argv) | ||
|
||
|
||
# TODO(mattmoor): We can't easily depend on other libraries when | ||
# being invoked as a raw .py file. Once bundled, we should be able | ||
# to remove this fallback on a stub implementation of Wheel. | ||
try: | ||
from rules_python.whl import Wheel | ||
except: | ||
class Wheel(object): | ||
|
||
def __init__(self, path): | ||
self._path = path | ||
|
||
def basename(self): | ||
return os.path.basename(self._path) | ||
|
||
def distribution(self): | ||
# See https://www.python.org/dev/peps/pep-0427/#file-name-convention | ||
parts = self.basename().split('-') | ||
return parts[0] | ||
|
||
def version(self): | ||
# See https://www.python.org/dev/peps/pep-0427/#file-name-convention | ||
parts = self.basename().split('-') | ||
return parts[1] | ||
|
||
def repository_name(self): | ||
# Returns the canonical name of the Bazel repository for this package. | ||
canonical = 'pypi__{}_{}'.format(self.distribution(), self.version()) | ||
# Escape any illegal characters with underscore. | ||
return re.sub('[-.]', '_', canonical) | ||
from rules_python.whl import Wheel | ||
|
||
parser = argparse.ArgumentParser( | ||
description='Import Python dependencies into Bazel.') | ||
|
@@ -124,6 +96,59 @@ def repository_name(self): | |
parser.add_argument('--directory', action='store', | ||
help=('The directory into which to put .whl files.')) | ||
|
||
def determine_possible_extras(whls): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you document the argument and return value? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this definitely needed a docstring. |
||
"""Determines the list of possible "extras" for each .whl | ||
|
||
The possibility of an extra is determined by looking at its | ||
additional requirements, and determinine whether they are | ||
satisfied by the complete list of available wheels. | ||
|
||
Args: | ||
whls: a list of Wheel objects | ||
|
||
Returns: | ||
a dict that is keyed by the Wheel objects in whls, and whose | ||
values are lists of possible extras. | ||
""" | ||
whl_map = { | ||
whl.distribution(): whl | ||
for whl in whls | ||
} | ||
|
||
# TODO(mattmoor): Consider memoizing if this recursion ever becomes | ||
# expensive enough to warrant it. | ||
def is_possible(distro, extra): | ||
distro = distro.replace("-", "_") | ||
# If we don't have the .whl at all, then this isn't possible. | ||
if distro not in whl_map: | ||
return False | ||
whl = whl_map[distro] | ||
# If we have the .whl, and we don't need anything extra then | ||
# we can satisfy this dependency. | ||
if not extra: | ||
return True | ||
# If we do need something extra, then check the extra's | ||
# dependencies to make sure they are fully satisfied. | ||
for extra_dep in whl.dependencies(extra=extra): | ||
req = pkg_resources.Requirement.parse(extra_dep) | ||
# Check that the dep and any extras are all possible. | ||
if not is_possible(req.project_name, None): | ||
return False | ||
for e in req.extras: | ||
if not is_possible(req.project_name, e): | ||
return False | ||
# If all of the dependencies of the extra are satisfiable then | ||
# it is possible to construct this dependency. | ||
return True | ||
|
||
return { | ||
whl: [ | ||
extra | ||
for extra in whl.extras() | ||
if is_possible(whl.distribution(), extra) | ||
] | ||
for whl in whls | ||
} | ||
|
||
def main(): | ||
args = parser.parse_args() | ||
|
@@ -140,6 +165,9 @@ def list_whls(): | |
if fname.endswith('.whl'): | ||
yield os.path.join(root, fname) | ||
|
||
whls = [Wheel(path) for path in list_whls()] | ||
possible_extras = determine_possible_extras(whls) | ||
|
||
def whl_library(wheel): | ||
# Indentation here matters. whl_library must be within the scope | ||
# of the function below. We also avoid reimporting an existing WHL. | ||
|
@@ -149,10 +177,25 @@ def whl_library(wheel): | |
name = "{repo_name}", | ||
whl = "@{name}//:{path}", | ||
requirements = "@{name}//:requirements.bzl", | ||
extras = [{extras}] | ||
)""".format(name=args.name, repo_name=wheel.repository_name(), | ||
path=wheel.basename()) | ||
|
||
whls = [Wheel(path) for path in list_whls()] | ||
path=wheel.basename(), | ||
extras=','.join([ | ||
'"%s"' % extra | ||
for extra in possible_extras.get(wheel, []) | ||
])) | ||
|
||
whl_targets = ','.join([ | ||
','.join([ | ||
'"%s": "@%s//:pkg"' % (whl.distribution().lower(), whl.repository_name()) | ||
] + [ | ||
# For every extra that is possible from this requirements.txt | ||
'"%s[%s]": "@%s//:%s"' % (whl.distribution().lower(), extra.lower(), | ||
whl.repository_name(), extra) | ||
for extra in possible_extras.get(whl, []) | ||
]) | ||
for whl in whls | ||
]) | ||
|
||
with open(args.output, 'w') as f: | ||
f.write("""\ | ||
|
@@ -178,10 +221,7 @@ def requirement(name): | |
return _requirements[name_key] | ||
""".format(input=args.input, | ||
whl_libraries='\n'.join(map(whl_library, whls)) if whls else "pass", | ||
mappings=','.join([ | ||
'"%s": "@%s//:pkg"' % (wheel.distribution().lower(), wheel.repository_name()) | ||
for wheel in whls | ||
]))) | ||
mappings=whl_targets)) | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI the 0.27.0, 0.28.x, and 0.29 releases all had wide-ranging changes to deps, and various problems with deps, unrelated to the issue at hand.