Skip to content

Commit

Permalink
[develop2] Implement forcing of download sources (#13003)
Browse files Browse the repository at this point in the history
* [develop2] install sources

* add test

* Update conan/api/subapi/install.py

Co-authored-by: Rubén Rincón Blanco <git@rinconblanco.es>

---------

Co-authored-by: Rubén Rincón Blanco <git@rinconblanco.es>
  • Loading branch information
memsharded and AbrilRBS authored Jan 31, 2023
1 parent 7c7e1c3 commit ad7fd95
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 9 deletions.
14 changes: 12 additions & 2 deletions conan/api/subapi/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,23 @@ def install_binaries(self, deps_graph, remotes=None):
installer.install(deps_graph, remotes)

@api_method
def install_system_requires(self, graph):
def install_system_requires(self, graph, only_info=False):
""" Install binaries for dependency graph
:param only_info: Only allow reporting and checking, but never install
:param graph: Dependency graph to intall packages for
"""
app = ConanApp(self.conan_api.cache_folder)
installer = BinaryInstaller(app)
installer.install_system_requires(graph)
installer.install_system_requires(graph, only_info)

@api_method
def install_sources(self, graph, remotes):
""" Install sources for dependency graph
:param graph: Dependency graph to install packages for
"""
app = ConanApp(self.conan_api.cache_folder)
installer = BinaryInstaller(app)
installer.install_sources(graph, remotes)

# TODO: Look for a better name
def install_consumer(self, deps_graph, generators=None, source_folder=None, output_folder=None,
Expand Down
7 changes: 3 additions & 4 deletions conan/cli/commands/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,9 @@ def graph_info(conan_api, parser, subparser, *args):
conan_api.graph.analyze_binaries(deps_graph, args.build, remotes=remotes, update=args.update,
lockfile=lockfile)
print_graph_packages(deps_graph)
# TODO: Refactor magic strings and use _SystemPackageManagerTool.mode_xxx ones
if profile_host.conf.get("tools.system.package_manager:mode") \
in ("check", "report", "report-installed"):
conan_api.install.install_system_requires(deps_graph)

conan_api.install.install_system_requires(deps_graph, only_info=True)
conan_api.install.install_sources(deps_graph, remotes=remotes)

lockfile = conan_api.lockfile.update_lockfile(lockfile, deps_graph, args.lockfile_packages,
clean=args.lockfile_clean)
Expand Down
25 changes: 22 additions & 3 deletions conans/client/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ def __init__(self, app):
self._hook_manager = app.hook_manager

def _install_source(self, node, remotes):
if node.binary != BINARY_BUILD:
conanfile = node.conanfile
download_source = conanfile.conf.get("tools.build:download_source", check_type=bool)

if not download_source and node.binary != BINARY_BUILD:
return

conanfile = node.conanfile
Expand All @@ -192,27 +195,43 @@ def _install_source(self, node, remotes):
config_source(export_source_folder, conanfile, self._hook_manager)

@staticmethod
def install_system_requires(graph):
def install_system_requires(graph, only_info=False):
install_graph = InstallGraph(graph)
install_order = install_graph.install_order()

for level in install_order:
for install_reference in level:
for package in install_reference.packages.values():
if package.binary == BINARY_SKIP:
if not only_info and package.binary == BINARY_SKIP:
continue
conanfile = package.nodes[0].conanfile
# TODO: Refactor magic strings and use _SystemPackageManagerTool.mode_xxx ones
mode = conanfile.conf.get("tools.system.package_manager:mode")
if only_info and mode is None:
continue
if hasattr(conanfile, "system_requirements"):
with conanfile_exception_formatter(conanfile, "system_requirements"):
conanfile.system_requirements()
for n in package.nodes:
n.conanfile.system_requires = conanfile.system_requires

conanfile = graph.root.conanfile
mode = conanfile.conf.get("tools.system.package_manager:mode")
if only_info and mode is None:
return
if hasattr(conanfile, "system_requirements"):
with conanfile_exception_formatter(conanfile, "system_requirements"):
conanfile.system_requirements()

def install_sources(self, graph, remotes):
install_graph = InstallGraph(graph)
install_order = install_graph.install_order()

for level in install_order:
for install_reference in level:
for package in install_reference.packages.values():
self._install_source(package.nodes[0], remotes)

def install(self, deps_graph, remotes):
assert not deps_graph.error, "This graph cannot be installed: {}".format(deps_graph)

Expand Down
1 change: 1 addition & 0 deletions conans/model/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
# Tools
"tools.android:ndk_path": "Argument for the CMAKE_ANDROID_NDK",
"tools.build:skip_test": "Do not execute CMake.test() and Meson.test() when enabled",
"tools.build:download_source": "Force download of sources for every package",
"tools.build:jobs": "Default compile jobs number -jX Ninja, Make, /MP VS (default: max CPUs)",
"tools.build:sysroot": "Pass the --sysroot=<tools.build:sysroot> flag if available. (None by default)",
"tools.build.cross_building:can_run": "Bool value that indicates whether is possible to run a non-native "
Expand Down
42 changes: 42 additions & 0 deletions conans/test/integration/command/test_forced_download_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import textwrap

import pytest

from conans.test.utils.tools import TestClient


@pytest.fixture()
def client():
c = TestClient(default_server_user=True)
dep = textwrap.dedent("""
from conan import ConanFile
class Dep(ConanFile):
name = "dep"
version = "0.1"
def source(self):
self.output.info("RUNNING SOURCE!!")
""")

c.save({"dep/conanfile.py": dep})
c.run("create dep")
c.run("upload * -c -r=default")
c.run("remove * -c")
return c


def test_install(client):
client.run("install --requires=dep/0.1")
assert "RUNNING SOURCE" not in client.out
client.run("install --requires=dep/0.1 -c tools.build:download_source=True")
assert "RUNNING SOURCE" in client.out
client.run("install --requires=dep/0.1 -c tools.build:download_source=True")
assert "RUNNING SOURCE" not in client.out


def test_info(client):
client.run("graph info --requires=dep/0.1")
assert "RUNNING SOURCE" not in client.out
client.run("graph info --requires=dep/0.1 -c tools.build:download_source=True")
assert "RUNNING SOURCE" in client.out
client.run("graph info --requires=dep/0.1 -c tools.build:download_source=True")
assert "RUNNING SOURCE" not in client.out

0 comments on commit ad7fd95

Please sign in to comment.