Repository: conan-io/conan

Issue:
Add KDE Neon to the with_apt list
To help us debug your issue please explain:

- [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.

The issue is very simple, KDE neon is missing from the list of operating systems that support apt. 
https://github.com/conan-io/conan/blob/85a41a2a502290879721c3e585672df292a1359b/conans/client/tools/oss.py#L122
For this OS the distro.id() function returns 'neon'.


Discussion:
Hi @rodolfo-picoreti 

Could you please elaborate on this OS? We are using the ``distro.id()`` to detect the linux distro, and the returned values from that function can be:
```
"ubuntu"        Ubuntu
    "debian"        Debian
    "rhel"          RedHat Enterprise Linux
    "centos"        CentOS
    "fedora"        Fedora
    "sles"          SUSE Linux Enterprise Server
    "opensuse"      openSUSE
    "amazon"        Amazon Linux
    "arch"          Arch Linux
    "cloudlinux"    CloudLinux OS
    "exherbo"       Exherbo Linux
    "gentoo"        GenToo Linux
    "ibm_powerkvm"  IBM PowerKVM
    "kvmibm"        KVM for IBM z Systems
    "linuxmint"     Linux Mint
    "mageia"        Mageia
    "mandriva"      Mandriva Linux
    "parallels"     Parallels
    "pidora"        Pidora
    "raspbian"      Raspbian
    "oracle"        Oracle Linux (and Oracle Enterprise Linux)
    "scientific"    Scientific Linux
    "slackware"     Slackware
    "xenserver"     XenServer
```
Any idea how to detect that distro? Won't the function return "ubuntu", as that is the base of KDE Neon?
Hey @memsharded 

The distro is: https://neon.kde.org/. The distro package probably gets the id value from the same place where lsb_release does.

Output of  **lsb_release -a**:
```
No LSB modules are available.
Distributor ID: neon
Description:    KDE neon User Edition 5.13
Release:        18.04
Codename:       bionic
```

Output of **distro.id()**: `'neon'`

I think the values you listed are only the "reliable" distro ID values, but the function can return other values.
https://github.com/nir0s/distro/blob/d20463809ce8ebb24177ea6df5e371be6d6963e1/distro.py#L128-L130
It doesn't make sense to me to use a whitelist of distros to know which ones uses apt, yum or whatever. There are tons of distros out there, you can't whitelist them all. Wouldn't simple `which apt` checking at runtime if apt is in the path be enough?
BTW, that's what is already done to detect pacman on Windows.
This is the implementation:
```python
def with_pacman(self):
        if self.is_linux:
            return self.linux_distro in ["arch", "manjaro"]
        elif self.is_windows and which('uname.exe'):
            uname = subprocess.check_output(['uname.exe', '-s']).decode()
            return uname.startswith('MSYS_NT') and which('pacman.exe')
        return False
```
That means it is not used to detect it, it is just a confirmation. The detection is MSYS_NT as return of ``uname``

The problem with using the which(app) only approach, is that it would fail in any system that contains "pacman", the game, in the path, for example.  So I think that whitelisting the distros as first step is more robust.
Whitelisting can't be robust. If anyone creates and rebrands an Ubuntu derivative, your whitelist is out of date and conan will fail for no good reason.

Just like in a [duck test](https://en.wikipedia.org/wiki/Duck_test), if your system has a binary named `apt`, that `apt` is in the path, that it can perform an `apt` query like listing the packages, then it's probably the `apt` package managager.

For example, you may run `apt show apt` and check if the command returns `Package: apt` in the first line of stdout. This should be better than parsing the output of `<some-package-manager> --version` as your pacman game might implement that option.

Resolving patch:
diff --git a/conans/client/tools/oss.py b/conans/client/tools/oss.py
--- a/conans/client/tools/oss.py
+++ b/conans/client/tools/oss.py
@@ -119,7 +119,7 @@ def __init__(self):
     @property
     def with_apt(self):
         return self.is_linux and self.linux_distro in \
-                                 ("debian", "ubuntu", "knoppix", "linuxmint", "raspbian")
+                                 ("debian", "ubuntu", "knoppix", "linuxmint", "raspbian", "neon")
 
     @property
     def with_yum(self):


Test patch:
diff --git a/conans/test/util/tools_test.py b/conans/test/util/tools_test.py
--- a/conans/test/util/tools_test.py
+++ b/conans/test/util/tools_test.py
@@ -160,6 +160,11 @@ def system_package_tool_test(self):
             spt.update()
             self.assertEquals(runner.command_called, "sudo --askpass apt-get update")
 
+            os_info.linux_distro = "neon"
+            spt = SystemPackageTool(runner=runner, os_info=os_info)
+            spt.update()
+            self.assertEquals(runner.command_called, "sudo --askpass apt-get update")
+
             os_info.linux_distro = "fedora"
             spt = SystemPackageTool(runner=runner, os_info=os_info)
             spt.update()