Skip to content

Conversation

@davidlucman
Copy link

No description provided.

MINIMUM_SPARSE_VERSION = "0.6.4"

class SparseDependency(Dependency):
class InstallDependency(Dependency):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is no longer specific to sparse.py, these changes should be made to class Dependency directly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured it would be nice to keep these outside of class Dependency for customization.

Comment on lines 36 to 44
def install_sparse_from_source() -> None:
"""
Install sparse from source.
"""
with tempfile.TemporaryDirectory() as tmpdir:
src_dir = os.path.join(tmpdir, "sparse")
subprocess.run(["git", "clone", "git://git.kernel.org/pub/scm/devel/sparse/sparse.git", src_dir], check=True)
subprocess.run(["make"], cwd=src_dir, check=True)
subprocess.run(["sudo", "make", f"PREFIX={SANDBOX_PATH}", "install"], cwd=src_dir, check=True)

def install_llvm_from_source() -> None:
pass
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense to make these functions overwrite Dependency.install_from_source() instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added these functions here to have the option to add custom install from source instructions.

@davidgantman davidgantman linked an issue Jul 31, 2025 that may be closed by this pull request
@davidlucman
Copy link
Author

I noticed that clang is being installed in ai_code_review.py and also in sparse.py. Should they be put together or stay separate?

@davidgantman
Copy link
Collaborator

I noticed that clang is being installed in ai_code_review.py and also in sparse.py. Should they be put together or stay separate?

They should stay separate. For example, situations such as ai_code_review requiring clang<=20 and sparse requiring clang>=14, each one should be able to define its own requirements.

This brings up a interesting dilemma, what happens if sparse installs clang-22 and then ai_code_review.install() runs and installs clang-12 (for whatever reason)? It's possible for there to be no intersection between the ranges of the compatible versions of certain dependencies, and we don't take that into account, we just run review.install() and continue, and never check to make sure none of the subsequent reviews install an version that's incompatible with the first review.

It might be necessary to redesign the dependency check, maybe we can iterate through each reviews' dependencies and create a set (set, not list) of dependencies, that way we can overlay the ranges of compatible versions and ensure that there's an intersection between them. Altneratively, we can create a per-PatchReview bin directory where all of its dependencies are installed, and in PatchReview.__init__() we can prepend PATH with cur_review.dependencies_dir so that the binaries in the respective PatchReview dependency directory are used. For example PatchWise/patchwise/bin/sparse/clang (clang-20) and PatchWise/patchwise/bin/aicodereview/clang (clang-14)

Signed-off-by: David Lucman <dlucman@qti.qualcomm.com>
@davidlucman davidlucman force-pushed the install-dependencies-07-30 branch from 9439323 to 806c184 Compare July 31, 2025 06:47
self,
name: str,
install_name: str = "",
source: str = "",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

source is not a string, right? It's supposed to be a function?

def __init__(
self,
name: str,
install_name: str = "",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
install_name: str = "",
package_name: str = "",

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a way to define optional strings with typing

except ImportError as e:
self.logger.warning(f"{e}")
self.logger.info(f"Installing {self.name} from source...")
self.source()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.source isn't being defined in ai_code_review.py


DEPENDENCIES = getattr(AiReview, "DEPENDENCIES", []) + [
Dependency(
InstallDependency(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.source isn't being defined in ai_code_review.py

max_version: Union[int, float, str, None] = None,
):
self.name = name
self.install_name = install_name if install_name else name
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.install_name = install_name if install_name else name
self.install_name = install_name or name

):
self.name = name
self.install_name = install_name if install_name else name
self.source = source
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of taking a function as an argument, just define the installation function in the subclasses that need it and call it from _do_install()

Comment on lines +115 to +120
# method_name = (
# f"{self.__class__.__name__}.{inspect.currentframe().f_code.co_name}"
# )
# raise NotImplementedError(
# f"{self.__class__.__name__} must implement {method_name}."
# )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# method_name = (
# f"{self.__class__.__name__}.{inspect.currentframe().f_code.co_name}"
# )
# raise NotImplementedError(
# f"{self.__class__.__name__} must implement {method_name}."
# )

@davidlucman
Copy link
Author

Do you think we should add install_llvm_from_source in a common folder since we are installing LLVM projects separately in sparse.py and ai_code_review.py?

@davidgantman
Copy link
Collaborator

Do you think we should add install_llvm_from_source in a common folder since we are installing LLVM projects separately in sparse.py and ai_code_review.py?

Good point, there's definitely value in having a shared Dependency object for LLVM between reviews, let's move class Dependency to patch_review/dependencies/dependency.py and implement class LLVMDependency in patch_review/dependencies/llvm_dependency.py. The call to install_llvm_from_source() can be made directly from LLVMDependency._do_install()

@davidlucman
Copy link
Author

I'm planning to reorganize the Dependency class. First, I'll move it into its own file and turn it into a minimal template class. Then, I'll create specific subclasses like SourceDependency and PackageDependency that inherit from it. This structure will allow us to support different methods for installing custom dependencies.

@davidgantman
Copy link
Collaborator

Mark the PR as a draft until you're ready for review.

@davidlucman davidlucman marked this pull request as draft August 5, 2025 06:08
@davidgantman davidgantman added the duplicate This issue or pull request already exists label Sep 9, 2025
@davidgantman
Copy link
Collaborator

Replaced by #40

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Install dependencies not working

2 participants