Skip to content

Commit

Permalink
Recipe Layouts: Step 0 (#8243)
Browse files Browse the repository at this point in the history
* Minimum changes

* Fixed mock value install folder

* litle review changes

* Changed data structure

* Clean code
  • Loading branch information
lasote authored Jan 8, 2021
1 parent 989d7ef commit 223ab0f
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 2 deletions.
38 changes: 38 additions & 0 deletions conans/model/conan_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from conans.errors import ConanException, ConanInvalidConfiguration
from conans.model.build_info import DepsCppInfo
from conans.model.env_info import DepsEnvInfo
from conans.model.layout import Layout
from conans.model.options import Options, OptionsValues, PackageOptions
from conans.model.requires import Requirements
from conans.model.user_info import DepsUserInfo
Expand Down Expand Up @@ -132,6 +133,9 @@ class ConanFile(object):
provides = None
deprecated = None

# layout
layout = None

def __init__(self, output, runner, display_name="", user=None, channel=None):
# an output stream (writeln, info, warn error)
self.output = ScopedOutput(display_name, output)
Expand All @@ -144,6 +148,8 @@ def __init__(self, output, runner, display_name="", user=None, channel=None):
self.compatible_packages = []
self._conan_using_build_profile = False

self.layout = Layout()

def initialize(self, settings, env):
if isinstance(self.generators, str):
self.generators = [self.generators]
Expand Down Expand Up @@ -176,6 +182,38 @@ def initialize(self, settings, env):
if self.description is not None and not isinstance(self.description, six.string_types):
raise ConanException("Recipe 'description' must be a string.")

@property
def source_folder(self):
return self.layout.source_folder

@source_folder.setter
def source_folder(self, folder):
self.layout.set_base_source_folder(folder)

@property
def build_folder(self):
return self.layout.build_folder

@build_folder.setter
def build_folder(self, folder):
self.layout.set_base_build_folder(folder)

@property
def install_folder(self):
return self.layout.install_folder

@install_folder.setter
def install_folder(self, folder):
self.layout.set_base_install_folder(folder)

@property
def package_folder(self):
return self.layout.package_folder

@package_folder.setter
def package_folder(self, folder):
self.layout.set_base_package_folder(folder)

@property
def env(self):
"""Apply the self.deps_env_info into a copy of self._conan_env_values (will prioritize the
Expand Down
71 changes: 71 additions & 0 deletions conans/model/layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import os


class _LayoutEntry(object):

def __init__(self):
self.folder = ""


class Layout(object):
def __init__(self):

self._base_source_folder = None
self._base_build_folder = None
self._base_install_folder = None
self._base_package_folder = None

self.install = _LayoutEntry()
self.source = _LayoutEntry()
self.build = _LayoutEntry()
self.package = _LayoutEntry() # Where the artifacts are installed

def __repr__(self):
return str(self.__dict__)

@property
def source_folder(self):
if self._base_source_folder is None:
return None
if not self.source.folder:
return self._base_source_folder

return os.path.join(self._base_source_folder, self.source.folder)

def set_base_source_folder(self, folder):
self._base_source_folder = folder

@property
def build_folder(self):
if self._base_build_folder is None:
return None
if not self.build.folder:
return self._base_build_folder
return os.path.join(self._base_build_folder, self.build.folder)

def set_base_build_folder(self, folder):
self._base_build_folder = folder

@property
def install_folder(self):
if self._base_install_folder is None:
return self.build_folder # If None, default to build_folder (review)
if not self.install.folder:
return self._base_install_folder

return os.path.join(self._base_install_folder, self.install.folder)

def set_base_install_folder(self, folder):
self._base_install_folder = folder

@property
def package_folder(self):
if self._base_package_folder is None:
return None
if not self.package.folder:
return self._base_package_folder

return os.path.join(self._base_package_folder, self.package.folder)

def set_base_package_folder(self, folder):
self._base_package_folder = folder
9 changes: 7 additions & 2 deletions conans/test/utils/mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from conans.client.output import ConanOutput
from conans.client.userio import UserIO
from conans.model.env_info import DepsEnvInfo, EnvInfo, EnvValues
from conans.model.layout import Layout
from conans.model.options import PackageOptions
from conans.model.user_info import DepsUserInfo

Expand Down Expand Up @@ -123,6 +124,7 @@ def deps(self):
class MockConanfile(ConanFile):

def __init__(self, settings, options=None, runner=None):
self.layout = Layout()
self.deps_cpp_info = MockDepsCppInfo()
self.settings = settings
self.runner = runner
Expand All @@ -137,6 +139,7 @@ def __init__(self, settings, options=None, runner=None):

self.package_folder = None


def run(self, *args, **kwargs):
if self.runner:
kwargs["output"] = None
Expand All @@ -149,7 +152,6 @@ def __init__(self, shared=None, options=None, options_values=None):
options = options or ""
self.command = None
self.path = None
self.source_folder = self.build_folder = "."
self.settings = None
self.options = Options(PackageOptions.loads(options))
if options_values:
Expand All @@ -159,7 +161,6 @@ def __init__(self, shared=None, options=None, options_values=None):
self.deps_cpp_info.sysroot = "/path/to/sysroot"
self.output = TestBufferConanOutput()
self.in_local_cache = False
self.install_folder = "myinstallfolder"
if shared is not None:
self.options = namedtuple("options", "shared")(shared)
self.should_configure = True
Expand All @@ -172,6 +173,10 @@ def __init__(self, shared=None, options=None, options_values=None):
self.env_info = EnvInfo()
self.deps_user_info = DepsUserInfo()
self._conan_env_values = EnvValues()
self.layout = Layout()
self.layout.set_base_source_folder(".")
self.layout.set_base_build_folder(".")
self.layout.set_base_install_folder("myinstallfolder")

def run(self, command, win_bash=False, subsystem=None):
assert win_bash is False
Expand Down

0 comments on commit 223ab0f

Please sign in to comment.