summaryrefslogtreecommitdiff
path: root/pylint/testutils/primer.py
diff options
context:
space:
mode:
Diffstat (limited to 'pylint/testutils/primer.py')
-rw-r--r--pylint/testutils/primer.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/pylint/testutils/primer.py b/pylint/testutils/primer.py
new file mode 100644
index 000000000..e96ee0ea6
--- /dev/null
+++ b/pylint/testutils/primer.py
@@ -0,0 +1,100 @@
+import logging
+from pathlib import Path
+from typing import Dict, List, Optional, Union
+
+import git
+
+PRIMER_DIRECTORY_PATH = Path(".pylint_primer_tests")
+
+
+class PackageToLint:
+ """Represents data about a package to be tested during primer tests"""
+
+ url: str
+ """URL of the repository to clone"""
+
+ branch: str
+ """Branch of the repository to clone"""
+
+ directories: List[str]
+ """Directories within the repository to run pylint over"""
+
+ commit: Optional[str] = None
+ """Commit hash to pin the repository on"""
+
+ pylint_additional_args: List[str] = []
+ """Arguments to give to pylint"""
+
+ pylintrc_relpath: Optional[str] = None
+ """Path relative to project's main directory to the pylintrc if it exists"""
+
+ def __init__(
+ self,
+ url: str,
+ branch: str,
+ directories: List[str],
+ commit: Optional[str] = None,
+ pylint_additional_args: Optional[List[str]] = None,
+ pylintrc_relpath: Optional[str] = None,
+ ) -> None:
+ self.url = url
+ self.branch = branch
+ self.directories = directories
+ self.commit = commit
+ self.pylint_additional_args = pylint_additional_args or []
+ self.pylintrc_relpath = pylintrc_relpath
+
+ @property
+ def pylintrc(self) -> Optional[Path]:
+ if self.pylintrc_relpath is None:
+ return None
+ return self.clone_directory / self.pylintrc_relpath
+
+ @property
+ def clone_directory(self) -> Path:
+ """Directory to clone repository into"""
+ clone_name = "/".join(self.url.split("/")[-2:]).replace(".git", "")
+ return PRIMER_DIRECTORY_PATH / clone_name
+
+ @property
+ def paths_to_lint(self) -> List[str]:
+ """The paths we need to lint"""
+ return [str(self.clone_directory / path) for path in self.directories]
+
+ @property
+ def pylint_args(self) -> List[str]:
+ options: List[str] = []
+ if self.pylintrc is not None:
+ # There is an error if rcfile is given but does not exists
+ options += [f"--rcfile={self.pylintrc}"]
+ return self.paths_to_lint + options + self.pylint_additional_args
+
+ def lazy_clone(self) -> None:
+ """Concatenates the target directory and clones the file"""
+ logging.info("Lazy cloning %s", self.url)
+ if not self.clone_directory.exists():
+ options: Dict[str, Union[str, int]] = {
+ "url": self.url,
+ "to_path": str(self.clone_directory),
+ "branch": self.branch,
+ "depth": 1,
+ }
+ logging.info("Directory does not exists, cloning: %s", options)
+ git.Repo.clone_from(**options)
+ return
+
+ remote_sha1_commit = (
+ git.cmd.Git().ls_remote(self.url, self.branch).split("\t")[0]
+ )
+ local_sha1_commit = git.Repo(self.clone_directory).head.object.hexsha
+ if remote_sha1_commit != local_sha1_commit:
+ logging.info(
+ "Remote sha is %s while local sha is %s : pulling",
+ remote_sha1_commit,
+ local_sha1_commit,
+ )
+ repo = git.Repo(self.clone_directory)
+ origin = repo.remotes.origin
+ origin.pull()
+ else:
+ logging.info("Already up to date.")