Fix a bug with automatic tag detection (#45696)
Extracted from #45638 When adding the "detectable" tag to a package class that has the "tag" attribute inherited from a base class, we need to copy it to avoid modifying the base class.
This commit is contained in:
		 Massimiliano Culpo
					Massimiliano Culpo
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							7c985d6432
						
					
				
				
					commit
					7001a2a65a
				
			| @@ -197,13 +197,12 @@ def __init__(cls, name, bases, attr_dict): | ||||
|         # that "foo" was a possible executable. | ||||
| 
 | ||||
|         # If a package has the executables or libraries  attribute then it's | ||||
|         # assumed to be detectable | ||||
|         # assumed to be detectable. Add a tag, so finding them is faster | ||||
|         if hasattr(cls, "executables") or hasattr(cls, "libraries"): | ||||
|             # Append a tag to each detectable package, so that finding them is faster | ||||
|             if not hasattr(cls, "tags"): | ||||
|                 setattr(cls, "tags", [DetectablePackageMeta.TAG]) | ||||
|             elif DetectablePackageMeta.TAG not in cls.tags: | ||||
|                 cls.tags.append(DetectablePackageMeta.TAG) | ||||
|             # To add the tag, we need to copy the tags attribute, and attach it to | ||||
|             # the current class. We don't use append, since it might modify base classes, | ||||
|             # if "tags" is retrieved following the MRO. | ||||
|             cls.tags = getattr(cls, "tags", []) + [DetectablePackageMeta.TAG] | ||||
| 
 | ||||
|             @classmethod | ||||
|             def platform_executables(cls): | ||||
|   | ||||
| @@ -114,11 +114,31 @@ def test_find_external_cmd_not_buildable(mutable_config, working_env, mock_execu | ||||
| @pytest.mark.parametrize( | ||||
|     "names,tags,exclude,expected", | ||||
|     [ | ||||
|         # find --all | ||||
|         (None, ["detectable"], [], ["builtin.mock.find-externals1"]), | ||||
|         # find -all | ||||
|         ( | ||||
|             None, | ||||
|             ["detectable"], | ||||
|             [], | ||||
|             [ | ||||
|                 "builtin.mock.find-externals1", | ||||
|                 "builtin.mock.gcc", | ||||
|                 "builtin.mock.llvm", | ||||
|                 "builtin.mock.intel-oneapi-compilers", | ||||
|             ], | ||||
|         ), | ||||
|         # find --all --exclude find-externals1 | ||||
|         (None, ["detectable"], ["builtin.mock.find-externals1"], []), | ||||
|         (None, ["detectable"], ["find-externals1"], []), | ||||
|         ( | ||||
|             None, | ||||
|             ["detectable"], | ||||
|             ["builtin.mock.find-externals1"], | ||||
|             ["builtin.mock.gcc", "builtin.mock.llvm", "builtin.mock.intel-oneapi-compilers"], | ||||
|         ), | ||||
|         ( | ||||
|             None, | ||||
|             ["detectable"], | ||||
|             ["find-externals1"], | ||||
|             ["builtin.mock.gcc", "builtin.mock.llvm", "builtin.mock.intel-oneapi-compilers"], | ||||
|         ), | ||||
|         # find cmake (and cmake is not detectable) | ||||
|         (["cmake"], ["detectable"], [], []), | ||||
|     ], | ||||
|   | ||||
| @@ -153,7 +153,7 @@ def test_tag_no_tags(mock_packages): | ||||
| 
 | ||||
| 
 | ||||
| def test_tag_update_package(mock_packages): | ||||
|     mock_index = spack.repo.PATH.tag_index | ||||
|     mock_index = mock_packages.tag_index | ||||
|     index = spack.tag.TagIndex(repository=mock_packages) | ||||
|     for name in spack.repo.all_package_names(): | ||||
|         index.update_package(name) | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| from spack.package import * | ||||
| 
 | ||||
| 
 | ||||
| class Gcc(Package): | ||||
| class Gcc(CompilerPackage, Package): | ||||
|     """Simple compiler package.""" | ||||
| 
 | ||||
|     homepage = "http://www.example.com" | ||||
| @@ -18,6 +18,10 @@ class Gcc(Package): | ||||
| 
 | ||||
|     depends_on("conflict", when="@3.0") | ||||
| 
 | ||||
|     c_names = ["gcc"] | ||||
|     cxx_names = ["g++"] | ||||
|     fortran_names = ["gfortran"] | ||||
| 
 | ||||
|     def install(self, spec, prefix): | ||||
|         # Create the minimal compiler that will fool `spack compiler find` | ||||
|         mkdirp(prefix.bin) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| from spack.package import * | ||||
| 
 | ||||
| 
 | ||||
| class IntelOneapiCompilers(Package): | ||||
| class IntelOneapiCompilers(Package, CompilerPackage): | ||||
|     """Simple compiler package.""" | ||||
| 
 | ||||
|     homepage = "http://www.example.com" | ||||
| @@ -18,6 +18,10 @@ class IntelOneapiCompilers(Package): | ||||
|     version("2.0", md5="abcdef0123456789abcdef0123456789") | ||||
|     version("3.0", md5="def0123456789abcdef0123456789abc") | ||||
| 
 | ||||
|     c_names = ["icx"] | ||||
|     cxx_names = ["icpx"] | ||||
|     fortran_names = ["ifx"] | ||||
| 
 | ||||
|     @property | ||||
|     def compiler_search_prefix(self): | ||||
|         return self.prefix.foo.bar.baz.bin | ||||
|   | ||||
							
								
								
									
										30
									
								
								var/spack/repos/builtin.mock/packages/llvm/package.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								var/spack/repos/builtin.mock/packages/llvm/package.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| # Copyright 2013-2024 Lawrence Livermore National Security, LLC and other | ||||
| # Spack Project Developers. See the top-level COPYRIGHT file for details. | ||||
| # | ||||
| # SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||||
| 
 | ||||
| from spack.package import * | ||||
| 
 | ||||
| 
 | ||||
| class Llvm(Package, CompilerPackage): | ||||
|     """Simple compiler package.""" | ||||
| 
 | ||||
|     homepage = "http://www.example.com" | ||||
|     url = "http://www.example.com/gcc-1.0.tar.gz" | ||||
| 
 | ||||
|     version("18.1.8", md5="0123456789abcdef0123456789abcdef") | ||||
| 
 | ||||
|     variant( | ||||
|         "clang", default=True, description="Build the LLVM C/C++/Objective-C compiler frontend" | ||||
|     ) | ||||
| 
 | ||||
|     c_names = ["clang"] | ||||
|     cxx_names = ["clang++"] | ||||
|     fortran_names = ["flang"] | ||||
| 
 | ||||
|     def install(self, spec, prefix): | ||||
|         # Create the minimal compiler that will fool `spack compiler find` | ||||
|         mkdirp(prefix.bin) | ||||
|         with open(prefix.bin.gcc, "w") as f: | ||||
|             f.write('#!/bin/bash\necho "%s"' % str(spec.version)) | ||||
|         set_executable(prefix.bin.gcc) | ||||
		Reference in New Issue
	
	Block a user