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

[rfc] When should we use validate() and what goes there #4261

Open
prince-chrismc opened this issue Jan 14, 2021 · 7 comments
Open

[rfc] When should we use validate() and what goes there #4261

prince-chrismc opened this issue Jan 14, 2021 · 7 comments

Comments

@prince-chrismc
Copy link
Contributor

prince-chrismc commented Jan 14, 2021

This is something I've seen a lot of recently. We need a consensus and what is the correct procedure.

In the last 24hrs, the usage of this new method, seems to have unearthed a bug where hooks are failing on projects which do no support the platform. #4193


If a thread could be opened to discuss what should go to validate() and what should stay in configure(), it would be nice, because I don't think that moving such verifications in validate() is a good thing (why should we allow requirements() to be called if we already know that it doesn't make sense?).

Originally posted by @SpaceIm in #4133 (comment)

I had very strange bugs on CCI when using validate(self) the last days:
eg #4181 (comment) or #4182 (comment)
so I'm not very inclined to use it until we understand what happened. Can we wait to introduce it ?

Originally posted by @ericLemanissier in #4254 (comment)

@ericLemanissier ericLemanissier mentioned this issue Jan 15, 2021
4 tasks
@uilianries
Copy link
Member

Hooks can be fixed to accept validate() method, no problem.

As any other feature, validate() was introduced as experimental, so we can change it without breaking anything on a stable version.

CCI considers the latest Conan version available, so there is no problem using validate().

Anyway, we have to fix it, I'm going to send a fix for Hooks.

@SpaceIm
Copy link
Contributor

SpaceIm commented Jan 15, 2021

I would prefer to keep early checks (raising ConanInvalidConfiguration) in configure() , basically all checks NOT based on:

  • dependencies final options values
  • dependencies final versions

It avoids to launch unecessary dependency graph resolution under a recipe, and side effects.

@ericLemanissier
Copy link
Contributor

ericLemanissier commented Jan 15, 2021

and version of dependencies are basically not available from validate(self) IIUC (cf conan-io/conan#8053 (review)), so that leaves only dependencies options values

@uilianries
Copy link
Member

configure() still generates a invalid package ID, that's why we are moving to validate().

There is a good explanation about the decision on here: https://blog.conan.io/2020/12/14/New-conan-release-1-32.html

@prince-chrismc
Copy link
Contributor Author

Correct me if I am wrong but according to the blog we should always throw ConanInvalidConfiguration from validate()?

I guess it's my inexperience but I do not fully understand the motivation and how the package_id is currently being affect when we throw from configure().

I see two distinct uses cases...

challenges surrounding the definition, detection, and handling invalid or impossible configurations. Historically, the general recommendation has been to handle these cases by raising ConanInvalidConfiguration errors during the configure() method

there are some checks which simply cannot be run there because of the state of the dependency graph. [...] so we’ve now added [...] a new method to Conanfile named validate() method which executes after the graph has been fully evaluated solving the previous problems

Why is the recommendation to always throw ConanInvalidConfiguration from validate()?


The difficulty lines in when we need to throw invalid configuration. Currently in CCI there are a few different scenarios:

❓ Most of which do not require the dependency graph. Why is it not longer advisable to throw these in the configure method?


A mostly complete list of when we are throwing

self.settings

  1. Platform support
    if self.settings.os != "Windows":
    raise ConanInvalidConfiguration("ags doesn't support OS: {}.".format(self.settings.os))
  2. Compiler support
    if self.settings.compiler == "apple-clang":
    raise ConanInvalidConfiguration("apple-clang not supported")
  3. Cppstd Requirements
    not any([str(self.settings.compiler.cppstd) == std for std in ["17", "20", "gnu17", "gnu20"]]):
    raise ConanInvalidConfiguration("nanoRange requires at least c++17")

self.options

  1. Local Recipe Options
    if (self.options.panic_handler == 'backtrace' and
    not self.options.backtrace):
    raise ConanInvalidConfiguration(
  2. Missing deps
    elif self.options.dtls_backend == "gnutls":
    raise ConanInvalidConfiguration("gnu tls not available yet")
  3. Dependency Option
    (self.options["boost"].header_only or self.options["boost"].without_system):
    raise ConanInvalidConfiguration("libtorrent requires boost with system, which is non-header only in boost < 1.69.0")

self.deps_cpp_info

  1. Version Requirements
    elif tools.Version(self.version) <= "2.0.1" and "boost" in self.deps_cpp_info.deps and tools.Version(self.deps_cpp_info["boost"].version) >= "1.74.0":
    raise ConanInvalidConfiguration("simple-websocket-server versions <=2.0.1 require boost < 1.74.0")

@madebr
Copy link
Contributor

madebr commented Jan 22, 2021

@uilianries

There is a good explanation about the decision on here: https://blog.conan.io/2020/12/14/New-conan-release-1-32.html

BINARY_INVALID and INVALID are currently not well documented.

Where should the following checks be placed?

  1. Invalid os:
    if self.settings.os == "Windows":
        raise ConanInvalidConfiguration("No Windows")
  2. Invalid option:
    if self.settings.os == "Linux" and self.options.option_a:
        raise ConanInvalidConfiguration("Invalid option a")
  3. Invalid option of dependency:
    if self.options.option_a == "abc" and not self.options["dep"].option_a:
       raise ConanInvalidConfiguration("dep:option_a has invalid valiue")

Imho, the cleares place to put them are:

  1. Invalid os: configure (config_options would also be a valid place)
  2. Invalid option: configure (fail early)
  3. Invalid option of dependency: validate. No discussion about this one.

Where would you put these ones?
Did I mess other (extreme) cases?

@SSE4
Copy link
Contributor

SSE4 commented Jan 22, 2021

Invalid option: configure (fail early)

there are different cases for invalid options, e.g.:

  • option conflicts with another option
  • option is invalid for the given settings
  • option is not implemented (e.g. missing dep in conan center)

but, perhaps, they all are equivalent in terms of the implementation. in any case, the option could be overridden, e.g.:

  • passing option value in command line
  • passing option value in profile
  • overriding in consumer(s)

I'd expect validate to always get the final value of the option always

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants