Repository: conan-io/conan

Issue:
[SCM] [SVN] Parse SVN info independent of SVN client version
- [x] I've read the [CONTRIBUTING guide](https://raw.githubusercontent.com/conan-io/conan/develop/.github/CONTRIBUTING.md).
- [x] I've specified the Conan version, operating system version and any tool that can be relevant.
- [x] I've explained the steps to reproduce the error or the motivation/use case of the question/suggestion.

Conan version: 1.9.0
Python 3.6.5
OS: Ubuntu 14.04.5 LTS
SVN: 1.8.8 (r1568071)

When we use the new SCM Feature for SVN we get the following error on one of our build slaves:
```
Exporting package recipe
svn: invalid option: --show-item
Type 'svn help' for usage.
Traceback (most recent call last):
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/command.py", line 1428, in run
    method(args[0][1:])
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/command.py", line 299, in create
    test_build_folder=args.test_build_folder)
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/conan_api.py", line 88, in wrapper
    return f(*args, **kwargs)
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/conan_api.py", line 361, in create
    self._client_cache, self._hook_manager, self._registry)
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/cmd/export.py", line 59, in cmd_export
    keep_source)
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/cmd/export.py", line 157, in _export_conanfile
    output, paths, conan_ref)
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/cmd/export.py", line 79, in _capture_export_scm_data
    origin = scm.get_qualified_remote_url()
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/model/scm.py", line 84, in get_qualified_remote_url
    return self.repo.get_qualified_remote_url()
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/tools/scm.py", line 263, in get_qualified_remote_url
    url = self.get_remote_url()
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/tools/scm.py", line 259, in get_remote_url
    return self._show_item('url')
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/tools/scm.py", line 209, in _show_item
    value = self.run("info --show-item {item} \"{target}\"".format(item=item, target=target))
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/tools/scm.py", line 205, in run
    return super(SVN, self).run(command="{} {}".format(command, extra_options))
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/tools/scm.py", line 39, in run
    return self._runner(command)
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/site-packages/conans/client/tools/scm.py", line 176, in runner_no_strip
    return decode_text(subprocess.check_output(command, shell=True))
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
  File "/home/blade4/jenkins/CWS/Tools/Python3/lib/python3.6/subprocess.py", line 418, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'svn info --show-item url "."  --no-auth-cache --non-interactive --trust-server-cert-failures=unknown-ca' returned non-zero exit status 1.

ERROR: Command 'svn info --show-item url "."  --no-auth-cache --non-interactive --trust-server-cert-failures=unknown-ca' returned non-zero exit status 1.
```

When we call `svn info --show-item url` from console we get the following error:
```
svn: invalid option: --show-item
```

Seems that our SVN client does not support this command.

Could you please have a look at this?

Thank You!


Discussion:
See #3737. I assumed this was fixed in 1.9.0

Edit: Just seen your SVN version. Much newer then mine :smile: Maybe the version logic is not quite right in the fix?
Hello @keithrob91,

thanks for your answer. You said 
> maybe the version logic is not quite right in the fix?

Is saw in your code that you use the `--xml` option for newer svn client versions.
Maybe you could use the xml option also for svn 1.8 clients. The xml option should have been available at least since svn 1.6, according to this site: http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.info.html
It wasn't me who implemented the feature, I just requested it.

I believe @jgsogo is the person most involved with the implementation.
@keithrob91 Sorry, I see that you had the same problem with SVN client 1.7

@jgsogo We patched `API_CHANGE_VERSION` in `scm.py` from 1.8 to 1.9 and it seems to work now on all of our build clients.

We testet it with:
* SVN client 1.8.8 (Ubuntu 14)
* SVN client 1.9.3 (Ubuntu 16)
* SVN client 1.8.19 (Windows 7)
* SVN client 1.9.5 (Windows 7)

Could you please verify this?
Hi, first of all, sorry for the inconvenience, we find very difficult to test Conan using every single version of all the externals tools that are being used. There are too many.

The `SVN.API_CHANGE_VERSION` is used for different functions in the cose (see [here](https://github.com/conan-io/conan/blob/d4fcadaaeee302f9dec0fc3bf44bdce0cfac744f/conans/client/tools/scm.py#L169)):

 * ``trust-server-cert-failures`` parameter:

```python
        if not self._verify_ssl:
            if self.version >= SVN.API_CHANGE_VERSION:
                extra_options += " --trust-server-cert-failures=unknown-ca"
            else:
                extra_options += " --trust-server-cert"
```

 * ``show-item``:

```python
        if self.version >= SVN.API_CHANGE_VERSION:
            value = self.run("info --show-item {item} \"{target}\"".format(item=item, target=target))
            return value.strip()
        else:
            output = self.run("info --xml \"{target}\"".format(target=target))
            ...
            # ...and not all versions have all parameters available
            raise ConanException("Retrieval of item '{}' not implemented for SVN<{}".format(
                item, SVN.API_CHANGE_VERSION))
```

 * to check if the working is pristine:

```python
    if self.version >= SVN.API_CHANGE_VERSION:
            output = self.run("status -u -r {} --xml".format(self.get_revision()))
    else:
        return False  # Older versions do not allow the `-r <revision>` argument.
```

So, as far as we know we should change the `API_CHANGE_VERSION` from `1.8` to `1.9` because:
 * @keithrob91 (with SVN 1.7.14) won't be affected
 * @ahauan4 (with SVN 1.8.8, 1.9.3, 1.8.19, 1.9.5), can you confirm that these three points behave as expected with you plethora of SVN versions? I'll check it in the docs too, but a live confirmation is always worth.

Thanks a lot for your patience! 
Hello @jsogo,

> can you confirm that these three points behave as expected with you plethora of SVN versions?

Yes, we can
Hello @jsogo,

I have another question:
Since the is_pristine check isn't available for SVN clients < 1.9.0 and Conan raises an Exception, is it even possible to use SVN clients < 1.9.0?

Tonight our Jenkins job failed on Ubuntu 14 with SVN 1.8.8 with the following error:
```
conans.errors.ConanException: Error 512 while executing cmake --build '.' '--' '-j8'

[...]/conans/client/tools/scm.py:300: UserWarning: SVN::is_pristine for SVN v1.8.8 (less than 1.9) is not implemented, it is returning not-pristine always because it cannot compare with checked out version.
```
Could you tell us when exactly the is_pristine check is executed?

Thank You!
My  understanding of `is_pristine()` is that it merely outputs a warning that you may have local changes in your working copy, so warns you of that fact. I didn't think it would fail a build because of it.

I think that is what I observed when I used it in SVN v1.7
It seems that it failed while calling `cmake.build()`. Here is the complete stacktrace:
```
MyModule/version@user/channel: 
MyModule/version@user/channel: ERROR: Package '1d14fc112df5a2efd962d11b86b589726e6800f6' build failed
MyModule/version@user/channel: WARN: Build folder /home/user/.conan/data/MyModule/version/user/channel/build/97441877182eb1ba842598d25184f19be7bc0691
ERROR: Traceback (most recent call last):
  File "/home/user/python/lib/python3.6/site-packages/conans/errors.py", line 24, in conanfile_exception_formatter
    yield
  File "/home/user/python/lib/python3.6/site-packages/conans/client/installer.py", line 181, in _build_package
    self._conan_file.build()
  File "/home/user/.conan/data/MyModule/version/user/channel/package/conanfile.py", line 30, in build
    cmake.build(build_dir=".", args=args)
  File "/home/user/python/lib/python3.6/site-packages/conans/client/build/cmake.py", line 192, in build
    self._build(args, build_dir, target)
  File "/home/user/python/lib/python3.6/site-packages/conans/client/build/cmake.py", line 219, in _build
    self._run(command)
  File "/home/user/python/lib/python3.6/site-packages/conans/client/build/cmake.py", line 148, in _run
    self._conanfile.run(command)
  File "/home/user/python/lib/python3.6/site-packages/conans/model/conan_file.py", line 262, in run
    raise ConanException("Error %d while executing %s" % (retcode, command))
conans.errors.ConanException: Error 512 while executing cmake --build '.' '--' '-j8'

/home/user/python/lib/python3.6/site-packages/conans/client/tools/scm.py:300: UserWarning: SVN::is_pristine for SVN v1.8.8 (less than 1.9) is not implemented, it is returning not-pristine always because it cannot compare with checked out version.
  " checked out version.".format(self.version, SVN.API_CHANGE_VERSION))
```
With conan 1.9.1 I just tried a `conan create . dev/dev` on a recipe that uses scm and svn and I got the warning when the initial export is performed, but everything worked fine.
Hm. I will upgrade to 1.9.1 an test it again
Ok. it seems that the warning message about is_pristine had nothing to do with the cmake error. So everything should be ok. It had nothing to do with the initial issue anyway.

@jgsogo From my side you can implement the bugfix changing `API_CHANGE_VERSION` from `1.8` to `1.9`

Thanks you both for your comments. 💯 

As you have realized, the `is_pristine` function is just used to warn the user (nevertheless it makes no sense in the initial checkout). 

I will propose a PR for the next release with the `API_CHANGE_VERSION` change.

Resolving patch:
diff --git a/conans/client/tools/scm.py b/conans/client/tools/scm.py
--- a/conans/client/tools/scm.py
+++ b/conans/client/tools/scm.py
@@ -169,7 +169,7 @@ def _check_git_repo(self):
 class SVN(SCMBase):
     cmd_command = "svn"
     file_protocol = 'file:///' if platform.system() == "Windows" else 'file://'
-    API_CHANGE_VERSION = Version("1.8")  # CLI changes in 1.8
+    API_CHANGE_VERSION = Version("1.9")  # CLI changes in 1.9
 
     def __init__(self, folder=None, runner=None, *args, **kwargs):
         def runner_no_strip(command):


Test patch: