Repository: conan-io/conan

Issue:
conan create not deleting cached sources with scm capture
Repository with the `conanfile.py`, scm to auto:

In the local project:

`conan create . user/channel`
`>> Change CMakeLists.txt <<`
`conan create . user/channel`

**Result**: Conan create is keeping the local cache source folder, so the change in the CMakeLists.txt is not used.




Discussion:

Resolving patch:
diff --git a/conans/client/cmd/export.py b/conans/client/cmd/export.py
--- a/conans/client/cmd/export.py
+++ b/conans/client/cmd/export.py
@@ -9,11 +9,12 @@
 from conans.client.file_copier import FileCopier
 from conans.client.loader_parse import load_conanfile_class
 from conans.client.output import ScopedOutput
+from conans.client.source import get_scm_data
 from conans.errors import ConanException
 from conans.model.conan_file import create_exports, create_exports_sources
 from conans.model.manifest import FileTreeManifest
 from conans.model.ref import ConanFileReference
-from conans.model.scm import SCM, SCMData
+from conans.model.scm import SCM
 from conans.paths import CONAN_MANIFEST, CONANFILE
 from conans.util.files import save, rmdir, is_dirty, set_dirty, mkdir
 from conans.util.log import logger
@@ -104,13 +105,10 @@ def _capture_export_scm_data(conanfile, src_path, destination_folder, output, pa
     if os.path.exists(scm_src_file):
         os.unlink(scm_src_file)
 
-    try:
-        scm_data = SCMData(conanfile)
-    except ConanException:
+    scm_data = get_scm_data(conanfile)
+
+    if not scm_data or not (scm_data.capture_origin or scm_data.capture_revision):
         return
-    else:
-        if not (scm_data.capture_origin or scm_data.capture_revision):
-            return
 
     scm = SCM(scm_data, src_path)
 
diff --git a/conans/client/source.py b/conans/client/source.py
--- a/conans/client/source.py
+++ b/conans/client/source.py
@@ -74,6 +74,13 @@ def _clean_source_folder(folder):
             pass
 
 
+def get_scm_data(conanfile):
+    try:
+        return SCMData(conanfile)
+    except ConanException:
+        return None
+
+
 def config_source(export_folder, export_source_folder, local_sources_path, src_folder,
                   conanfile, output, force=False):
     """ creates src folder and retrieve, calling source() from conanfile
@@ -103,6 +110,9 @@ def remove_source(raise_error=True):
     elif conanfile.build_policy_always:
         output.warn("Detected build_policy 'always', trying to remove source folder")
         remove_source()
+    elif local_sources_path and os.path.exists(local_sources_path):
+        output.warn("Detected 'scm' auto in conanfile, trying to remove source folder")
+        remove_source()
 
     if not os.path.exists(src_folder):
         output.info('Configuring sources in %s' % src_folder)
@@ -116,11 +126,8 @@ def remove_source(raise_error=True):
                     conanfile.build_folder = None
                     conanfile.package_folder = None
 
-                    try:
-                        scm_data = SCMData(conanfile)
-                    except ConanException:
-                        pass
-                    else:
+                    scm_data = get_scm_data(conanfile)
+                    if scm_data:
                         dest_dir = os.path.normpath(os.path.join(src_folder, scm_data.subfolder))
                         captured = local_sources_path and os.path.exists(local_sources_path)
                         local_sources_path = local_sources_path if captured else None
@@ -158,11 +165,8 @@ def config_source_local(dest_dir, conanfile, conanfile_folder, output):
                 with get_env_context_manager(conanfile):
                     conanfile.build_folder = None
                     conanfile.package_folder = None
-                    try:
-                        scm_data = SCMData(conanfile)
-                    except ConanException:
-                        pass
-                    else:
+                    scm_data = get_scm_data(conanfile)
+                    if scm_data:
                         dest_dir = os.path.join(dest_dir, scm_data.subfolder)
                         capture = scm_data.capture_origin or scm_data.capture_revision
                         local_sources_path = conanfile_folder if capture else None


Test patch:
diff --git a/conans/test/functional/scm_test.py b/conans/test/functional/scm_test.py
--- a/conans/test/functional/scm_test.py
+++ b/conans/test/functional/scm_test.py
@@ -5,7 +5,7 @@
 
 from conans.client.tools.scm import Git
 from conans.model.ref import ConanFileReference, PackageReference
-from conans.model.scm import SCM, SCMData
+from conans.model.scm import SCMData
 from conans.test.utils.test_files import temp_folder
 from conans.test.utils.tools import TestClient, TestServer, create_local_git_repo
 from conans.util.files import load, rmdir
@@ -259,6 +259,37 @@ def test_install_checked_out(self):
         client2.run("install lib/0.1@lasote/channel --build")
         self.assertIn("My file is copied", client2.out)
 
+    def test_source_removed_in_local_cache(self):
+
+        conanfile = '''
+from conans import ConanFile, tools
+
+class ConanLib(ConanFile):
+    scm = {
+        "type": "git",
+        "url": "auto",
+        "revision": "auto",
+    }
+    
+    def build(self):
+        contents = tools.load("myfile")
+        self.output.warn("Contents: %s" % contents)
+        
+'''
+        path, commit = create_local_git_repo({"myfile": "contents", "conanfile.py": conanfile},
+                                             branch="my_release")
+        self.client.current_folder = path
+        self.client.runner('git remote add origin https://myrepo.com.git', cwd=path)
+        self._commit_contents()
+
+        self.client.run("create . lib/1.0@user/channel")
+        self.assertIn("Contents: contents", self.client.out)
+        self.client.save({"myfile": "Contents 2"})
+        self.client.run("create . lib/1.0@user/channel")
+        self.assertIn("Contents: Contents 2", self.client.out)
+        self.assertIn("Detected 'scm' auto in conanfile, trying to remove source folder",
+                      self.client.out)
+
     def test_submodule(self):
         subsubmodule, _ = create_local_git_repo({"subsubmodule": "contents"})
         submodule, _ = create_local_git_repo({"submodule": "contents"}, submodules=[subsubmodule])