Skip to content

Commit

Permalink
Merge pull request #52 from sebalix/imp-port-any-addon-path
Browse files Browse the repository at this point in the history
[IMP] Migrate/port modules located in subfolder (module path as input instead of module name)
  • Loading branch information
sebalix authored Nov 5, 2024
2 parents dce5068 + 3708158 commit 918d2d4
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 32 deletions.
26 changes: 18 additions & 8 deletions oca_port/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class App(Output):
string representation of the source branch, e.g. 'origin/15.0'
target:
string representation of the target branch, e.g. 'origin/16.0'
addon:
the name of the module to process
addon_path:
the path of the addon to process
destination:
string representation of the destination branch,
e.g. 'camptocamp/16.0-addon-dev'
Expand Down Expand Up @@ -62,7 +62,7 @@ class App(Output):

source: str
target: str
addon: str
addon_path: str
destination: str = None
source_version: str = None
target_version: str = None
Expand Down Expand Up @@ -149,6 +149,11 @@ def _prepare_parameters(self):
if self.repo.is_dirty(untracked_files=True):
raise ValueError("changes not committed detected in this repository.")

# Module name
self.addon_path = pathlib.Path(self.addon_path)
self.addons_rootdir = self.addon_path.parent
self.addon = self.addon_path.name

# Convert them to full remote info if needed
for key in ("source", "target", "destination"):
value = getattr(self, key)
Expand Down Expand Up @@ -263,14 +268,19 @@ def _check_branch_exists(self, branch, raise_exc=False):

def _check_addon_exists(self, branch, raise_exc=False):
repo = self.repo
addon = self.addon
branch_addons = [t.path for t in repo.commit(branch.ref()).tree.trees]
if addon not in branch_addons:
addons_tree = repo.commit(branch.ref()).tree
if self.addons_rootdir and self.addons_rootdir.name:
addons_tree /= str(self.addons_rootdir)
branch_addons = [t.path for t in addons_tree.trees]
if str(self.addon_path) not in branch_addons:
if not raise_exc:
return False
error = f"{addon} does not exist on {branch.ref()}"
error = f"{self.addon_path} does not exist on {branch.ref()}"
if self.cli:
error = f"{bc.FAIL}{addon}{bc.ENDC} does not exist on {branch.ref()}"
error = (
f"{bc.FAIL}{self.addon_path}{bc.ENDC} "
"does not exist on {branch.ref()}"
)
raise ValueError(error)
return True

Expand Down
6 changes: 3 additions & 3 deletions oca_port/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
@click.command()
@click.argument("source", required=True)
@click.argument("target", required=True)
@click.argument("addon", required=True)
@click.argument("addon_path", required=True)
@click.option(
"--destination",
help=("Git reference where work will be pushed, e.g. 'camptocamp/16.0-dev'."),
Expand Down Expand Up @@ -99,7 +99,7 @@
@click.option("--no-cache", is_flag=True, help="Disable user's cache.")
@click.option("--clear-cache", is_flag=True, help="Clear the user's cache.")
def main(
addon: str,
addon_path: str,
source: str,
target: str,
destination: str,
Expand Down Expand Up @@ -132,7 +132,7 @@ def main(
"""
try:
app = App(
addon=addon,
addon_path=addon_path,
source=source,
target=target,
destination=destination,
Expand Down
2 changes: 1 addition & 1 deletion oca_port/migrate_addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def _generate_patches(self, patches_dir):
patches_dir,
f"{self.app.to_branch.ref()}..{self.app.from_branch.ref()}",
"--",
self.app.addon,
self.app.addon_path,
)

def _apply_patches(self, patches_dir):
Expand Down
29 changes: 20 additions & 9 deletions oca_port/port_addon_pr.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import click
import git
import requests

from .utils import git as g, misc
from .utils.session import Session
Expand Down Expand Up @@ -607,7 +608,7 @@ class BranchesDiff(Output):

def __init__(self, app):
self.app = app
self.path = self.app.addon
self.path = self.app.addon_path
self.from_branch_path_commits, _ = self._get_branch_commits(
self.app.from_branch.ref(), self.path
)
Expand Down Expand Up @@ -649,7 +650,9 @@ def _get_branch_commits(self, branch, path="."):
for commit in commits:
if self.app.cache.is_commit_ported(commit.hexsha):
continue
com = g.Commit(commit, cache=self.app.cache)
com = g.Commit(
commit, addons_path=self.app.addons_rootdir, cache=self.app.cache
)
if self._skip_commit(com):
continue
commits_list.append(com)
Expand Down Expand Up @@ -751,7 +754,11 @@ def get_commits_diff(self):
# Ignore commits referenced by a PR but not present
# in the stable branches
continue
pr_commit = g.Commit(raw_commit, cache=self.app.cache)
pr_commit = g.Commit(
raw_commit,
addons_path=self.app.addons_rootdir,
cache=self.app.cache,
)
if self._skip_commit(pr_commit):
continue
pr_commit_paths = {
Expand Down Expand Up @@ -839,12 +846,16 @@ def _get_original_pr(self, commit: g.Commit):
# Request GitHub to get them
if not any("github.com" in remote.url for remote in self.app.repo.remotes):
return
raw_data = self.app.github.get_original_pr(
self.app.upstream_org,
self.app.repo_name,
self.app.from_branch.name,
commit.hexsha,
)
try:
raw_data = self.app.github.get_original_pr(
self.app.upstream_org,
self.app.repo_name,
self.app.from_branch.name,
commit.hexsha,
)
except requests.exceptions.ConnectionError:
self._print("⚠️ Unable to detect original PR (connection error)")
return
if raw_data:
# Get all commits of the PR as they could update others addons
# than the one the user is interested in.
Expand Down
2 changes: 1 addition & 1 deletion oca_port/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def _create_app(self, source, target, destination=None, **kwargs):
"source": source,
"target": target,
"destination": destination,
"addon": self.addon,
"addon_path": self.addon,
"source_version": None,
"target_version": None,
"repo_path": self.repo_path,
Expand Down
28 changes: 18 additions & 10 deletions oca_port/utils/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)

import contextlib
import pathlib
import re
import subprocess
from collections import abc
Expand Down Expand Up @@ -38,10 +39,12 @@ def ref(self):
class CommitPath(str):
"""Helper class to know if a base path is a directory or a file."""

def __new__(cls, value):
new_value = value.split("/", maxsplit=1)[0]
obj = super().__new__(cls, new_value)
obj.isdir = "/" in value
def __new__(cls, addons_path, value):
file_path = pathlib.Path(value).relative_to(addons_path)
root_node = file_path.parts[0]
obj = super().__new__(cls, root_node)
# As soon as `file_path` has a parent, the root node is obviously a folder
obj.isdir = bool(file_path.parent.name)
return obj


Expand All @@ -58,9 +61,10 @@ class Commit:
other_equality_attrs = ("paths",)
eq_strict = True

def __init__(self, commit, cache=None):
def __init__(self, commit, addons_path=".", cache=None):
"""Initializes a new Commit instance from a GitPython Commit object."""
self.raw_commit = commit
self.addons_path = addons_path
self.cache = cache
self.author_name = commit.author.name
self.author_email = commit.author.email
Expand All @@ -87,11 +91,15 @@ def files(self):

@property
def paths(self):
"""Returns list of `CommitPath` objects."""
# Access git storage or cache only on demand to avoid too much IO
paths = {CommitPath(f) for f in self.files}
if not self._paths:
self._paths = paths
"""Return the folders/files updated in `addons_path`.
If a commit updates files 'x/a/b/c.py', 'x/d/e.py' and 'x/f.txt', knowing
the `addons_path` is `x`, the root nodes updated by this commit are
`a` (folder), `d` (folder) and `f.txt` (file).
"""
if self._paths:
return self._paths
self._paths = {CommitPath(self.addons_path, f) for f in self.files}
return self._paths

def _get_files(self):
Expand Down

0 comments on commit 918d2d4

Please sign in to comment.