Re: [gentoo-portage-dev] [PATCH gentoolkit] bin: Add merge-driver-ekeyword
On 12/31/20 11:47 AM, Matt Turner wrote: > Since the KEYWORDS=... assignment is a single line, git struggles to > handle conflicts. When rebasing a series of commits that modify the > KEYWORDS=... it's usually easier to throw them away and reapply on the > new tree than it is to manually handle conflicts during the rebase. > > git allows a 'merge driver' program to handle conflicts; this program > handles conflicts in the KEYWORDS=... assignment. E.g., given an ebuild > with these keywords: > > KEYWORDS="~alpha amd64 arm arm64 ~hppa ppc ppc64 x86" > > One developer drops the ~alpha keyword and pushes to gentoo.git, and > another developer stabilizes hppa. Without this merge driver, git > requires the second developer to manually resolve the conflict which is > tedious and prone to mistakes when rebasing a long series of patches. > With the custom merge driver, it automatically resolves the conflict. > > To use the merge driver, configure your gentoo.git as such: > > gentoo.git/.git/config: > > [merge "keywords"] > name = KEYWORDS merge driver > driver = merge-driver-ekeyword %O %A %B %P > > gentoo.git/.git/info/attributes: > > *.ebuild merge=keywords > > Signed-off-by: Matt Turner > --- > v3: Address Zac's feedback: use tempfile.TemporaryDirectory Looks great! -- Thanks, Zac signature.asc Description: OpenPGP digital signature
Re: [gentoo-portage-dev] [PATCH gentoolkit] bin: Add merge-driver-ekeyword
On Mon, Dec 28, 2020 at 8:09 PM Zac Medico wrote: > > On 12/28/20 3:15 PM, Matt Turner wrote: > > +def apply_keyword_changes(ebuild: str, pathname: str, > > + changes: List[Tuple[Optional[str], > > + Optional[str]]]) -> int: > > +result: int = 0 > > + > > +# ekeyword will only modify files named *.ebuild, so make a symlink > > +ebuild_symlink: str = os.path.basename(pathname) > > +os.symlink(ebuild, ebuild_symlink) > > Are we sure that the current working directory is an entirely safe place > to create this symlink? A simple fix would be to use > tempfile.TemporaryDirectory to create a temporary directory to hold the > symlink. Or, we could change ekeyword to assume that an argument is an > ebuild if os.path.isfile(arg) succeeds. Thanks, this is a good question. I've sent a v3 patch using tempfile.TemporaryDirectory. I think that's better than passing ".merge_file_SEd3R8" to ekeyword since the filename is printed and it's nice to see what file is being modified during the rebase.
Re: [gentoo-portage-dev] [PATCH gentoolkit] bin: Add merge-driver-ekeyword
On 12/28/20 5:09 PM, Zac Medico wrote: > On 12/28/20 3:15 PM, Matt Turner wrote: >> +def apply_keyword_changes(ebuild: str, pathname: str, >> + changes: List[Tuple[Optional[str], >> + Optional[str]]]) -> int: >> +result: int = 0 >> + >> +# ekeyword will only modify files named *.ebuild, so make a symlink >> +ebuild_symlink: str = os.path.basename(pathname) >> +os.symlink(ebuild, ebuild_symlink) > > Are we sure that the current working directory is an entirely safe place > to create this symlink? A simple fix would be to use > tempfile.TemporaryDirectory to create a temporary directory to hold the > symlink. Or, we could change ekeyword to assume that an argument is an > ebuild if os.path.isfile(arg) succeeds. > >> +for removals, additions in changes: >> +args = [] >> +for rem in removals: >> +# Drop leading '~' and '-' characters and prepend '^' >> +i = 1 if rem[0] in ('~', '-') else 0 >> +args.append('^' + rem[i:]) >> +if additions: >> +args.extend(additions) >> +args.append(ebuild_symlink) >> + >> +result = ekeyword.main(args) Another option is to bypass the ekeyword.main function, like this: try: ekeyword.process_ebuild(pathname, list(map(ekeyword.arg_to_op, args)) except Exception: result = 1 traceback.print_exc() else: result = 0 >> +if result != 0: >> +break >> + >> +os.remove(ebuild_symlink) >> +return result > > -- Thanks, Zac signature.asc Description: OpenPGP digital signature
Re: [gentoo-portage-dev] [PATCH gentoolkit] bin: Add merge-driver-ekeyword
On 12/28/20 3:15 PM, Matt Turner wrote: > +def apply_keyword_changes(ebuild: str, pathname: str, > + changes: List[Tuple[Optional[str], > + Optional[str]]]) -> int: > +result: int = 0 > + > +# ekeyword will only modify files named *.ebuild, so make a symlink > +ebuild_symlink: str = os.path.basename(pathname) > +os.symlink(ebuild, ebuild_symlink) Are we sure that the current working directory is an entirely safe place to create this symlink? A simple fix would be to use tempfile.TemporaryDirectory to create a temporary directory to hold the symlink. Or, we could change ekeyword to assume that an argument is an ebuild if os.path.isfile(arg) succeeds. > +for removals, additions in changes: > +args = [] > +for rem in removals: > +# Drop leading '~' and '-' characters and prepend '^' > +i = 1 if rem[0] in ('~', '-') else 0 > +args.append('^' + rem[i:]) > +if additions: > +args.extend(additions) > +args.append(ebuild_symlink) > + > +result = ekeyword.main(args) > +if result != 0: > +break > + > +os.remove(ebuild_symlink) > +return result -- Thanks, Zac signature.asc Description: OpenPGP digital signature