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

Git.to_conandata and from_conandata #15377

Merged
merged 9 commits into from
Jan 24, 2024
2 changes: 1 addition & 1 deletion conan/tools/files/conandata.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def trim_conandata(conanfile):
version = str(conanfile.version)
result = {}
for k, v in conandata.items():
if not isinstance(v, dict):
if k == "scm" or not isinstance(v, dict):
result[k] = v
continue # to allow user extra conandata, common to all versions
version_data = v.get(version)
Expand Down
11 changes: 10 additions & 1 deletion conan/tools/scm/git.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fnmatch
import os

from conan.tools.files import chdir
from conan.tools.files import chdir, update_conandata
from conan.errors import ConanException
from conans.model.conf import ConfDefinition
from conans.util.files import mkdir
Expand Down Expand Up @@ -237,3 +237,12 @@ def included_files(self):
files = self.run("ls-files --full-name --others --cached --exclude-standard")
files = files.splitlines()
return files

def coordinates_to_conandata(self):
scm_url, scm_commit = self.get_url_and_commit()
update_conandata(self._conanfile, {"scm": {"commit": scm_commit, "url": scm_url}})

def checkout_from_conandata_coordinates(self):
sources = self._conanfile.conan_data["scm"]
self.clone(url=sources["url"], target=".")
self.checkout(commit=sources["commit"])
42 changes: 37 additions & 5 deletions conans/test/functional/tools/scm/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ class TestGitBasicSCMFlow:
- export() stores it in conandata.yml
- source() recovers the info from conandata.yml and clones it
"""
conanfile = textwrap.dedent("""
conanfile_full = textwrap.dedent("""
import os
from conan import ConanFile
from conan.tools.scm import Git
Expand Down Expand Up @@ -513,10 +513,40 @@ def build(self):
self.output.info("MYCMAKE-BUILD: {}".format(load(self, cmake)))
self.output.info("MYFILE-BUILD: {}".format(load(self, file_h)))
""")
conanfile_scm = textwrap.dedent("""
import os
from conan import ConanFile
from conan.tools.scm import Git
from conan.tools.files import load, trim_conandata

def test_full_scm(self):
class Pkg(ConanFile):
name = "pkg"
version = "0.1"

def export(self):
Git(self).coordinates_to_conandata()
trim_conandata(self) # to test it does not affect

def layout(self):
self.folders.source = "."

def source(self):
Git(self).checkout_from_conandata_coordinates()
self.output.info("MYCMAKE: {}".format(load(self, "CMakeLists.txt")))
self.output.info("MYFILE: {}".format(load(self, "src/myfile.h")))

def build(self):
cmake = os.path.join(self.source_folder, "CMakeLists.txt")
file_h = os.path.join(self.source_folder, "src/myfile.h")
self.output.info("MYCMAKE-BUILD: {}".format(load(self, cmake)))
self.output.info("MYFILE-BUILD: {}".format(load(self, file_h)))
""")

@pytest.mark.parametrize("conanfile_scm", [False, True])
def test_full_scm(self, conanfile_scm):
conanfile = self.conanfile_scm if conanfile_scm else self.conanfile_full
folder = os.path.join(temp_folder(), "myrepo")
url, commit = create_local_git_repo(files={"conanfile.py": self.conanfile,
url, commit = create_local_git_repo(files={"conanfile.py": conanfile,
"src/myfile.h": "myheader!",
"CMakeLists.txt": "mycmake"}, folder=folder)

Expand All @@ -543,15 +573,17 @@ def test_full_scm(self):
assert "conanfile.py (pkg/0.1): MYCMAKE-BUILD: mycmake" in c.out
assert "conanfile.py (pkg/0.1): MYFILE-BUILD: myheader!" in c.out

def test_branch_flow(self):
@pytest.mark.parametrize("conanfile_scm", [False, True])
def test_branch_flow(self, conanfile_scm):
""" Testing that when a user creates a branch, and pushes a commit,
the package can still be built from sources, and get_url_and_commit() captures the
remote URL and not the local
"""
conanfile = self.conanfile_scm if conanfile_scm else self.conanfile_full
url = git_create_bare_repo()
c = TestClient(default_server_user=True)
c.run_command('git clone "{}" .'.format(url))
c.save({"conanfile.py": self.conanfile,
c.save({"conanfile.py": conanfile,
"src/myfile.h": "myheader!",
"CMakeLists.txt": "mycmake"})
c.run_command("git checkout -b mybranch")
Expand Down