diff --git a/pre_commit/languages/dotnet.py b/pre_commit/languages/dotnet.py index 3983c6f0c..9ebda2f73 100644 --- a/pre_commit/languages/dotnet.py +++ b/pre_commit/languages/dotnet.py @@ -2,6 +2,9 @@ import contextlib import os.path +import re +import xml.etree.ElementTree +import zipfile from typing import Generator from typing import Sequence @@ -57,10 +60,29 @@ def install_environment( ), ) - # Determine tool from the packaged file ..nupkg - build_outputs = os.listdir(os.path.join(prefix.prefix_dir, build_dir)) - for output in build_outputs: - tool_name = output.split('.')[0] + nupkg_dir = prefix.path(build_dir) + nupkgs = [x for x in os.listdir(nupkg_dir) if x.endswith('.nupkg')] + + if not nupkgs: + raise AssertionError('could not find any build outputs to install') + + for nupkg in nupkgs: + with zipfile.ZipFile(os.path.join(nupkg_dir, nupkg)) as f: + nuspec, = (x for x in f.namelist() if x.endswith('.nuspec')) + with f.open(nuspec) as spec: + tree = xml.etree.ElementTree.parse(spec) + + namespace = re.match(r'{.*}', tree.getroot().tag) + if not namespace: + raise AssertionError('could not parse namespace from nuspec') + + tool_id_element = tree.find(f'.//{namespace[0]}id') + if tool_id_element is None: + raise AssertionError('expected to find an "id" element') + + tool_id = tool_id_element.text + if not tool_id: + raise AssertionError('"id" element missing tool name') # Install to bin dir helpers.run_setup_cmd( @@ -69,7 +91,7 @@ def install_environment( 'dotnet', 'tool', 'install', '--tool-path', os.path.join(envdir, BIN_DIR), '--add-source', build_dir, - tool_name, + tool_id, ), ) diff --git a/testing/resources/dotnet_hooks_csproj_prefix_repo/.gitignore b/testing/resources/dotnet_hooks_csproj_prefix_repo/.gitignore new file mode 100644 index 000000000..edcd28f4a --- /dev/null +++ b/testing/resources/dotnet_hooks_csproj_prefix_repo/.gitignore @@ -0,0 +1,3 @@ +bin/ +obj/ +nupkg/ diff --git a/testing/resources/dotnet_hooks_csproj_prefix_repo/.pre-commit-hooks.yaml b/testing/resources/dotnet_hooks_csproj_prefix_repo/.pre-commit-hooks.yaml new file mode 100644 index 000000000..6626627d7 --- /dev/null +++ b/testing/resources/dotnet_hooks_csproj_prefix_repo/.pre-commit-hooks.yaml @@ -0,0 +1,5 @@ +- id: dotnet-example-hook + name: dotnet example hook + entry: testeroni.tool + language: dotnet + files: '' diff --git a/testing/resources/dotnet_hooks_csproj_prefix_repo/Program.cs b/testing/resources/dotnet_hooks_csproj_prefix_repo/Program.cs new file mode 100644 index 000000000..1456e8ef2 --- /dev/null +++ b/testing/resources/dotnet_hooks_csproj_prefix_repo/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace dotnet_hooks_repo +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello from dotnet!"); + } + } +} diff --git a/testing/resources/dotnet_hooks_csproj_prefix_repo/dotnet_hooks_csproj_prefix_repo.csproj b/testing/resources/dotnet_hooks_csproj_prefix_repo/dotnet_hooks_csproj_prefix_repo.csproj new file mode 100644 index 000000000..754b76006 --- /dev/null +++ b/testing/resources/dotnet_hooks_csproj_prefix_repo/dotnet_hooks_csproj_prefix_repo.csproj @@ -0,0 +1,9 @@ + + + Exe + net7.0 + true + testeroni.tool + ./nupkg + + diff --git a/tests/repository_test.py b/tests/repository_test.py index 8705d8860..c3936bf2f 100644 --- a/tests/repository_test.py +++ b/tests/repository_test.py @@ -1031,6 +1031,7 @@ def test_local_perl_additional_dependencies(store): 'dotnet_hooks_csproj_repo', 'dotnet_hooks_sln_repo', 'dotnet_hooks_combo_repo', + 'dotnet_hooks_csproj_prefix_repo', ), ) def test_dotnet_hook(tempdir_factory, store, repo):