Repository: nf-core/tools

Issue:
New module structure breaks patch file functionality
### Description of the bug

After the recent update to the new module structure in https://github.com/nf-core/modules, all `nf-core modules` operations. When using the latest version of nf-core tools (dev, 2.6) many errors are occurring which are being solved as part of https://github.com/nf-core/tools/pull/1867 

However! `diff` files created by previous versions of `nf-core module patch` still cause problems. The existing paths create issues for the tools:
```bash
nf-core modules update --all -y
...
FileNotFoundError: [Errno 2] No such file or directory: 'modules/nf-core/modules/bcftools/filter/bcftools-filter.diff'
```

To recreate this problem, clone the repo: https://github.com/adamrtalbot/rnaseq/tree/nf-core_2.6_update_problems and run `nf-core modules update`. This repo has had a patch applied to the `tar` module with v2.5.1 and is then updated to 2.6 afterwards.

To fix:
 - The path must be corrected in the `modules.json`
 - The paths _within_ the `.diff` file itself must be corrected

Once this is done `nf-core modules` functionality works.

This does not seem to affect patches performed after updating to 2.6.

### Command used and terminal output

```console
nf-core modules update

# On repo: https://github.com/adamrtalbot/rnaseq/tree/nf-core_2.6_update_problems
```


### System information

_No response_


Discussion:

Resolving patch:
diff --git a/nf_core/modules/modules_command.py b/nf_core/modules/modules_command.py
--- a/nf_core/modules/modules_command.py
+++ b/nf_core/modules/modules_command.py
@@ -176,11 +176,46 @@ def check_modules_structure(self):
                 # Move wrong modules to the right directory
                 for module in wrong_location_modules:
                     modules_dir = Path("modules").resolve()
-                    correct_dir = Path(modules_dir, self.modules_repo.repo_path, Path(*module.parts[2:]))
+                    module_name = str(Path(*module.parts[2:]))
+                    correct_dir = Path(modules_dir, self.modules_repo.repo_path, Path(module_name))
                     wrong_dir = Path(modules_dir, module)
                     shutil.move(wrong_dir, correct_dir)
                     log.info(f"Moved {wrong_dir} to {correct_dir}.")
+                    # Check if a path file exists
+                    patch_path = correct_dir / Path(module_name + ".diff")
+                    self.check_patch_paths(patch_path, module_name)
                 shutil.rmtree(Path(self.dir, "modules", self.modules_repo.repo_path, "modules"))
                 # Regenerate modules.json file
                 modules_json = ModulesJson(self.dir)
                 modules_json.check_up_to_date()
+
+    def check_patch_paths(self, patch_path, module_name):
+        """
+        Check that paths in patch files are updated to the new modules path
+        """
+        if patch_path.exists():
+            log.info(f"Modules {module_name} contains a patch file.")
+            rewrite = False
+            with open(patch_path, "r") as fh:
+                lines = fh.readlines()
+                for index, line in enumerate(lines):
+                    # Check if there are old paths in the patch file and replace
+                    if f"modules/{self.modules_repo.repo_path}/modules/{module_name}/" in line:
+                        rewrite = True
+                        lines[index] = line.replace(
+                            f"modules/{self.modules_repo.repo_path}/modules/{module_name}/",
+                            f"modules/{self.modules_repo.repo_path}/{module_name}/",
+                        )
+            if rewrite:
+                log.info(f"Updating paths in {patch_path}")
+                with open(patch_path, "w") as fh:
+                    for line in lines:
+                        fh.write(line)
+                # Update path in modules.json if the file is in the correct format
+                modules_json = ModulesJson(self.dir)
+                modules_json.load()
+                if modules_json.has_git_url_and_modules():
+                    modules_json.modules_json["repos"][self.modules_repo.remote_url]["modules"][
+                        self.modules_repo.repo_path
+                    ][module_name]["patch"] = str(patch_path.relative_to(Path(self.dir).resolve()))
+                modules_json.dump()
diff --git a/nf_core/modules/patch.py b/nf_core/modules/patch.py
--- a/nf_core/modules/patch.py
+++ b/nf_core/modules/patch.py
@@ -50,7 +50,7 @@ def patch(self, module=None):
         module_dir = [dir for dir, m in modules if m == module][0]
         module_fullname = str(Path("modules", module_dir, module))
 
-        # Verify that the module has an entry is the modules.json file
+        # Verify that the module has an entry in the modules.json file
         if not self.modules_json.module_present(module, self.modules_repo.remote_url, module_dir):
             raise UserWarning(
                 f"The '{module_fullname}' module does not have an entry in the 'modules.json' file. Cannot compute patch"
diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py
--- a/nf_core/modules/update.py
+++ b/nf_core/modules/update.py
@@ -613,6 +613,9 @@ def try_apply_patch(self, module, repo_path, patch_relpath, module_dir, module_i
         patch_path = Path(self.dir / patch_relpath)
         module_relpath = Path("modules", repo_path, module)
 
+        # Check that paths in patch file are updated
+        self.check_patch_paths(patch_path, module)
+
         # Copy the installed files to a new temporary directory to save them for later use
         temp_dir = Path(tempfile.mkdtemp())
         temp_module_dir = temp_dir / module


Test patch: