Repository: conan-io/conan-center-index

Issue:
[package] gfortran/10.2: source code download url broken?
### Package and Environment Details

* Package Name/Version: **gfortran/10.2**
* Operating System+version: **Linux Ubuntu 18.04**
* Compiler+version: **GCC 7**
* Conan version: **conan 1.18.0**



### Conan profile

```
Configuration:
[settings]
arch=x86_64
arch.march=None
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=7
os=Linux
os_build=Linux
[options]
[build_requires]
[env]
```

### Steps to reproduce

I just tried to build the gfortran package locally
```
conan create recipes/gfrotran/all/ 10.2@_/_
```

### Logs

<details><summary>Click to expand log</summary>

```
gfortran/10.2: Forced build from source
gfortran/10.2 (test package): Installing package
Requirements
    gfortran/10.2 from local cache - Cache
Packages
    gfortran/10.2:4db1be536558d833e52e862fd84d64d75c2b3656 - Build

Installing (downloading, building) binaries...
gfortran/10.2: Configuring sources in /home/g.gulgulia/.conan/data/gfortran/10.2/_/_/source
ERROR: gfortran/10.2: Error in source() method, line 44
        tools.get(**url[it])
        NotFoundException: Not found: https://gfortran.meteodat.ch/download/x86_64/snapshots/gcc-10-20210109.tar.xz
```

</details>



Discussion:
the link for Linux version `gcc-10-20210109.tar.xz` doesn't exist on the page https://gfortran.meteodat.ch/download/x86_64/snapshots which is specified in `gfortran/all/conandata.yml`



Resolving patch:
diff --git a/recipes/gfortran/all/conanfile.py b/recipes/gfortran/all/conanfile.py
--- a/recipes/gfortran/all/conanfile.py
+++ b/recipes/gfortran/all/conanfile.py
@@ -1,11 +1,9 @@
-from conans import ConanFile, tools
-from conans.errors import ConanInvalidConfiguration
+from conan import ConanFile
+from conan.errors import ConanInvalidConfiguration
+from conan.tools.files import copy, get, load, save, download
 import os
-import glob
-
-
-required_conan_version = ">=1.32.0"
 
+required_conan_version = ">=1.46.0"
 
 class GFortranConan(ConanFile):
     name = "gfortran"
@@ -14,12 +12,9 @@ class GFortranConan(ConanFile):
     homepage = "https://gcc.gnu.org/fortran"
     topics = ("gnu", "gcc", "fortran", "compiler")
     license = "GPL-3.0-or-later"
-    settings = "os", "arch"
+    settings = "os", "arch", "compiler", "build_type"
     no_copy_source = True
-
-    @property
-    def _source_subfolder(self):
-        return os.path.join(self.source_folder, "source_subfolder_{}".format(str(self.settings.os)))
+    short_paths = True
 
     def validate(self):
         if self.settings.arch != "x86_64":
@@ -29,38 +24,56 @@ def validate(self):
 
     def build_requirements(self):
         if self.settings.os == "Windows":
-            self.build_requires("7zip/19.00")
+            self.tool_requires("7zip/19.00")
+
+    def build(self):
+        if self.settings.os == "Windows":
+            filename =  os.path.join(self.build_folder, "GCC-10.2.0-crt-8.0.0-with-ada-20201019.7z")
+            download(self, **self.conan_data["sources"][self.version][str(self.settings.os)]["x86_64"], filename=filename)
+            self.run(f"7z x {filename}")
+        else:
+            get(self, **self.conan_data["sources"][self.version][str(self.settings.os)]["x86_64"],
+                    destination=self.build_folder, strip_root=True)
 
-    def source(self):
-        url = self.conan_data["sources"][self.version]["url"]
-        for it in url.keys():
-            if self.settings.os == "Windows" and it == "Windows":
-                filename = url[it]["filename"]
-                tools.download(**url[it])
-                self.run("7z x {0}".format(filename))
-                os.unlink(filename)
-                os.rename("mingw64", "source_subfolder_Windows")
-            elif it != "Windows":
-                tools.get(**url[it])
-                pattern = "gcc-*" if it == "Linux" else "usr"
-                os.rename(glob.glob(pattern)[0], "source_subfolder_{}".format(it))
+    @property
+    def _archive_contents_path(self):
+        if self.settings.os == "Macos":
+            return os.path.join(self.build_folder, "local")
+        elif self.settings.os == "Windows":
+            return os.path.join(self.build_folder, "mingw64")
+        else:
+            return os.path.join(self.build_folder)
+
+    @property
+    def _license_path(self):
+        return os.path.join(self._archive_contents_path, "share", "info")
+
+    @property
+    def _library_source_path(self):
+        return os.path.join(self._archive_contents_path, {
+            "Linux":  "lib64",
+            "Macos": "lib",
+            "Windows": os.path.join("lib", "gcc", "x86_64-w64-mingw32", "10.2.0")
+        }[str(self.settings.os)])
 
     def _extract_license(self):
-        info = tools.load(os.path.join(self.source_folder, "source_subfolder_Linux", "share", "info", "gfortran.info"))
+        info = load(self, os.path.join(self._license_path, "gfortran.info"))
         license_contents = info[info.find("Version 3"):info.find("END OF TERMS", 1)]
-        tools.save("LICENSE", license_contents)
+        save(self, os.path.join(self.build_folder, "LICENSE"), license_contents)
+
+    def package_id(self):
+        del self.info.settings.compiler
+        del self.info.settings.build_type # The binaries are not specific
 
     def package(self):
         self._extract_license()
-        self.copy("LICENSE", dst="licenses")
-        self.copy("gfortran*", dst="bin", src=os.path.join(self._source_subfolder, "bin"))
-        self.copy("gfortran", dst="bin", src=os.path.join(self._source_subfolder, "local", "bin"))
-        self.copy("libgfortran.a", dst="lib", src=os.path.join(self._source_subfolder, "lib64"))
-        self.copy("libgfortran.a", dst="lib", src=os.path.join(self._source_subfolder, "local", "lib"))
-        self.copy("libgfortran.a", dst="lib", src=os.path.join(self._source_subfolder, "lib", "gcc", "x86_64-w64-mingw32", "10.2.0"))
+        copy(self, "LICENSE", src=self.build_folder, dst=os.path.join(self.package_folder, "licenses"))
+        copy(self, "gfortran*", src=os.path.join(self._archive_contents_path, "bin"), dst=os.path.join(self.package_folder, "bin"))
+        copy(self, "libgfortran.a", src=self._library_source_path, dst=os.path.join(self.package_folder, "lib"))
 
     def package_info(self):
         bin_path = os.path.join(self.package_folder, "bin")
         self.output.info("Appending PATH environment variable: {}".format(bin_path))
+        self.cpp_info.includedirs = []
         self.env_info.PATH.append(bin_path)
         self.cpp_info.libs = ["gfortran"]


Test patch:
diff --git a/recipes/gfortran/all/test_package/conanfile.py b/recipes/gfortran/all/test_package/conanfile.py
--- a/recipes/gfortran/all/test_package/conanfile.py
+++ b/recipes/gfortran/all/test_package/conanfile.py
@@ -1,8 +1,14 @@
-from conans import ConanFile, tools
+from conan import ConanFile
+from conan.tools.build import can_run
 
 class TestPackageConan(ConanFile):
     settings = "os", "arch", "compiler", "build_type"
+    generators = "VirtualBuildEnv"
+    test_type = "explicit"
+
+    def build_requirements(self):
+        self.tool_requires(self.tested_reference_str)
 
     def test(self):
-        if not tools.cross_building(self):
-            self.run("gfortran --version", run_environment=True)
+        if can_run(self):
+            self.run("gfortran --version", env="conanrun")
diff --git a/recipes/gfortran/all/test_v1_package/conanfile.py b/recipes/gfortran/all/test_v1_package/conanfile.py
new file mode 100644
--- /dev/null
+++ b/recipes/gfortran/all/test_v1_package/conanfile.py
@@ -0,0 +1,8 @@
+from conans import ConanFile, tools
+
+class TestPackageConan(ConanFile):
+    settings = "os", "arch", "compiler", "build_type"
+
+    def test(self):
+        if not tools.cross_building(self):
+            self.run("gfortran --version", run_environment=True)