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

Fix: handle corner cases related to SCM with local sources optimization #4249

Merged
merged 50 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
6a5d3f4
reorder imports
jgsogo Jan 4, 2019
3b812b6
tests for the bug
jgsogo Jan 4, 2019
18a7a22
share as much code as possible between all tests (be sure that we are…
jgsogo Jan 4, 2019
7bf233b
conanfile is in root folder
jgsogo Jan 4, 2019
843310c
reordered tests
jgsogo Jan 4, 2019
3e4cfc5
add tests with conanfile in subfolder
jgsogo Jan 4, 2019
1ed8340
fix tests when conanfile is in repo root
jgsogo Jan 4, 2019
100eb2c
fix local source method
jgsogo Jan 4, 2019
ca5b0d3
remove repeated tests
jgsogo Jan 8, 2019
7de4d29
remove comments
jgsogo Jan 8, 2019
4a29eb3
remove test
jgsogo Jan 8, 2019
1894a7a
tag tests
jgsogo Jan 8, 2019
febe546
normalize path before storing it in scm_folder
jgsogo Jan 8, 2019
7eafda4
clean URL (remove peg-revision from SVN), otherwise relpath between u…
jgsogo Jan 8, 2019
0dc41cf
normalice 'src', if it enters 'merge_directories' with a final dot it…
jgsogo Jan 8, 2019
e45d606
add function to clean url inside SCM class, it knows all the possible…
jgsogo Jan 8, 2019
91b2b7b
fix tests that were failing
jgsogo Jan 8, 2019
54e9a6d
add tests that should work for SVN using url='auto'
jgsogo Jan 8, 2019
1c25bdd
Merge remote-tracking branch 'conan/develop' into issue/4222-scm-mono…
jgsogo Jan 8, 2019
8487db9
remove dupe test
jgsogo Jan 8, 2019
f763903
if we use 'scm.url=['auto']' we need a repository here
jgsogo Jan 8, 2019
5148671
we need something that resembles an url/file/...
jgsogo Jan 8, 2019
b25fe45
inherit from 'object', compatibility issues
jgsogo Jan 8, 2019
1db293e
if not local repo, then there will be no url
jgsogo Jan 8, 2019
84e97b7
order lists before comparing them
jgsogo Jan 8, 2019
c2ec7c1
use forward slashes in command line (single back-slash will be escaped)
jgsogo Jan 8, 2019
451253c
replace slashes (test failing in windows)
jgsogo Jan 8, 2019
c8f976a
forward slashes (failing tests in Windwos)
jgsogo Jan 8, 2019
0ec7c81
forward slashes
jgsogo Jan 9, 2019
48f7f22
forward slashes (failing in Windows)
jgsogo Jan 9, 2019
e2831e1
add more workflows to test suite
jgsogo Jan 9, 2019
576d30d
add unittests for the source and export functions related to SCM
jgsogo Jan 15, 2019
892a597
forward slashes (win)
jgsogo Jan 16, 2019
d676791
Merge remote-tracking branch 'conan/develop' into issue/4222-scm-mono…
jgsogo Jan 17, 2019
33d0c84
fix argument name changed
jgsogo Jan 21, 2019
560d5d5
classmethod to static
jgsogo Jan 21, 2019
5e7b955
move unittest to proper place
jgsogo Jan 21, 2019
c451b37
add function to SCM to handle the computation of the local sources path
jgsogo Jan 21, 2019
8855cc9
add docs
jgsogo Jan 21, 2019
31121a2
it doesn't breaks, and the scm keeps its value
jgsogo Jan 28, 2019
d500375
remove FIXME
jgsogo Jan 28, 2019
914d9a2
add tests without repo and without origin
jgsogo Jan 28, 2019
752ee6b
same for SVN
jgsogo Jan 28, 2019
31dcb84
fix some unittests that now requires an origin to work
jgsogo Jan 28, 2019
f7cf4e7
we need a remote to resolve the 'auto' (although it is only for revis…
jgsogo Jan 28, 2019
40834fc
do not check origin if url is defined
jgsogo Jan 29, 2019
9c91fee
if repo is Git, then local_source_folder should always equal to repo …
jgsogo Jan 29, 2019
7cfe96b
avoid calling twice the function
jgsogo Jan 29, 2019
ec55353
no need for valid URL if git
jgsogo Jan 29, 2019
33734c4
typo
jgsogo Jan 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions conans/client/cmd/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@ def _capture_export_scm_data(conanfile, conanfile_dir, destination_folder, outpu
captured_revision = scm_data.capture_revision

scm = SCM(scm_data, conanfile_dir, output)
if scm_data.capture_origin or scm_data.capture_revision:
# Generate the scm_folder.txt file pointing to the src_path
src_path = scm.get_repo_root()
save(scm_src_file, src_path.replace("\\", "/"))
captured = scm_data.capture_origin or scm_data.capture_revision

if scm_data.url == "auto":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check with a test of export+upload, without having a remote repo origin, and it should fail.

origin = scm.get_qualified_remote_url(remove_credentials=True)
Expand All @@ -96,6 +93,12 @@ def _capture_export_scm_data(conanfile, conanfile_dir, destination_folder, outpu

_replace_scm_data_in_conanfile(os.path.join(destination_folder, "conanfile.py"), scm_data)

if captured:
# Generate the scm_folder.txt file pointing to the src_path
src_path = scm.get_local_path_to_url(scm_data.url)
if src_path:
save(scm_src_file, os.path.normpath(src_path).replace("\\", "/"))

return scm_data, captured_revision


Expand Down
21 changes: 16 additions & 5 deletions conans/client/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def complete_recipe_sources(remote_manager, cache, conanfile, ref):


def merge_directories(src, dst, excluded=None, symlinks=True):
src = os.path.normpath(src)
dst = os.path.normpath(dst)
excluded = excluded or []
excluded = [os.path.normpath(entry) for entry in excluded]
Expand Down Expand Up @@ -192,20 +193,30 @@ def _run_scm(conanfile, src_folder, local_sources_path, output, cache):
dest_dir = os.path.normpath(os.path.join(src_folder, scm_data.subfolder))
if cache:
# When in cache, capturing the sources from user space is done only if exists
captured = local_sources_path and os.path.exists(local_sources_path)
if not local_sources_path or not os.path.exists(local_sources_path):
local_sources_path = None
else:
# In user space, if revision="auto", then copy
captured = scm_data.capture_origin or scm_data.capture_revision
local_sources_path = local_sources_path if captured and conanfile.develop else None

if local_sources_path:
if scm_data.capture_origin or scm_data.capture_revision: # FIXME: or clause?
scm = SCM(scm_data, local_sources_path, output)
scm_url = scm_data.url if scm_data.url != "auto" else \
scm.get_qualified_remote_url(remove_credentials=True)

src_path = scm.get_local_path_to_url(url=scm_url)
if src_path:
local_sources_path = src_path
else:
local_sources_path = None

if local_sources_path and conanfile.develop:
excluded = SCM(scm_data, local_sources_path, output).excluded_files
output.info("Getting sources from folder: %s" % local_sources_path)
merge_directories(local_sources_path, dest_dir, excluded=excluded)
else:
output.info("Getting sources from url: '%s'" % scm_data.url)
scm = SCM(scm_data, dest_dir, output)
scm.checkout()

if cache:
# This is a bit weird. Why after a SCM should we remove files. Maybe check conan 2.0
_clean_source_folder(dest_dir)
21 changes: 21 additions & 0 deletions conans/model/scm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os

from conans.client.tools.scm import Git, SVN
from conans.errors import ConanException
Expand Down Expand Up @@ -99,3 +100,23 @@ def get_qualified_remote_url(self, remove_credentials):

def is_local_repository(self):
return self.repo.is_local_repository()

@staticmethod
def clean_url(url):
_, last_chunk = url.rsplit('/', 1)
if '@' in last_chunk: # Remove peg_revision
url, peg_revision = url.rsplit('@', 1)
return url
return url

def get_local_path_to_url(self, url):
""" Compute the local path to the directory where the URL is pointing to (only make sense
for CVS where chunks of the repository can be checked out isolated). The argument
'url' should be contained inside the root url.
"""
src_root = self.get_repo_root()
url_root = SCM(self._data, src_root, self._output).get_remote_url(remove_credentials=True)
if url_root:
url = self.clean_url(url)
src_path = os.path.join(src_root, os.path.relpath(url, url_root))
return src_path
4 changes: 3 additions & 1 deletion conans/test/functional/command/source_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ class ScmtestConan(ConanFile):
"""
client = TestClient()
client.save({"conanfile.py": conanfile})
client.runner("git init .", cwd=client.current_folder)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? The test case was failing even if it wasn't a git repo. Maybe leave the test as it was, and if anything, adding a new one with a git repo too.

Copy link
Contributor Author

@jgsogo jgsogo Jan 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without creating the Git repository this test fails (because it cannot get the URL to the remote). It is related to the comment about the difficult to understand block. If I execute conditionally that block for Git, then this test (and many others) can be kept as before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Maybe an error test, if it is not a git repo, what is the error message. Who is launching it and at which step? Hint: should probably be on export time, not on "create" time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if:

  • URL is defined hardcoded with full url, not "auto"
  • revision=auto

client.run("source .")
self.assertEqual(["conanfile.py"], os.listdir(client.current_folder))
self.assertEqual(sorted(["conanfile.py", '.git']),
sorted(os.listdir(client.current_folder)))

def local_flow_patch_test(self):
# https://github.com/conan-io/conan/issues/2327
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def reuse_scm_test(self):

conanfile = """from conans import ConanFile
scm = {"type" : "git",
"url" : "somerepo",
"url" : "http://somerepo",
"revision" : "auto"}

class MyConanfileBase(ConanFile):
Expand All @@ -298,13 +298,13 @@ class MyConanfileBase(ConanFile):
client.run("get MyConanfileBase/1.1@lasote/testing")
# The global scm is left as-is
self.assertIn("""scm = {"type" : "git",
"url" : "somerepo",
"url" : "http://somerepo",
"revision" : "auto"}""", client.out)
# but the class one is replaced
self.assertNotIn("scm = scm", client.out)
self.assertIn(' scm = {"revision":', client.out)
self.assertIn('"type": "git",', client.out)
self.assertIn('"url": "somerepo"', client.out)
self.assertIn('"url": "http://somerepo"', client.out)

reuse = """from conans import python_requires
base = python_requires("MyConanfileBase/1.1@lasote/testing")
Expand All @@ -320,7 +320,7 @@ def _my_method(self):
self.assertNotIn("scm = base.scm", client.out)
self.assertIn('scm = {"revision":', client.out)
self.assertIn('"type": "git",', client.out)
self.assertIn('"url": "somerepo"', client.out)
self.assertIn('"url": "http://somerepo"', client.out)

def reuse_exports_test(self):
conanfile = """from conans import ConanFile
Expand Down
Loading