-
Notifications
You must be signed in to change notification settings - Fork 989
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
Add more meaninful error when parsing conanfile reference (closes #3204) #3410
Changes from 10 commits
3c3b6e8
161e1f2
f3d6f33
8133446
9f48b5d
c933ec0
46df758
d16c6da
62f771e
7dc4321
672b460
98ad177
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from collections import namedtuple | ||
import re | ||
from six import string_types | ||
from conans.errors import ConanException, InvalidNameException | ||
from conans.model.version import Version | ||
|
||
|
@@ -8,37 +9,44 @@ class ConanName(object): | |
_max_chars = 50 | ||
_min_chars = 2 | ||
_validation_pattern = re.compile("^[a-zA-Z0-9_][a-zA-Z0-9_\+\.-]{%s,%s}$" | ||
% (_min_chars - 1, _max_chars)) | ||
% (_min_chars - 1, _max_chars - 1)) | ||
|
||
@staticmethod | ||
def invalid_name_message(name): | ||
if len(name) > ConanName._max_chars: | ||
message = ("'%s' is too long. Valid names must contain at most %s characters." | ||
% (name, ConanName._max_chars)) | ||
elif len(name) < ConanName._min_chars: | ||
message = ("'%s' is too short. Valid names must contain at least %s characters." | ||
% (name, ConanName._min_chars)) | ||
def invalid_name_message(value, message=None): | ||
message = message or "'{value}' {reason}" | ||
if len(value) > ConanName._max_chars: | ||
reason = "is too long. Valid names must contain at most %s characters."\ | ||
% ConanName._max_chars | ||
elif len(value) < ConanName._min_chars: | ||
reason = "is too short. Valid names must contain at least %s characters."\ | ||
% ConanName._min_chars | ||
else: | ||
message = ("'%s' is an invalid name. Valid names MUST begin with a " | ||
"letter or number, have between %s-%s chars, including " | ||
"letters, numbers, underscore, dot and dash" | ||
% (name, ConanName._min_chars, ConanName._max_chars)) | ||
raise InvalidNameException(message) | ||
reason = ("is an invalid name. Valid names MUST begin with a " | ||
"letter, number or underscore, have between %s-%s chars, including " | ||
"letters, numbers, underscore, dot and dash" | ||
% (ConanName._min_chars, ConanName._max_chars)) | ||
raise InvalidNameException(message.format(value=value, reason=reason, | ||
type=type(value).__name__)) | ||
|
||
@staticmethod | ||
def validate_user(username): | ||
if ConanName._validation_pattern.match(username) is None: | ||
ConanName.invalid_name_message(username) | ||
def validate_string(value, message=None): | ||
"""Check for string""" | ||
if not isinstance(value, string_types): | ||
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. I don't like this checking for string, too defensive. All the fields of ConanFileReference are strings, by definition. 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. This issue started because we want to provide a more meaninful message for a |
||
message = message or "'{value}' (type {type}) {reason}" | ||
raise InvalidNameException(message.format(value=value, reason="is not a string", | ||
type=type(value).__name__)) | ||
|
||
@staticmethod | ||
def validate_name(name, version=False): | ||
def validate_name(name, version=False, message=None): | ||
"""Check for name compliance with pattern rules""" | ||
ConanName.validate_string(name, message=message) | ||
if name == "*": | ||
return | ||
if ConanName._validation_pattern.match(name) is None: | ||
if version and name.startswith("[") and name.endswith("]"): | ||
# TODO: Check value between brackets | ||
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. Leave it as TODO or check version ranges according to semver as documented (https://docs.conan.io/en/latest/mastering/version_ranges.html)? 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. Could be done in a different PR, not urgent, leave it. |
||
return | ||
ConanName.invalid_name_message(name) | ||
ConanName.invalid_name_message(name, message=message) | ||
|
||
|
||
class ConanFileReference(namedtuple("ConanFileReference", "name version user channel")): | ||
|
@@ -52,16 +60,20 @@ class ConanFileReference(namedtuple("ConanFileReference", "name version user cha | |
def __new__(cls, name, version, user, channel, revision=None): | ||
"""Simple name creation. | ||
@param name: string containing the desired name | ||
@param validate: checks for valid complex name. default True | ||
@param version: string containing the desired version | ||
@param user: string containing the user name | ||
@param channel: string containing the user channel | ||
@param revision: string containing the revision (optional) | ||
""" | ||
ConanName.validate_name(name) | ||
ConanName.validate_name(version, True) | ||
ConanName.validate_name(user) | ||
ConanName.validate_name(channel) | ||
message = "Value provided for {item}, '{{value}}' (type {{type}}), {{reason}}" | ||
ConanName.validate_name(name, message=message.format(item="package name")) | ||
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. Do not format every argument (this operation might be done lots of times), for every new ConanFileReference you are formating 4 strings. I know it seems little, but we need to try to keep performance and running time low. 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. Ok, then I'll go for a different approach |
||
ConanName.validate_name(version, True, message=message.format(item="package version")) | ||
ConanName.validate_name(user, message=message.format(item="package user name")) | ||
ConanName.validate_name(channel, message=message.format(item="package user")) | ||
version = Version(version) | ||
obj = super(cls, ConanFileReference).__new__(cls, name, version, user, channel) | ||
if revision: | ||
ConanName.validate_name(revision) | ||
ConanName.validate_name(revision, message=message.format(item="package revision")) | ||
obj.revision = revision | ||
return obj | ||
|
||
|
@@ -123,7 +135,8 @@ def __new__(cls, conan, package_id): | |
revision = None | ||
if "#" in package_id: | ||
package_id, revision = package_id.rsplit("#", 1) | ||
ConanName.validate_name(revision) | ||
message = "Value provided for package revision, '{value}' (type {type}) {reason}" | ||
ConanName.validate_name(revision, message=message) | ||
obj = super(cls, PackageReference).__new__(cls, conan, package_id) | ||
obj.revision = revision | ||
return obj | ||
|
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.
This is breaking! Should we change
_max_chars = 51
too?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.
Could you add some test checking the length limit of the names (or add a new one checking the upper limit)?
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.
There are tests to check upper and lower limits here and here, maybe in order to be backwards compatible we can make
_max_chars = 51
(or greater) and be sure that it is checked and used in strings with this value.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.
I would say yes, we should raise it to 51