[ADD] makefile format script directory with format_script

This commit is contained in:
Mathieu Benoit 2021-06-27 00:49:00 -04:00
parent 705416d021
commit bb4fc63fc2
23 changed files with 1754 additions and 782 deletions

View file

@ -246,7 +246,7 @@ open_terminal:
# format # # format #
############ ############
.PHONY: format .PHONY: format
format: format_code_generator format_code_generator_template format: format_code_generator format_code_generator_template format_script
.PHONY: format_code_generator .PHONY: format_code_generator
format_code_generator: format_code_generator:
@ -258,6 +258,10 @@ format_code_generator_template:
./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator-template/ ./script/maintenance/black.sh ./addons/TechnoLibre_odoo-code-generator-template/
#./script/maintenance/prettier_xml.sh ./addons/TechnoLibre_odoo-code-generator-template/ #./script/maintenance/prettier_xml.sh ./addons/TechnoLibre_odoo-code-generator-template/
.PHONY: format_script
format_script:
./script/maintenance/black.sh ./script/
########### ###########
# clean # # clean #
########### ###########

View file

@ -5,6 +5,7 @@ import argparse
import logging import logging
import subprocess import subprocess
from code_writer import CodeWriter from code_writer import CodeWriter
# import tokenize # import tokenize
from script.git_tool import GitTool from script.git_tool import GitTool
@ -21,16 +22,22 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Transform a python file in code writer format python file. Transform a python file in code writer format python file.
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-f",
"--file",
dest="file",
required=True,
help="Path of file to transform to code_writer.",
)
parser.add_argument(
"-o", "--output", dest="output", help="The output file."
) )
parser.add_argument('-f', '--file', dest="file", required=True,
help="Path of file to transform to code_writer.")
parser.add_argument('-o', '--output', dest="output",
help="The output file.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -68,7 +75,11 @@ def main():
no_tab = 0 no_tab = 0
# Validate file format # Validate file format
out = subprocess.check_output(f"python -m tabnanny {config.file}", stderr=subprocess.STDOUT, shell=True) out = subprocess.check_output(
f"python -m tabnanny {config.file}",
stderr=subprocess.STDOUT,
shell=True,
)
if out: if out:
print(out) print(out)
sys.exit(1) sys.exit(1)
@ -82,14 +93,16 @@ def main():
cw.emit("cw = CodeWriter()") cw.emit("cw = CodeWriter()")
no_line = 1 no_line = 1
with open(config.file, 'r') as file: with open(config.file, "r") as file:
for line in file.readlines(): for line in file.readlines():
nb_tab, nb_space = count_space_tab(line) nb_tab, nb_space = count_space_tab(line)
diff_tab = nb_tab - last_nb_tab diff_tab = nb_tab - last_nb_tab
new_line = line.strip() new_line = line.strip()
new_line = new_line.replace("\"", "\\\"") new_line = new_line.replace('"', '\\"')
status_no_tab = add_line(cw, new_line, no_line, nb_tab, no_tab, no_tab, nb_space) status_no_tab = add_line(
cw, new_line, no_line, nb_tab, no_tab, no_tab, nb_space
)
if status_no_tab >= 0: if status_no_tab >= 0:
no_tab = status_no_tab no_tab = status_no_tab
@ -99,13 +112,15 @@ def main():
output = cw.render() output = cw.render()
if config.output: if config.output:
with open(config.output, 'w') as file: with open(config.output, "w") as file:
file.write(output) file.write(output)
else: else:
print(output) print(output)
def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space): def add_line(
cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space
):
""" """
Recursive check indent and write line Recursive check indent and write line
:param cw: code_writer module :param cw: code_writer module
@ -123,25 +138,27 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
sys.exit(-1) sys.exit(-1)
if nb_indent == -1: if nb_indent == -1:
cw.emit("cw.emit(\"\")") cw.emit('cw.emit("")')
return 0 return 0
elif nb_indent == no_indent: elif nb_indent == no_indent:
if nb_indent == 0: if nb_indent == 0:
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
return 0 return 0
elif nb_indent == 1: elif nb_indent == 1:
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 2: elif nb_indent == 2:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
f"with cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 3: elif nb_indent == 3:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -150,9 +167,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 4: elif nb_indent == 4:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -164,9 +184,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 5: elif nb_indent == 5:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -181,9 +204,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 6: elif nb_indent == 6:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -201,9 +227,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 7: elif nb_indent == 7:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -224,9 +253,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 8: elif nb_indent == 8:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -250,9 +282,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 9: elif nb_indent == 9:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -279,9 +314,12 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 10: elif nb_indent == 10:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -311,9 +349,14 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 11: elif nb_indent == 11:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -342,13 +385,26 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 12: elif nb_indent == 12:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -377,16 +433,35 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 13: elif nb_indent == 13:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -415,19 +490,44 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 14: elif nb_indent == 14:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -458,22 +558,53 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 15: elif nb_indent == 15:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -504,25 +635,63 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
"with"
f" cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 16: elif nb_indent == 16:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -551,28 +720,72 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
f"with cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 17: elif nb_indent == 17:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -601,31 +814,81 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
f"with cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 18: elif nb_indent == 18:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -656,34 +919,90 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
f"with cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
elif nb_indent == 19: elif nb_indent == 19:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
@ -716,48 +1035,126 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent - 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with"
f" cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if nb_indent - 1 > init_no_intend: if (
cw.emit(f"with cw.indent():") nb_indent
- 1
> init_no_intend
):
cw.emit(
f"with cw.indent():"
)
with cw.indent(): with cw.indent():
if no_indent != init_no_intend: if (
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") no_indent
!= init_no_intend
):
cw.emit(
f"with cw.indent({4 + nb_space if nb_space else ''}):"
)
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(
f'cw.emit("{line}")'
)
return nb_indent return nb_indent
else: else:
if no_indent > nb_indent: if no_indent > nb_indent:
# deindent # deindent
return add_line(cw, line, no_line, nb_indent, no_indent - 1, init_no_intend, nb_space) return add_line(
cw,
line,
no_line,
nb_indent,
no_indent - 1,
init_no_intend,
nb_space,
)
else: else:
# indent # indent
return add_line(cw, line, no_line, nb_indent, no_indent + 1, init_no_intend, nb_space) return add_line(
cw,
line,
no_line,
nb_indent,
no_indent + 1,
init_no_intend,
nb_space,
)
print("BUG") print("BUG")
return -1 return -1
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -20,16 +20,22 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Transform a xml file in code writer format xml file. Transform a xml file in code writer format xml file.
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-f",
"--file",
dest="file",
required=True,
help="Path of file to transform to code_writer.",
)
parser.add_argument(
"-o", "--output", dest="output", help="The output file."
) )
parser.add_argument('-f', '--file', dest="file", required=True,
help="Path of file to transform to code_writer.")
parser.add_argument('-o', '--output', dest="output",
help="The output file.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -55,7 +61,10 @@ def code_writer_deep_xml(nodes):
if lst_comment: if lst_comment:
comment = f"# {lst_comment[0]}" comment = f"# {lst_comment[0]}"
code_line = (f"E.{node.tagName}({str(dict(node.attributes.items()))})", value) code_line = (
f"E.{node.tagName}({str(dict(node.attributes.items()))})",
value,
)
lst_result.append((comment, code_line)) lst_result.append((comment, code_line))
elif node.nodeType == Node.TEXT_NODE: elif node.nodeType == Node.TEXT_NODE:
if size_nodes == 1: if size_nodes == 1:
@ -102,31 +111,36 @@ def main():
print(f"Error, cannot parse {config.file}") print(f"Error, cannot parse {config.file}")
sys.exit(1) sys.exit(1)
cw.emit('from lxml.builder import E') cw.emit("from lxml.builder import E")
cw.emit('from lxml import etree as ET') cw.emit("from lxml import etree as ET")
cw.emit('from code_writer import CodeWriter') cw.emit("from code_writer import CodeWriter")
cw.emit('') cw.emit("")
cw.emit('print(\'<?xml version="1.0" encoding="utf-8"?>\')') cw.emit('print(\'<?xml version="1.0" encoding="utf-8"?>\')')
cw.emit('print("<odoo>")') cw.emit('print("<odoo>")')
lst_function = [] lst_function = []
comment_for_next_group = None comment_for_next_group = None
for odoo in mydoc.getElementsByTagName('odoo'): for odoo in mydoc.getElementsByTagName("odoo"):
for ir_view_item in odoo.childNodes: for ir_view_item in odoo.childNodes:
if ir_view_item.nodeType == Node.ELEMENT_NODE: if ir_view_item.nodeType == Node.ELEMENT_NODE:
# Show part of xml # Show part of xml
fct_name = "ma_fonction" fct_name = "ma_fonction"
lst_function.append(fct_name) lst_function.append(fct_name)
cw.emit(f'def {fct_name}():') cw.emit(f"def {fct_name}():")
with cw.indent(): with cw.indent():
cw.emit('"""') cw.emit('"""')
for line in transform_string_to_list(ir_view_item.toprettyxml()): for line in transform_string_to_list(
ir_view_item.toprettyxml()
):
cw.emit(line) cw.emit(line)
cw.emit('"""') cw.emit('"""')
# Show comment # Show comment
if comment_for_next_group: if comment_for_next_group:
cw.emit(f'print(\'<!-- {comment_for_next_group.strip()} -->\')') cw.emit(
"print('<!--"
f" {comment_for_next_group.strip()} -->')"
)
comment_for_next_group = None comment_for_next_group = None
attributes_root = dict(ir_view_item.attributes.items()) attributes_root = dict(ir_view_item.attributes.items())
@ -136,15 +150,21 @@ def main():
generate_code.generate_code(lst_out) generate_code.generate_code(lst_out)
child_root = generate_code.result child_root = generate_code.result
code = f'root = E.{ir_view_item.tagName}({str(attributes_root)}, {child_root})' code = (
"root ="
f" E.{ir_view_item.tagName}({str(attributes_root)},"
f" {child_root})"
)
for line in code.split("\n"): for line in code.split("\n"):
cw.emit(line) cw.emit(line)
cw.emit('content = ET.tostring(root, pretty_print=True)') cw.emit("content = ET.tostring(root, pretty_print=True)")
cw.emit() cw.emit()
cw.emit("cw = CodeWriter()") cw.emit("cw = CodeWriter()")
cw.emit('for line in content.decode("utf-8").split("\\n"):') cw.emit(
'for line in content.decode("utf-8").split("\\n"):'
)
with cw.indent(): with cw.indent():
cw.emit("with cw.indent():") cw.emit("with cw.indent():")
with cw.indent(): with cw.indent():
@ -161,13 +181,15 @@ def main():
output = cw.render() output = cw.render()
if config.output: if config.output:
with open(config.output, 'w') as file: with open(config.output, "w") as file:
file.write(output) file.write(output)
else: else:
print(output) print(output)
def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space): def add_line(
cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space
):
""" """
Recursive check indent and write line Recursive check indent and write line
:param cw: code_writer module :param cw: code_writer module
@ -185,21 +207,21 @@ def add_line(cw, line, no_line, nb_indent, no_indent, init_no_intend, nb_space):
sys.exit(-1) sys.exit(-1)
if nb_indent == -1: if nb_indent == -1:
cw.emit("cw.emit(\"\")") cw.emit('cw.emit("")')
return 0 return 0
elif nb_indent == no_indent: elif nb_indent == no_indent:
if nb_indent == 0: if nb_indent == 0:
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
return 0 return 0
elif nb_indent == 1: elif nb_indent == 1:
if no_indent != init_no_intend: if no_indent != init_no_intend:
cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):") cw.emit(f"with cw.indent({4 + nb_space if nb_space else ''}):")
with cw.indent(): with cw.indent():
cw.emit(f"cw.emit(\"{line}\")") cw.emit(f'cw.emit("{line}")')
elif nb_indent == 2: elif nb_indent == 2:
if nb_indent - 1 > init_no_intend: if nb_indent - 1 > init_no_intend:
cw.emit(f"with cw.indent():") cw.emit(f"with cw.indent():")
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -5,7 +5,7 @@ import argparse
import logging import logging
from subprocess import check_output from subprocess import check_output
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO")) logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
@ -22,20 +22,29 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Restore database, use cache to clone to improve speed. Restore database, use cache to clone to improve speed.
''', """,
epilog='''\ epilog="""\
''' """,
) )
# parser.add_argument('-d', '--dir', dest="dir", default="./", # parser.add_argument('-d', '--dir', dest="dir", default="./",
# help="Path of repo to change remote, including submodule.") # help="Path of repo to change remote, including submodule.")
parser.add_argument('--database', help="Database to manipulate.") parser.add_argument("--database", help="Database to manipulate.")
parser.add_argument('--image', default="erplibre_base", parser.add_argument(
help="Image name to restore, from directory image_db, filename without '.zip'. " "--image",
"Example, use erplibre_base to use image erplibre_base.zip.") default="erplibre_base",
parser.add_argument('--clean_cache', action="store_true", help="Delete all database cache to clone, " help=(
"begin by _cache_.") "Image name to restore, from directory image_db, filename without"
" '.zip'. Example, use erplibre_base to use image"
" erplibre_base.zip."
),
)
parser.add_argument(
"--clean_cache",
action="store_true",
help="Delete all database cache to clone, begin by _cache_.",
)
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -52,7 +61,10 @@ def main():
if config.clean_cache: if config.clean_cache:
for db in lst_db_cache: for db in lst_db_cache:
_logger.info(f"## Delete {db} ##") _logger.info(f"## Delete {db} ##")
arg = f"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database {db}" arg = (
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
f" {db}"
)
out = check_output(arg.split(" ")).decode() out = check_output(arg.split(" ")).decode()
print(out) print(out)
@ -61,23 +73,35 @@ def main():
# Drop db # Drop db
if config.database in lst_db: if config.database in lst_db:
_logger.info(f"## Drop {config.database} ##") _logger.info(f"## Drop {config.database} ##")
arg = f"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database {config.database}" arg = (
"./.venv/bin/python3 ./odoo/odoo-bin db --drop --database"
f" {config.database}"
)
out = check_output(arg.split(" ")).decode() out = check_output(arg.split(" ")).decode()
print(out) print(out)
# Check cache exist # Check cache exist
if cache_database not in lst_db_cache: if cache_database not in lst_db_cache:
_logger.info(f"## Create cache {cache_database} from image {config.image} ##") _logger.info(
arg = f"./.venv/bin/python3 ./odoo/odoo-bin db --restore --restore_image {config.image} " \ f"## Create cache {cache_database} from image"
f"--database {cache_database}" f" {config.image} ##"
)
arg = (
"./.venv/bin/python3 ./odoo/odoo-bin db --restore"
f" --restore_image {config.image} --database {cache_database}"
)
out = check_output(arg.split(" ")).decode() out = check_output(arg.split(" ")).decode()
print(out) print(out)
# Clone database # Clone database
_logger.info(f"## Clone cache {cache_database} to database {config.database} ##") _logger.info(
arg = f"./.venv/bin/python3 ./odoo/odoo-bin db --clone --from_database {cache_database} " \ f"## Clone cache {cache_database} to database {config.database} ##"
f"--database {config.database}" )
arg = (
"./.venv/bin/python3 ./odoo/odoo-bin db --clone --from_database"
f" {cache_database} --database {config.database}"
)
out = check_output(arg.split(" ")).decode() out = check_output(arg.split(" ")).decode()
print(out) print(out)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -1,6 +1,6 @@
#!./.venv/bin/python #!./.venv/bin/python
import requests import requests
r = requests.get(r'https://api.ipify.org') r = requests.get(r"https://api.ipify.org")
ip = r.text ip = r.text
print(ip) print(ip)

View file

@ -19,26 +19,47 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Can update all old_ip to new_ip. Can update all old_ip to new_ip.
When auto_sync is enable: When auto_sync is enable:
Check zone and name on cloudflare and compare with public ip, update all old ip with new ip if different. Check zone and name on cloudflare and compare with public ip, update all old ip with new ip if different.
You need your profile in file ~/.cloudflare/cloudflare.cfg You need your profile in file ~/.cloudflare/cloudflare.cfg
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"--profile",
required=True,
help="The profile of CloudFlare, check ~/.cloudflare/cloudflare.cfg.",
)
parser.add_argument(
"--old_ip", required=False, help="Ip to search to update."
)
parser.add_argument(
"--new_ip", required=False, help="Ip to replace the old ip."
)
parser.add_argument(
"--dns_name",
required=False,
help="DNS name to output his ip and sync.",
)
parser.add_argument(
"--zone_name",
required=False,
help="The CloudFlare zone name to check.",
)
parser.add_argument("--delete", action="store_true")
parser.add_argument("--debug", action="store_true")
parser.add_argument("--raw", action="store_true")
parser.add_argument(
"--auto_sync",
action="store_true",
help=(
"Need this to use DNS name and zone name to sync public ip to"
" CloudFlare."
),
) )
parser.add_argument('--profile', required=True,
help="The profile of CloudFlare, check ~/.cloudflare/cloudflare.cfg.")
parser.add_argument('--old_ip', required=False, help="Ip to search to update.")
parser.add_argument('--new_ip', required=False, help="Ip to replace the old ip.")
parser.add_argument('--dns_name', required=False, help="DNS name to output his ip and sync.")
parser.add_argument('--zone_name', required=False, help="The CloudFlare zone name to check.")
parser.add_argument('--delete', action="store_true")
parser.add_argument('--debug', action="store_true")
parser.add_argument('--raw', action="store_true")
parser.add_argument('--auto_sync', action="store_true",
help="Need this to use DNS name and zone name to sync public ip to CloudFlare.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -50,25 +71,28 @@ class ManageCloudFlare:
@staticmethod @staticmethod
def get_public_ip(): def get_public_ip():
r = requests.get(r'https://api.ipify.org') r = requests.get(r"https://api.ipify.org")
ip = r.text ip = r.text
return ip return ip
def get_ip_cloudflare(self, zone_name, name): def get_ip_cloudflare(self, zone_name, name):
"""Return ip from a zone and domain""" """Return ip from a zone and domain"""
zone = self.cf.zones.get(params={'name': zone_name}) zone = self.cf.zones.get(params={"name": zone_name})
lst_zone = [a.get("id") for a in zone] lst_zone = [a.get("id") for a in zone]
for zone_id in lst_zone: for zone_id in lst_zone:
lst_result_dns = self.cf.zones.dns_records.get(zone_id) lst_result_dns = self.cf.zones.dns_records.get(zone_id)
for result_dns in lst_result_dns: for result_dns in lst_result_dns:
if result_dns.get("type") == "A" and result_dns.get("name") == name: if (
result_dns.get("type") == "A"
and result_dns.get("name") == name
):
return result_dns.get("content") return result_dns.get("content")
def edit_cloudflare(self, old_ip, delete=False, new_ip=""): def edit_cloudflare(self, old_ip, delete=False, new_ip=""):
"""Change ip of zone and name""" """Change ip of zone and name"""
# TODO support smaller range # TODO support smaller range
params = {'per_page': 500} params = {"per_page": 500}
zones = self.cf.zones.get(params=params) zones = self.cf.zones.get(params=params)
result = zones.get("result") if self.raw else zones result = zones.get("result") if self.raw else zones
lst_zone = [a.get("id") for a in result] lst_zone = [a.get("id") for a in result]
@ -80,12 +104,25 @@ class ManageCloudFlare:
if dns.get("content") == old_ip: if dns.get("content") == old_ip:
if delete: if delete:
_logger.info(f"Delete {dns.get('name')}") _logger.info(f"Delete {dns.get('name')}")
r = self.cf.zones.dns_records.delete(zone_id, dns.get("id")) r = self.cf.zones.dns_records.delete(
zone_id, dns.get("id")
)
elif new_ip: elif new_ip:
_logger.info(f"Update {dns.get('name')} with ip {new_ip}, old ip was {old_ip}") _logger.info(
dns_record = {'name': dns.get("name"), 'type': dns.get("type"), 'content': new_ip} f"Update {dns.get('name')} with ip {new_ip}, old"
r = self.cf.zones.dns_records.post(zone_id, data=dns_record) f" ip was {old_ip}"
r = self.cf.zones.dns_records.delete(zone_id, dns.get("id")) )
dns_record = {
"name": dns.get("name"),
"type": dns.get("type"),
"content": new_ip,
}
r = self.cf.zones.dns_records.post(
zone_id, data=dns_record
)
r = self.cf.zones.dns_records.delete(
zone_id, dns.get("id")
)
def main(): def main():
@ -99,8 +136,10 @@ def main():
else: else:
_logger.info(f"Nothing to do, same ip {actual_ip}") _logger.info(f"Nothing to do, same ip {actual_ip}")
else: else:
cl.edit_cloudflare(config.old_ip, delete=config.delete, new_ip=config.new_ip) cl.edit_cloudflare(
config.old_ip, delete=config.delete, new_ip=config.new_ip
)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -5,7 +5,7 @@ import argparse
import logging import logging
import yaml import yaml
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -24,17 +24,27 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Update version of docker ready to commit. Update version of docker ready to commit.
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"--version", required=True, help="Version of ERPLibre."
)
parser.add_argument("--base", required=True, help="Docker base name.")
parser.add_argument("--prod", required=True, help="Docker prod name.")
parser.add_argument(
"--docker_compose_file",
default="./docker-compose.yml",
help="Docker compose file to update.",
)
parser.add_argument(
"--docker_prod",
default="./docker/Dockerfile.prod.pkg",
help="Docker prod file to update.",
) )
parser.add_argument('--version', required=True, help="Version of ERPLibre.")
parser.add_argument('--base', required=True, help="Docker base name.")
parser.add_argument('--prod', required=True, help="Docker prod name.")
parser.add_argument('--docker_compose_file', default="./docker-compose.yml", help="Docker compose file to update.")
parser.add_argument('--docker_prod', default="./docker/Dockerfile.prod.pkg", help="Docker prod file to update.")
args = parser.parse_args() args = parser.parse_args()
args.base_version = f"{args.base}:{args.version}" args.base_version = f"{args.base}:{args.version}"
args.prod_version = f"{args.prod}:{args.version}" args.prod_version = f"{args.prod}:{args.version}"
@ -57,7 +67,7 @@ def get_config():
def edit_text(config): def edit_text(config):
with open(config.docker_compose_file, 'r') as f: with open(config.docker_compose_file, "r") as f:
lst_docker_info = f.readlines() lst_docker_info = f.readlines()
if not lst_docker_info: if not lst_docker_info:
@ -70,18 +80,20 @@ def edit_text(config):
if is_find: if is_find:
key = "image:" key = "image:"
value = lst_docker_info[i] value = lst_docker_info[i]
lst_docker_info[i] = f"{value[:value.find(key) + len(key)]} {config.prod_version}\n" lst_docker_info[
i
] = f"{value[:value.find(key) + len(key)]} {config.prod_version}\n"
break break
if "ERPLibre" in docker_info: if "ERPLibre" in docker_info:
is_find = True is_find = True
i += 1 i += 1
with open(config.docker_compose_file, 'w') as f: with open(config.docker_compose_file, "w") as f:
f.writelines(lst_docker_info) f.writelines(lst_docker_info)
def edit_docker_prod(config): def edit_docker_prod(config):
with open(config.docker_prod, 'r') as f: with open(config.docker_prod, "r") as f:
lst_docker_info = f.readlines() lst_docker_info = f.readlines()
if not lst_docker_info: if not lst_docker_info:
@ -94,7 +106,7 @@ def edit_docker_prod(config):
lst_docker_info[i] = f"FROM {config.base_version}\n" lst_docker_info[i] = f"FROM {config.base_version}\n"
i += 1 i += 1
with open(config.docker_prod, 'w') as f: with open(config.docker_prod, "w") as f:
f.writelines(lst_docker_info) f.writelines(lst_docker_info)
@ -104,5 +116,5 @@ def main():
edit_docker_prod(config) edit_docker_prod(config)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -8,7 +8,7 @@ from giturlparse import parse # pip install giturlparse
from retrying import retry # pip install retrying from retrying import retry # pip install retrying
import yaml # pip install PyYAML import yaml # pip install PyYAML
DEFAULT_CONFIG_FILENAME = '~/.github/fork_github_repo.yaml' DEFAULT_CONFIG_FILENAME = "~/.github/fork_github_repo.yaml"
def github_url_argument(url): def github_url_argument(url):
@ -20,11 +20,11 @@ def github_url_argument(url):
""" """
parsed_url = parse(url) parsed_url = parse(url)
if not parsed_url.valid: if not parsed_url.valid:
raise argparse.ArgumentTypeError('%s is not a valid git URL' raise argparse.ArgumentTypeError("%s is not a valid git URL" % url)
% url)
if not parsed_url.github: if not parsed_url.github:
raise argparse.ArgumentTypeError('%s is not a GitHub repo' raise argparse.ArgumentTypeError(
% parsed_url.url) "%s is not a GitHub repo" % parsed_url.url
)
return url return url
@ -41,10 +41,10 @@ def get_config():
""" """
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Fork a GitHub repo, clone that repo to a local directory, add the upstream Fork a GitHub repo, clone that repo to a local directory, add the upstream
remote, create an optional feature branch and checkout that branch''', remote, create an optional feature branch and checkout that branch""",
epilog='''\ epilog="""\
The config file with a default location of The config file with a default location of
~/.github/fork_github_repo.yaml contains the following settings: ~/.github/fork_github_repo.yaml contains the following settings:
@ -59,27 +59,40 @@ The file is YAML formatted and the contents look like this :
github_token: 0123456789abcdef0123456789abcdef01234567 github_token: 0123456789abcdef0123456789abcdef01234567
repo_dir: ~/Documents/github.com/example/ repo_dir: ~/Documents/github.com/example/
organization: organization:
''' """,
) )
parser.add_argument( parser.add_argument(
'-c', '--config', "-c",
help='Filename of the yaml config file (default : %s)' "--config",
% DEFAULT_CONFIG_FILENAME, help="Filename of the yaml config file (default : %s)"
% DEFAULT_CONFIG_FILENAME,
default=filename_argument(DEFAULT_CONFIG_FILENAME), default=filename_argument(DEFAULT_CONFIG_FILENAME),
type=filename_argument) type=filename_argument,
parser.add_argument('url', help="GitHub URL of the upstream repo to fork", )
type=github_url_argument) parser.add_argument(
parser.add_argument('branch', nargs='?', default=None, "url",
help="Name of the feature branch to create") help="GitHub URL of the upstream repo to fork",
type=github_url_argument,
)
parser.add_argument(
"branch",
nargs="?",
default=None,
help="Name of the feature branch to create",
)
args = parser.parse_args() args = parser.parse_args()
if (args.config == filename_argument(DEFAULT_CONFIG_FILENAME)) and ( if (args.config == filename_argument(DEFAULT_CONFIG_FILENAME)) and (
not os.path.isfile(args.config)): not os.path.isfile(args.config)
parser.error('Please create a config file at %s or point to one with ' ):
'the --config option.' % DEFAULT_CONFIG_FILENAME) parser.error(
"Please create a config file at %s or point to one with "
"the --config option." % DEFAULT_CONFIG_FILENAME
)
if not os.path.isfile(args.config): if not os.path.isfile(args.config):
raise argparse.ArgumentTypeError( raise argparse.ArgumentTypeError(
'Could not find config file %s.' % args.config) "Could not find config file %s." % args.config
with open(args.config, 'r') as f: )
with open(args.config, "r") as f:
try: try:
config = yaml.safe_load(f) config = yaml.safe_load(f)
if isinstance(config, dict): if isinstance(config, dict):
@ -88,10 +101,12 @@ organization:
else: else:
raise argparse.ArgumentTypeError( raise argparse.ArgumentTypeError(
'Config contains %s of "%s" but it should be a dict' 'Config contains %s of "%s" but it should be a dict'
% (type(config), config)) % (type(config), config)
)
except yaml.YAMLError: except yaml.YAMLError:
raise argparse.ArgumentTypeError( raise argparse.ArgumentTypeError(
'Could not parse YAML in %s' % args.config) "Could not parse YAML in %s" % args.config
)
def get_list_fork_repo(upstream_url, github_token): def get_list_fork_repo(upstream_url, github_token):
@ -105,9 +120,15 @@ def get_list_fork_repo(upstream_url, github_token):
def fork_and_clone_repo( def fork_and_clone_repo(
upstream_url, github_token, repo_dir_root, branch_name=None, upstream_url,
upstream_name='upstream', organization_name=None, fork_only=False, github_token,
repo_root=None): repo_dir_root,
branch_name=None,
upstream_name="upstream",
organization_name=None,
fork_only=False,
repo_root=None,
):
"""Fork a GitHub repo, clone that repo to a local directory, """Fork a GitHub repo, clone that repo to a local directory,
add the upstream remote, create an optional feature branch and checkout add the upstream remote, create an optional feature branch and checkout
that branch that branch
@ -130,26 +151,28 @@ def fork_and_clone_repo(
# Fork the repo # Fork the repo
status, user = gh.user.get() status, user = gh.user.get()
user_name = user['login'] if not organization_name else organization_name user_name = user["login"] if not organization_name else organization_name
status, forked_repo = gh.repos[user_name][parsed_url.repo].get() status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
if status == 404: if status == 404:
status, upstream_repo = ( status, upstream_repo = gh.repos[parsed_url.owner][
gh.repos[parsed_url.owner][parsed_url.repo].get()) parsed_url.repo
].get()
if status == 404: if status == 404:
print("Unable to find repo %s" % upstream_url) print("Unable to find repo %s" % upstream_url)
exit(1) exit(1)
args = {} args = {}
if organization_name: if organization_name:
args["organization"] = organization_name args["organization"] = organization_name
status, forked_repo = ( status, forked_repo = gh.repos[parsed_url.owner][
gh.repos[parsed_url.owner][parsed_url.repo].forks.post(**args)) parsed_url.repo
].forks.post(**args)
if status == 404: if status == 404:
print("Error when forking repo %s" % forked_repo) print("Error when forking repo %s" % forked_repo)
exit(1) exit(1)
else: else:
print("Forked %s to %s" % (upstream_url, forked_repo['html_url'])) print("Forked %s to %s" % (upstream_url, forked_repo["html_url"]))
elif status == 202: elif status == 202:
print("Forked repo %s already exists" % forked_repo['full_name']) print("Forked repo %s already exists" % forked_repo["full_name"])
elif status != 200: elif status != 200:
print("Status not supported: %s - %s" % (status, forked_repo)) print("Status not supported: %s - %s" % (status, forked_repo))
exit(1) exit(1)
@ -166,24 +189,30 @@ def fork_and_clone_repo(
try: try:
if branch_name: if branch_name:
submodule_repo = retry( submodule_repo = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000 )(repo_root.create_submodule)(
)(repo_root.create_submodule)(repo_dir_root, repo_dir_root, repo_dir_root,
url=http_url, repo_dir_root,
branch=branch_name) url=http_url,
branch=branch_name,
)
else: else:
submodule_repo = retry( submodule_repo = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000 )(repo_root.create_submodule)(
)(repo_root.create_submodule)(repo_dir_root, repo_dir_root, repo_dir_root, repo_dir_root, url=http_url
url=http_url) )
except KeyError as e: except KeyError as e:
if os.path.isdir(repo_dir_root): if os.path.isdir(repo_dir_root):
print(f"Warning, submodule {repo_dir_root} already exist, " print(
f"you need to add it in stage.") f"Warning, submodule {repo_dir_root} already exist, "
"you need to add it in stage."
)
else: else:
print(f"\nERROR Cannot create submodule {repo_dir_root}." print(
f"Maybe you need to delete .git/modules/{repo_dir_root}\n") f"\nERROR Cannot create submodule {repo_dir_root}."
f"Maybe you need to delete .git/modules/{repo_dir_root}\n"
)
return return
# # Delete appropriate submodule and recreate_submodule # # Delete appropriate submodule and recreate_submodule
# shutil.rmtree(f".git/modules/{repo_dir_root}", ignore_errors=True) # shutil.rmtree(f".git/modules/{repo_dir_root}", ignore_errors=True)
@ -219,14 +248,15 @@ def fork_and_clone_repo(
# url=bare_repo.git_dir, branch='master') # url=bare_repo.git_dir, branch='master')
else: else:
if os.path.isdir(repo_dir): if os.path.isdir(repo_dir):
print("Directory %s already exists, assuming it's a clone" % repo_dir) print(
"Directory %s already exists, assuming it's a clone" % repo_dir
)
cloned_repo = Repo(repo_dir) cloned_repo = Repo(repo_dir)
else: else:
cloned_repo = retry( cloned_repo = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000 )(Repo.clone_from)(forked_repo["ssh_url"], repo_dir)
)(Repo.clone_from)(forked_repo['ssh_url'], repo_dir) print("Cloned %s to %s" % (forked_repo["ssh_url"], repo_dir))
print("Cloned %s to %s" % (forked_repo['ssh_url'], repo_dir))
# Create the remote upstream # Create the remote upstream
try: try:
@ -234,14 +264,14 @@ def fork_and_clone_repo(
print('Remote "%s" already exists in %s' % (upstream_name, repo_dir)) print('Remote "%s" already exists in %s' % (upstream_name, repo_dir))
except ValueError: except ValueError:
upstream_remote = retry( upstream_remote = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000
)(cloned_repo.create_remote)(upstream_name, upstream_url) )(cloned_repo.create_remote)(upstream_name, upstream_url)
print('Remote "%s" created for %s' % (upstream_name, upstream_url)) print('Remote "%s" created for %s' % (upstream_name, upstream_url))
# Fetch the remote upstream # Fetch the remote upstream
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
upstream_remote.fetch)() upstream_remote.fetch
)()
print('Remote "%s" fetched' % upstream_name) print('Remote "%s" fetched' % upstream_name)
# Create and checkout the branch # Create and checkout the branch
@ -255,19 +285,25 @@ def fork_and_clone_repo(
branch = cloned_repo.heads[branch_name] branch = cloned_repo.heads[branch_name]
print('Branch "%s" already exists' % branch_name) print('Branch "%s" already exists' % branch_name)
if branch_name not in cloned_repo.remotes.origin.refs: if branch_name not in cloned_repo.remotes.origin.refs:
cloned_repo.remotes.origin.push(refspec='{}:{}'.format( cloned_repo.remotes.origin.push(
branch.path, branch.path)) refspec="{}:{}".format(branch.path, branch.path)
)
print('Branch "%s" pushed to origin' % branch_name) print('Branch "%s" pushed to origin' % branch_name)
else: else:
print('Branch "%s" already exists in remote origin' % branch_name) print('Branch "%s" already exists in remote origin' % branch_name)
if branch.tracking_branch() is None: if branch.tracking_branch() is None:
branch.set_tracking_branch( branch.set_tracking_branch(
cloned_repo.remotes.origin.refs[branch_name]) cloned_repo.remotes.origin.refs[branch_name]
print('Tracking branch "%s" setup for branch "%s"' % ( )
cloned_repo.remotes.origin.refs[branch_name], branch_name)) print(
'Tracking branch "%s" setup for branch "%s"'
% (cloned_repo.remotes.origin.refs[branch_name], branch_name)
)
else: else:
print('Branch "%s" already setup to track "%s"' % ( print(
branch_name, cloned_repo.remotes.origin.refs[branch_name])) 'Branch "%s" already setup to track "%s"'
% (branch_name, cloned_repo.remotes.origin.refs[branch_name])
)
branch.checkout() branch.checkout()
print('Branch "%s" checked out' % branch_name) print('Branch "%s" checked out' % branch_name)
return branch return branch

View file

@ -6,7 +6,7 @@ import logging
from git import Repo from git import Repo
from retrying import retry # pip install retrying from retrying import retry # pip install retrying
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script import fork_github_repo from script import fork_github_repo
@ -27,18 +27,30 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"--organization",
dest="organization",
default="ERPLibre",
help="Choose organization to fork and change all repo.",
)
parser.add_argument(
"--github_token",
dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('--organization', dest="organization", default="ERPLibre",
help="Choose organization to fork and change all repo.")
parser.add_argument('--github_token', dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -76,21 +88,28 @@ def main():
# for remote in working_repo.remotes: # for remote in working_repo.remotes:
if remote_origin: if remote_origin:
repo_origin_info = GitTool.get_transformed_repo_info_from_url( repo_origin_info = GitTool.get_transformed_repo_info_from_url(
remote_origin.url, repo_path=repo.get("relative_path")) remote_origin.url, repo_path=repo.get("relative_path")
)
if repo_origin_info.organization not in dct_remote_name.keys(): if repo_origin_info.organization not in dct_remote_name.keys():
# Add remote # Add remote
upstream_remote = retry( upstream_remote = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000 )(working_repo.create_remote)(
)(working_repo.create_remote)(repo_origin_info.organization, repo_origin_info.organization, repo_origin_info.url_https
repo_origin_info.url_https) )
print('Remote "%s" created for %s' % ( print(
repo_origin_info.organization, repo_origin_info.url_https)) 'Remote "%s" created for %s'
% (
repo_origin_info.organization,
repo_origin_info.url_https,
)
)
# Fetch the remote # Fetch the remote
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
upstream_remote.fetch)() upstream_remote.fetch
)()
print('Remote "%s" fetched' % repo_origin_info.organization) print('Remote "%s" fetched' % repo_origin_info.organization)
# working_repo.git.remote.remove("origin") # working_repo.git.remote.remove("origin")
upstream_name = organization_name upstream_name = organization_name
@ -99,7 +118,9 @@ def main():
# [<git.Remote "origin">, <git.Remote "upstream">, <git.Remote "MathBenTech">] # [<git.Remote "origin">, <git.Remote "upstream">, <git.Remote "MathBenTech">]
_logger.info( _logger.info(
f"Fork {url} on dir {repo_dir_root} for organization {organization_name}") f"Fork {url} on dir {repo_dir_root} for organization"
f" {organization_name}"
)
fork_github_repo.fork_and_clone_repo( fork_github_repo.fork_and_clone_repo(
url, url,
@ -117,5 +138,5 @@ def main():
GitTool().generate_install_locally() GitTool().generate_install_locally()
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -6,7 +6,7 @@ import logging
from git import Repo from git import Repo
import git import git
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -26,24 +26,41 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"--organization",
dest="organization",
default="ERPLibre",
help="Choose organization to fork and change all repo.",
)
parser.add_argument(
"--skip_fork",
action="store_true",
help="Ignore fork to generate only manifest.",
)
parser.add_argument(
"-f", "--force", action="store_true", help="Force rewrite remote."
)
parser.add_argument(
"--fast", action="store_true", help="Ignore if repo already exist."
)
parser.add_argument(
"--github_token",
dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('--organization', dest="organization", default="ERPLibre",
help="Choose organization to fork and change all repo.")
parser.add_argument("--skip_fork", action="store_true",
help="Ignore fork to generate only manifest.")
parser.add_argument('-f', "--force", action="store_true",
help="Force rewrite remote.")
parser.add_argument("--fast", action="store_true",
help="Ignore if repo already exist.")
parser.add_argument('--github_token', dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -58,12 +75,21 @@ def main():
raise ValueError("Missing github_token") raise ValueError("Missing github_token")
organization_name = config.organization organization_name = config.organization
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True) lst_repo = git_tool.get_source_repo_addons(
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url( repo_path=config.dir, add_repo_root=True
a.get("url"), repo_path=config.dir, organization_force=organization_name, )
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"), lst_repo_organization = [
revision=a.get("revision"), clone_depth=a.get("clone_depth")) git_tool.get_transformed_repo_info_from_url(
for a in lst_repo] a.get("url"),
repo_path=config.dir,
organization_force=organization_name,
is_submodule=a.get("is_submodule"),
sub_path=a.get("sub_path"),
revision=a.get("revision"),
clone_depth=a.get("clone_depth"),
)
for a in lst_repo
]
if not config.skip_fork: if not config.skip_fork:
i = 0 i = 0
@ -71,7 +97,11 @@ def main():
for repo in lst_repo: for repo in lst_repo:
i += 1 i += 1
print(f"Nb element {i}/{total} - {repo.get('project_name')}") print(f"Nb element {i}/{total} - {repo.get('project_name')}")
if config.fast and repo.get("is_submodule") and os.path.isdir(repo.get("path")): if (
config.fast
and repo.get("is_submodule")
and os.path.isdir(repo.get("path"))
):
continue continue
url = repo.get("url") url = repo.get("url")
@ -83,16 +113,22 @@ def main():
# url, organization_force="ERPLibre", # url, organization_force="ERPLibre",
# is_submodule=repo.get("is_submodule"), # is_submodule=repo.get("is_submodule"),
# sub_path=repo.get("sub_path")) # sub_path=repo.get("sub_path"))
git_tool.fork_repo(upstream_url=url, git_tool.fork_repo(
github_token=github_token, upstream_url=url,
organization_name="ERPLibre") github_token=github_token,
organization_name="ERPLibre",
)
repo_info = git_tool.get_transformed_repo_info_from_url( repo_info = git_tool.get_transformed_repo_info_from_url(
url, organization_force=organization_name, url,
organization_force=organization_name,
is_submodule=repo.get("is_submodule"), is_submodule=repo.get("is_submodule"),
sub_path=repo.get("sub_path")) sub_path=repo.get("sub_path"),
git_tool.fork_repo(upstream_url=url, )
github_token=github_token, git_tool.fork_repo(
organization_name=organization_name) upstream_url=url,
github_token=github_token,
organization_name=organization_name,
)
# git_tool.add_and_fetch_remote(repo_info, root_repo=root_repo) # git_tool.add_and_fetch_remote(repo_info, root_repo=root_repo)
continue continue
@ -104,18 +140,25 @@ def main():
if not remote_erplibre: if not remote_erplibre:
repo_info = git_tool.get_transformed_repo_info_from_url( repo_info = git_tool.get_transformed_repo_info_from_url(
url, organization_force="ERPLibre", url,
organization_force="ERPLibre",
is_submodule=repo.get("is_submodule"), is_submodule=repo.get("is_submodule"),
sub_path=repo.get("sub_path")) sub_path=repo.get("sub_path"),
)
# git_tool.add_and_fetch_remote(repo_info) # git_tool.add_and_fetch_remote(repo_info)
git_tool.fork_repo(url, github_token, git_tool.fork_repo(
organization_name=organization_name, url,
) github_token,
organization_name=organization_name,
)
repo_info = git_tool.get_transformed_repo_info_from_url( repo_info = git_tool.get_transformed_repo_info_from_url(
url, organization_force=organization_name, url,
is_submodule=repo.get("is_submodule"), sub_path=repo.get("sub_path")) organization_force=organization_name,
is_submodule=repo.get("is_submodule"),
sub_path=repo.get("sub_path"),
)
if remote_origin: if remote_origin:
working_repo.git.remote("remove", "origin") working_repo.git.remote("remove", "origin")
repo_info.organization = "origin" repo_info.organization = "origin"
@ -131,10 +174,11 @@ def main():
# Update origin to new repo # Update origin to new repo
# git_tool.generate_git_modules(lst_repo_organization, repo_path=config.dir) # git_tool.generate_git_modules(lst_repo_organization, repo_path=config.dir)
git_tool.generate_repo_manifest(lst_repo_organization, git_tool.generate_repo_manifest(
output=f"{config.dir}manifest/default.dev.xml") lst_repo_organization, output=f"{config.dir}manifest/default.dev.xml"
)
git_tool.generate_install_locally() git_tool.generate_install_locally()
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -7,7 +7,7 @@ from git import Repo
from retrying import retry # pip install retrying from retrying import retry # pip install retrying
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script import git_tool from script import git_tool
@ -27,28 +27,51 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"--github_token",
dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user",
)
parser.add_argument(
"--open_web_browser",
action="store_true",
help="Open web browser for each repo.",
)
parser.add_argument(
"--generate_only_install_locally",
action="store_true",
help="Only generate script install_locally.sh.",
)
parser.add_argument(
"--sync_to",
dest="sync_to",
help="Only synchronize matching repo, use path compare to repo.",
)
parser.add_argument(
"--dry_sync",
dest="dry_sync",
action="store_true",
help="Don't apply modification when sync_to.",
)
parser.add_argument(
"--sync_with_submodule",
dest="sync_with_submodule",
action="store_true",
help="Remote directory use submodule to sync.",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('--github_token', dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user")
parser.add_argument("--open_web_browser", action="store_true",
help="Open web browser for each repo.")
parser.add_argument("--generate_only_install_locally", action="store_true",
help="Only generate script install_locally.sh.")
parser.add_argument("--sync_to", dest="sync_to",
help="Only synchronize matching repo, use path compare to "
"repo.")
parser.add_argument("--dry_sync", dest="dry_sync", action="store_true",
help="Don't apply modification when sync_to.")
parser.add_argument("--sync_with_submodule", dest="sync_with_submodule",
action="store_true",
help="Remote directory use submodule to sync.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -68,9 +91,11 @@ def main():
if config.sync_to[-1] != "/": if config.sync_to[-1] != "/":
config.sync_to += "/" config.sync_to += "/"
gt = git_tool.GitTool() gt = git_tool.GitTool()
result = gt.get_matching_repo(repo_compare_to=config.sync_to, result = gt.get_matching_repo(
force_normalize_compare=True, repo_compare_to=config.sync_to,
sync_with_submodule=config.sync_with_submodule) force_normalize_compare=True,
sync_with_submodule=config.sync_with_submodule,
)
gt.sync_to(result, checkout_when_diff=not config.dry_sync) gt.sync_to(result, checkout_when_diff=not config.dry_sync)
return return
@ -109,28 +134,34 @@ def main():
# # print(f"ERROR, missing branch 12.0 for {repo_dir_root}") # # print(f"ERROR, missing branch 12.0 for {repo_dir_root}")
_logger.info( _logger.info(
f"Fork {url} on dir {repo_dir_root} for organization {organization_name}") f"Fork {url} on dir {repo_dir_root} for organization"
f" {organization_name}"
)
try: try:
upstream_remote = cloned_repo.remote(upstream_name) upstream_remote = cloned_repo.remote(upstream_name)
print('Remote "%s" already exists in %s' % print(
(upstream_name, repo_dir_root)) 'Remote "%s" already exists in %s'
% (upstream_name, repo_dir_root)
)
except ValueError: except ValueError:
upstream_remote = retry( upstream_remote = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000
)(cloned_repo.create_remote)(upstream_name, upstream_url) )(cloned_repo.create_remote)(upstream_name, upstream_url)
print('Remote "%s" created for %s' % (upstream_name, upstream_url)) print('Remote "%s" created for %s' % (upstream_name, upstream_url))
try: try:
# Fetch the remote upstream # Fetch the remote upstream
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
upstream_remote.fetch)() upstream_remote.fetch
)()
print('Remote "%s" fetched' % upstream_name) print('Remote "%s" fetched' % upstream_name)
except Exception: except Exception:
print(f"ERROR git {repo_dir_root} remote {upstream_name} not exist.") print(
f"ERROR git {repo_dir_root} remote {upstream_name} not exist."
)
upstream_remote.remove(cloned_repo, upstream_name) upstream_remote.remove(cloned_repo, upstream_name)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -9,7 +9,7 @@ import sys
from git import Repo from git import Repo
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -27,18 +27,32 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"-f",
"--upstream",
dest="upstream",
help=(
"Upstream name to change address https to git. "
"When empty, all upstream is updated."
),
)
parser.add_argument(
"--git_to_https",
action="store_true",
help="Replace all repo git to https.",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('-f', '--upstream', dest="upstream",
help="Upstream name to change address https to git. "
"When empty, all upstream is updated.")
parser.add_argument("--git_to_https", action="store_true",
help="Replace all repo git to https.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -61,8 +75,9 @@ def main():
continue continue
repo_sm = Repo(repo_name) repo_sm = Repo(repo_name)
if upstream_name: if upstream_name:
remote_upstream_name = [a for a in repo_sm.remotes remote_upstream_name = [
if upstream_name == a.name] a for a in repo_sm.remotes if upstream_name == a.name
]
else: else:
remote_upstream_name = [a for a in repo_sm.remotes] remote_upstream_name = [a for a in repo_sm.remotes]
@ -73,5 +88,5 @@ def main():
print(f'Remote "{remote.name}" update for {new_url}') print(f'Remote "{remote.name}" update for {new_url}')
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -5,7 +5,7 @@ import argparse
import logging import logging
from git import Repo from git import Repo
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -24,13 +24,19 @@ def get_config():
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Get git diff between manifest repo revision, description="""Get git diff between manifest repo revision,
diff revision input1 to input2 """, diff revision input1 to input2 """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"--input1",
required=True,
help="Compare input1 to input2. Input1 is older config.",
)
parser.add_argument(
"--input2",
required=True,
help="Compare input1 to input2. Input2 is newer config.",
) )
parser.add_argument('--input1', required=True,
help="Compare input1 to input2. Input1 is older config.")
parser.add_argument('--input2', required=True,
help="Compare input1 to input2. Input2 is newer config.")
# parser.add_argument('--clear', action="store_true", # parser.add_argument('--clear', action="store_true",
# help="Create a new manifest and clear old configuration.") # help="Create a new manifest and clear old configuration.")
args = parser.parse_args() args = parser.parse_args()
@ -41,10 +47,16 @@ def main():
config = get_config() config = get_config()
git_tool = GitTool() git_tool = GitTool()
dct_remote_1, dct_project_1, default_remote_1 = git_tool.get_manifest_xml_info( (
filename=config.input1, add_root=True) dct_remote_1,
dct_remote_2, dct_project_2, default_remote_2 = git_tool.get_manifest_xml_info( dct_project_1,
filename=config.input2, add_root=True) default_remote_1,
) = git_tool.get_manifest_xml_info(filename=config.input1, add_root=True)
(
dct_remote_2,
dct_project_2,
default_remote_2,
) = git_tool.get_manifest_xml_info(filename=config.input2, add_root=True)
set_project_1 = set(dct_project_1.keys()) set_project_1 = set(dct_project_1.keys())
set_project_2 = set(dct_project_2.keys()) set_project_2 = set(dct_project_2.keys())
@ -75,14 +87,18 @@ def main():
path1 = value1.get("@path") path1 = value1.get("@path")
path2 = value2.get("@path") path2 = value2.get("@path")
if path1 != path2: if path1 != path2:
print(f"WARNING id {i}, path of git are different. " print(
f"Input1 {path1}, input2 {path2}") f"WARNING id {i}, path of git are different. "
f"Input1 {path1}, input2 {path2}"
)
continue continue
i += 1 i += 1
result = "same" if old_revision == new_revision else "diff" result = "same" if old_revision == new_revision else "diff"
print(f"{i}/{total} - {result} - " print(
f"{path1} {key} old {old_revision} new {new_revision}") f"{i}/{total} - {result} - "
f"{path1} {key} old {old_revision} new {new_revision}"
)
default_arg = [f"{old_revision}..{new_revision}"] default_arg = [f"{old_revision}..{new_revision}"]
if old_revision != new_revision: if old_revision != new_revision:
# get git diff # get git diff
@ -91,5 +107,5 @@ def main():
print(status) print(status)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -5,7 +5,7 @@ import argparse
import logging import logging
import copy import copy
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -23,15 +23,18 @@ def get_config():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Replace revision field in input2 from input1 if existing, create an output of new manifest.""", description="""Replace revision field in input2 from input1 if existing, create an output of new manifest.""",
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"--input1", required=True, help="First manifest to merge into input2."
)
parser.add_argument(
"--input2", required=True, help="Second manifest, overwrite by input1."
)
parser.add_argument(
"--output", required=True, help="Output of new manifest"
) )
parser.add_argument('--input1', required=True,
help="First manifest to merge into input2.")
parser.add_argument('--input2', required=True,
help="Second manifest, overwrite by input1.")
parser.add_argument('--output', required=True,
help="Output of new manifest")
# parser.add_argument('--clear', action="store_true", # parser.add_argument('--clear', action="store_true",
# help="Create a new manifest and clear old configuration.") # help="Create a new manifest and clear old configuration.")
args = parser.parse_args() args = parser.parse_args()
@ -42,10 +45,16 @@ def main():
config = get_config() config = get_config()
git_tool = GitTool() git_tool = GitTool()
dct_remote_1, dct_project_1, default_remote_1 = git_tool.get_manifest_xml_info( (
filename=config.input1, add_root=True) dct_remote_1,
dct_remote_2, dct_project_2, default_remote_2 = git_tool.get_manifest_xml_info( dct_project_1,
filename=config.input2, add_root=True) default_remote_1,
) = git_tool.get_manifest_xml_info(filename=config.input1, add_root=True)
(
dct_remote_2,
dct_project_2,
default_remote_2,
) = git_tool.get_manifest_xml_info(filename=config.input2, add_root=True)
dct_remote_3 = copy.deepcopy(dct_remote_2) dct_remote_3 = copy.deepcopy(dct_remote_2)
dct_project_3 = copy.deepcopy(dct_project_2) dct_project_3 = copy.deepcopy(dct_project_2)
@ -59,10 +68,13 @@ def main():
dct_project_3[key]["@dest-branch"] = "12.0" dct_project_3[key]["@dest-branch"] = "12.0"
# Update origin to new repo # Update origin to new repo
git_tool.generate_repo_manifest(dct_remote=dct_remote_3, dct_project=dct_project_3, git_tool.generate_repo_manifest(
output=config.output, dct_remote=dct_remote_3,
default_remote=default_remote_2) dct_project=dct_project_3,
output=config.output,
default_remote=default_remote_2,
)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -4,7 +4,7 @@ import sys
import argparse import argparse
import logging import logging
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -21,17 +21,29 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"--clear",
action="store_true",
help="Create a new manifest and clear old configuration.",
)
parser.add_argument(
"-m",
"--manifest",
default="manifest/default.dev.xml",
help="The manifest file path to generate.",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('--clear', action="store_true",
help="Create a new manifest and clear old configuration.")
parser.add_argument('-m', '--manifest', default="manifest/default.dev.xml",
help="The manifest file path to generate.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -40,26 +52,39 @@ def main():
config = get_config() config = get_config()
git_tool = GitTool() git_tool = GitTool()
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True) lst_repo = git_tool.get_source_repo_addons(
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url( repo_path=config.dir, add_repo_root=True
a.get("url"), repo_path=config.dir, get_obj=True, )
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"), lst_repo_organization = [
revision=a.get("revision"), clone_depth=a.get("clone_depth")) git_tool.get_transformed_repo_info_from_url(
for a in lst_repo] a.get("url"),
repo_path=config.dir,
get_obj=True,
is_submodule=a.get("is_submodule"),
sub_path=a.get("sub_path"),
revision=a.get("revision"),
clone_depth=a.get("clone_depth"),
)
for a in lst_repo
]
# Update origin to new repo # Update origin to new repo
if not config.clear: if not config.clear:
dct_remote, dct_project, _ = git_tool.get_manifest_xml_info( dct_remote, dct_project, _ = git_tool.get_manifest_xml_info(
repo_path=config.dir, add_root=True) repo_path=config.dir, add_root=True
)
else: else:
dct_remote = {} dct_remote = {}
dct_project = {} dct_project = {}
git_tool.generate_repo_manifest(lst_repo_organization, git_tool.generate_repo_manifest(
output=f"{config.dir}{config.manifest}", lst_repo_organization,
dct_remote=dct_remote, dct_project=dct_project, output=f"{config.dir}{config.manifest}",
keep_original=True) dct_remote=dct_remote,
dct_project=dct_project,
keep_original=True,
)
git_tool.generate_install_locally() git_tool.generate_install_locally()
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -6,7 +6,7 @@ import logging
from git import Repo from git import Repo
import git import git
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -25,14 +25,17 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Update config.conf file with group specified in manifest file. Update config.conf file with group specified in manifest file.
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"--group",
default="",
help="Prod by default, use 'dev' for manifest/default.dev.xml",
) )
parser.add_argument('--group', default="",
help="Prod by default, use 'dev' for manifest/default.dev.xml")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -46,5 +49,5 @@ def main():
git_tool.generate_install_locally(filter_group=filter_group) git_tool.generate_install_locally(filter_group=filter_group)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -6,7 +6,7 @@ import logging
from git import Repo from git import Repo
from git.exc import GitCommandError from git.exc import GitCommandError
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -24,11 +24,15 @@ def get_config():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description="""Compare actual code with a manifest.""", description="""Compare actual code with a manifest.""",
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-m",
"--manifest",
required=True,
help="The manifest to compare with actual code.",
) )
parser.add_argument('-m', '--manifest', required=True,
help="The manifest to compare with actual code.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -37,8 +41,12 @@ def main():
config = get_config() config = get_config()
git_tool = GitTool() git_tool = GitTool()
dct_remote, dct_project, default_remote = git_tool.get_manifest_xml_info(filename=config.manifest, add_root=True) dct_remote, dct_project, default_remote = git_tool.get_manifest_xml_info(
default_branch_name = default_remote.get("@revision", git_tool.default_branch) filename=config.manifest, add_root=True
)
default_branch_name = default_remote.get(
"@revision", git_tool.default_branch
)
i = 0 i = 0
total = len(dct_project) total = len(dct_project)
for name, project in dct_project.items(): for name, project in dct_project.items():
@ -57,7 +65,9 @@ def main():
# TODO maybe need to check divergence with local branch and not remote branch # TODO maybe need to check divergence with local branch and not remote branch
commit_head = git_repo.git.rev_parse("HEAD") commit_head = git_repo.git.rev_parse("HEAD")
try: try:
commit_branch = git_repo.git.rev_parse(f"{organization}/{branch_name}") commit_branch = git_repo.git.rev_parse(
f"{organization}/{branch_name}"
)
except GitCommandError: except GitCommandError:
print("ERROR Something wrong with this repo.") print("ERROR Something wrong with this repo.")
continue continue
@ -66,10 +76,13 @@ def main():
else: else:
print("PASS Not on specified branch, no divergence.") print("PASS Not on specified branch, no divergence.")
elif branch_name != value: elif branch_name != value:
print(f"ERROR, manifest revision is {branch_name} and actual revision is {value}.") print(
f"ERROR, manifest revision is {branch_name} and actual"
f" revision is {value}."
)
else: else:
print("PASS") print("PASS")
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -59,13 +59,17 @@ class GitTool:
return url, url_https, url_git return url, url_https, url_git
def get_transformed_repo_info_from_url(self, url: str, repo_path: str = "./", def get_transformed_repo_info_from_url(
get_obj: bool = True, self,
is_submodule: bool = True, url: str,
organization_force: str = None, repo_path: str = "./",
sub_path: str = "addons", get_obj: bool = True,
revision: str = "", is_submodule: bool = True,
clone_depth: str = "") -> object: organization_force: str = None,
sub_path: str = "addons",
revision: str = "",
clone_depth: str = "",
) -> object:
""" """
:param url: :param url:
@ -99,8 +103,8 @@ class GitTool:
relative_path = os.path.normpath(relative_path) relative_path = os.path.normpath(relative_path)
original_organization = organization original_organization = organization
url_https_original_organization = url_https[:url_https.rfind("/")] url_https_original_organization = url_https[: url_https.rfind("/")]
project_name = url_https[url_https.rfind("/") + 1:] project_name = url_https[url_https.rfind("/") + 1 :]
# begin_original = url_git[url_git.find(":") + 1:] # begin_original = url_git[url_git.find(":") + 1:]
# original_organization = begin_original[:begin_original.find("/")] # original_organization = begin_original[:begin_original.find("/")]
if organization_force: if organization_force:
@ -109,7 +113,7 @@ class GitTool:
url_split[3] = organization url_split[3] = organization
url_https = "/".join(url_split) url_https = "/".join(url_split)
url, _, url_git = self.get_url(url_https) url, _, url_git = self.get_url(url_https)
url_https_organization = url_https[:url_https.rfind("/")] url_https_organization = url_https[: url_https.rfind("/")]
d = { d = {
"url": url, "url": url,
@ -132,15 +136,26 @@ class GitTool:
return Struct(**d) return Struct(**d)
return d return d
def get_repo_info(self, repo_path: str = "./", def get_repo_info(
add_root: bool = False, is_manifest: bool = True, filter_group=None): self,
repo_path: str = "./",
add_root: bool = False,
is_manifest: bool = True,
filter_group=None,
):
if is_manifest: if is_manifest:
return self.get_repo_info_manifest_xml(repo_path=repo_path, return self.get_repo_info_manifest_xml(
add_root=add_root, filter_group=filter_group) repo_path=repo_path,
return self.get_repo_info_submodule(repo_path=repo_path, add_root=add_root) add_root=add_root,
filter_group=filter_group,
)
return self.get_repo_info_submodule(
repo_path=repo_path, add_root=add_root
)
def get_repo_info_submodule(self, repo_path: str = "./", def get_repo_info_submodule(
add_root: bool = False) -> list: self, repo_path: str = "./", add_root: bool = False
) -> list:
""" """
Get information about submodule from repo_path Get information about submodule from repo_path
:param repo_path: path of repo to get information about submodule :param repo_path: path of repo to get information about submodule
@ -166,7 +181,7 @@ class GitTool:
first_execution = True first_execution = True
for line in txt: for line in txt:
no_line += 1 no_line += 1
if line[:12] == "[submodule \"": if line[:12] == '[submodule "':
if not first_execution: if not first_execution:
data = { data = {
"url": url, "url": url,
@ -220,8 +235,9 @@ class GitTool:
lst_repo = sorted(lst_repo, key=lambda k: k.get("name")) lst_repo = sorted(lst_repo, key=lambda k: k.get("name"))
return lst_repo return lst_repo
def get_repo_info_manifest_xml(self, repo_path: str = "./", def get_repo_info_manifest_xml(
add_root: bool = False, filter_group=None) -> list: self, repo_path: str = "./", add_root: bool = False, filter_group=None
) -> list:
""" """
Get information about manifest of Repo from repo_path Get information about manifest of Repo from repo_path
:param repo_path: path of repo to get information about submodule :param repo_path: path of repo to get information about submodule
@ -255,7 +271,7 @@ class GitTool:
dct_remote = {a.get("@name"): a.get("@fetch") for a in lst_remote} dct_remote = {a.get("@name"): a.get("@fetch") for a in lst_remote}
for project in lst_project: for project in lst_project:
groups = project.get("@groups") groups = project.get("@groups")
lst_group = groups.split(',') if groups else [] lst_group = groups.split(",") if groups else []
# Continue if lst_filter exist and group in filter # Continue if lst_filter exist and group in filter
for group in lst_group: for group in lst_group:
if lst_filter_group and group not in lst_filter_group: if lst_filter_group and group not in lst_filter_group:
@ -290,9 +306,11 @@ class GitTool:
try: try:
url = repo_root.git.remote("get-url", "origin") url = repo_root.git.remote("get-url", "origin")
except Exception as e: except Exception as e:
print(f"WARNING: Missing origin remote, use default url " print(
f"{DEFAULT_REMOTE_URL}. Suggest to add a remote origin: \n" "WARNING: Missing origin remote, use default url "
f"> git remote add origin {DEFAULT_REMOTE_URL}") f"{DEFAULT_REMOTE_URL}. Suggest to add a remote origin: \n"
f"> git remote add origin {DEFAULT_REMOTE_URL}"
)
url = DEFAULT_REMOTE_URL url = DEFAULT_REMOTE_URL
url, url_https, url_git = self.get_url(url) url, url_https, url_git = self.get_url(url)
@ -308,8 +326,9 @@ class GitTool:
lst_repo = sorted(lst_repo, key=lambda k: k.get("name")) lst_repo = sorted(lst_repo, key=lambda k: k.get("name"))
return lst_repo return lst_repo
def get_manifest_xml_info(self, repo_path: str = "./", filename=None, def get_manifest_xml_info(
add_root: bool = False) -> list: self, repo_path: str = "./", filename=None, add_root: bool = False
) -> list:
""" """
Get contain of manifest Get contain of manifest
:param repo_path: path of repo to get information about submodule :param repo_path: path of repo to get information about submodule
@ -366,15 +385,22 @@ class GitTool:
def generate_install_locally(self, repo_path="./", filter_group=None): def generate_install_locally(self, repo_path="./", filter_group=None):
filename_locally = f"{repo_path}script/install_locally.sh" filename_locally = f"{repo_path}script/install_locally.sh"
lst_repo = self.get_repo_info(repo_path=repo_path, filter_group=filter_group) lst_repo = self.get_repo_info(
repo_path=repo_path, filter_group=filter_group
)
lst_result = [] lst_result = []
for repo in lst_repo: for repo in lst_repo:
# Exception, ignore addons/OCA_web and root # Exception, ignore addons/OCA_web and root
if "addons/OCA_web" == repo.get("path") or "odoo" == repo.get("path") or \ if (
"ERPLibre_image_db" == repo.get("path"): "addons/OCA_web" == repo.get("path")
or "odoo" == repo.get("path")
or "ERPLibre_image_db" == repo.get("path")
):
continue continue
str_repo = f' printf "${{EL_HOME}}/{repo.get("path")}," >> ' \ str_repo = (
f'${{EL_CONFIG_FILE}}\n' f' printf "${{EL_HOME}}/{repo.get("path")}," >> '
"${EL_CONFIG_FILE}\n"
)
lst_result.append(str_repo) lst_result.append(str_repo)
with open(filename_locally) as file: with open(filename_locally) as file:
all_lines = file.readlines() all_lines = file.readlines()
@ -383,8 +409,10 @@ class GitTool:
find_index = False find_index = False
index_find = 0 index_find = 0
for line in all_lines: for line in all_lines:
if not find_index and \ if (
"if [[ ${EL_MINIMAL_ADDONS} = \"False\" ]]; then\n" == line: not find_index
and 'if [[ ${EL_MINIMAL_ADDONS} = "False" ]]; then\n' == line
):
index_find = index + 1 index_find = index + 1
for insert_line in lst_result: for insert_line in lst_result:
all_lines.insert(index_find, insert_line) all_lines.insert(index_find, insert_line)
@ -398,8 +426,10 @@ class GitTool:
index += 1 index += 1
if not find_index: if not find_index:
print(f"ERROR cannot regenerate file {filename_locally}, " print(
f"did you change the header?") f"ERROR cannot regenerate file {filename_locally}, "
"did you change the header?"
)
# create file # create file
with open(filename_locally, mode="w") as file: with open(filename_locally, mode="w") as file:
@ -409,9 +439,15 @@ class GitTool:
def str_insert(source_str, insert_str, pos): def str_insert(source_str, insert_str, pos):
return source_str[:pos] + insert_str + source_str[pos:] return source_str[:pos] + insert_str + source_str[pos:]
def generate_repo_manifest(self, lst_repo: List[Struct] = [], output: str = "", def generate_repo_manifest(
dct_remote={}, dct_project={}, default_remote=None, self,
keep_original=False): lst_repo: List[Struct] = [],
output: str = "",
dct_remote={},
dct_project={},
default_remote=None,
keep_original=False,
):
""" """
Generate repo manifest Generate repo manifest
:param lst_repo: optional, update manifest with list_repo :param lst_repo: optional, update manifest with list_repo
@ -424,7 +460,9 @@ class GitTool:
:return: :return:
""" """
if not output: if not output:
raise Exception("Cannot generate manifest with missing output filename.") raise Exception(
"Cannot generate manifest with missing output filename."
)
lst_remote = [] lst_remote = []
lst_remote_name = [] lst_remote_name = []
lst_project = [] lst_project = []
@ -433,28 +471,40 @@ class GitTool:
# Fill with configuration # Fill with configuration
for dct_value in dct_remote.values(): for dct_value in dct_remote.values():
lst_remote.append(OrderedDict( lst_remote.append(
[('@name', dct_value.get("@name")), OrderedDict(
('@fetch', dct_value.get("@fetch"))] [
)) ("@name", dct_value.get("@name")),
("@fetch", dct_value.get("@fetch")),
]
)
)
lst_remote_name.append(dct_value.get("@name")) lst_remote_name.append(dct_value.get("@name"))
for dct_value in dct_project.values(): for dct_value in dct_project.values():
lst_project_info = [ lst_project_info = [
('@name', dct_value.get("@name")), ("@name", dct_value.get("@name")),
('@path', dct_value.get("@path")), ("@path", dct_value.get("@path")),
] ]
if "@remote" in dct_value.keys(): if "@remote" in dct_value.keys():
lst_project_info.append(('@remote', dct_value.get("@remote"))) lst_project_info.append(("@remote", dct_value.get("@remote")))
if "@revision" in dct_value.keys(): if "@revision" in dct_value.keys():
lst_project_info.append(('@revision', dct_value.get("@revision"))) lst_project_info.append(
("@revision", dct_value.get("@revision"))
)
if "@clone-depth" in dct_value.keys(): if "@clone-depth" in dct_value.keys():
lst_project_info.append(('@clone-depth', dct_value.get("@clone-depth"))) lst_project_info.append(
("@clone-depth", dct_value.get("@clone-depth"))
)
if "@groups" in dct_value.keys(): if "@groups" in dct_value.keys():
lst_project_info.append(('@groups', dct_value.get("@groups"))) lst_project_info.append(("@groups", dct_value.get("@groups")))
if "@upstream" in dct_value.keys(): if "@upstream" in dct_value.keys():
lst_project_info.append(('@upstream', dct_value.get("@upstream"))) lst_project_info.append(
("@upstream", dct_value.get("@upstream"))
)
if "@dest-branch" in dct_value.keys(): if "@dest-branch" in dct_value.keys():
lst_project_info.append(('@dest-branch', dct_value.get("@dest-branch"))) lst_project_info.append(
("@dest-branch", dct_value.get("@dest-branch"))
)
lst_project.append(OrderedDict(lst_project_info)) lst_project.append(OrderedDict(lst_project_info))
lst_project_name.append(dct_value.get("@name")) lst_project_name.append(dct_value.get("@name"))
@ -463,64 +513,97 @@ class GitTool:
if not repo.is_submodule: if not repo.is_submodule:
# Default # Default
if lst_default: if lst_default:
raise Exception("Cannot have many root repo. " raise Exception(
"Validate why 2 or more is not submodule.") "Cannot have many root repo. "
lst_default.append(OrderedDict([ "Validate why 2 or more is not submodule."
('@remote', repo.original_organization), )
('@revision', DEFAULT_BRANCH), lst_default.append(
('@sync-j', "4"), OrderedDict(
('@sync-c', "true"), [
])) ("@remote", repo.original_organization),
("@revision", DEFAULT_BRANCH),
("@sync-j", "4"),
("@sync-c", "true"),
]
)
)
else: else:
if keep_original and repo.project_name not in dct_project.keys(): if (
keep_original
and repo.project_name not in dct_project.keys()
):
# Exception, create a new remote to keep tracking on original # Exception, create a new remote to keep tracking on original
original_organization = f"{repo.original_organization}_origin" original_organization = (
f"{repo.original_organization}_origin"
)
else: else:
original_organization = repo.original_organization original_organization = repo.original_organization
# Add remote, only unique remote # Add remote, only unique remote
if original_organization not in lst_remote_name: if original_organization not in lst_remote_name:
lst_remote.append(OrderedDict( lst_remote.append(
[('@name', original_organization), OrderedDict(
('@fetch', repo.url_https_organization + "/")] [
)) ("@name", original_organization),
("@fetch", repo.url_https_organization + "/"),
]
)
)
lst_remote_name.append(repo.original_organization) lst_remote_name.append(repo.original_organization)
# Add project, only unique project # Add project, only unique project
if repo.project_name not in lst_project_name: if repo.project_name not in lst_project_name:
lst_project_name.append(repo.project_name) lst_project_name.append(repo.project_name)
lst_project_info = [ lst_project_info = [
('@name', repo.project_name), ("@name", repo.project_name),
('@path', repo.path), ("@path", repo.path),
('@remote', original_organization), ("@remote", original_organization),
] ]
if repo.revision: if repo.revision:
lst_project_info.append(('@revision', repo.revision)) lst_project_info.append(("@revision", repo.revision))
if repo.clone_depth: if repo.clone_depth:
lst_project_info.append(('@clone-depth', repo.clone_depth)) lst_project_info.append(
("@clone-depth", repo.clone_depth)
)
if repo.sub_path == "addons": if repo.sub_path == "addons":
lst_project_info.append(('@groups', "addons")) lst_project_info.append(("@groups", "addons"))
else: else:
lst_project_info.append(('@groups', "odoo")) lst_project_info.append(("@groups", "odoo"))
lst_project.append(OrderedDict(lst_project_info)) lst_project.append(OrderedDict(lst_project_info))
if default_remote and not lst_default: if default_remote and not lst_default:
lst_default.append(OrderedDict([ lst_default.append(
('@remote', default_remote.get("@remote")), OrderedDict(
('@revision', DEFAULT_BRANCH), [
('@sync-j', "4"), ("@remote", default_remote.get("@remote")),
('@sync-c', "true"), ("@revision", DEFAULT_BRANCH),
])) ("@sync-j", "4"),
("@sync-c", "true"),
]
)
)
# Order in alphabetic # Order in alphabetic
lst_order_remote = sorted(lst_remote, key=lambda key: key.get("@name")) lst_order_remote = sorted(lst_remote, key=lambda key: key.get("@name"))
lst_order_default = sorted(lst_default, key=lambda key: key.get("@remote")) lst_order_default = sorted(
lst_order_project = sorted(lst_project, key=lambda key: key.get("@name")) lst_default, key=lambda key: key.get("@remote")
)
lst_order_project = sorted(
lst_project, key=lambda key: key.get("@name")
)
dct_repo = OrderedDict( dct_repo = OrderedDict(
[('manifest', OrderedDict([ [
('remote', lst_order_remote), (
('default', lst_order_default), "manifest",
('project', lst_order_project), OrderedDict(
]))]) [
("remote", lst_order_remote),
("default", lst_order_default),
("project", lst_order_project),
]
),
)
]
)
str_xml_text = xmltodict.unparse(dct_repo, pretty=True) str_xml_text = xmltodict.unparse(dct_repo, pretty=True)
pos_insert = str_xml_text.rfind("</remote>") pos_insert = str_xml_text.rfind("</remote>")
@ -541,20 +624,26 @@ class GitTool:
str_xml_text = str_xml_text.replace("></remote", "/") str_xml_text = str_xml_text.replace("></remote", "/")
str_xml_text = str_xml_text.replace("></default", "/") str_xml_text = str_xml_text.replace("></default", "/")
str_xml_text = str_xml_text.replace("></project", "/") str_xml_text = str_xml_text.replace("></project", "/")
str_xml_text = str_xml_text.replace("encoding=\"utf-8\"", "encoding=\"UTF-8\"") str_xml_text = str_xml_text.replace(
'encoding="utf-8"', 'encoding="UTF-8"'
)
str_xml_text = str_xml_text.replace("\t", " ") str_xml_text = str_xml_text.replace("\t", " ")
# create file # create file
with open(output, mode="w") as file: with open(output, mode="w") as file:
file.writelines(str_xml_text + "\n") file.writelines(str_xml_text + "\n")
def generate_git_modules(self, lst_repo: List[Struct], repo_path: str = "./"): def generate_git_modules(
self, lst_repo: List[Struct], repo_path: str = "./"
):
lst_modules = [] lst_modules = []
for repo in lst_repo: for repo in lst_repo:
if repo.is_submodule: if repo.is_submodule:
lst_modules.append(f"[submodule \"{repo.path}\"]\n" lst_modules.append(
f"\turl = {repo.url_https}\n" f'[submodule "{repo.path}"]\n'
f"\tpath = {repo.path}\n") f"\turl = {repo.url_https}\n"
f"\tpath = {repo.path}\n"
)
# create file # create file
with open(f"{repo_path}.gitmodules", mode="w") as file: with open(f"{repo_path}.gitmodules", mode="w") as file:
@ -581,10 +670,9 @@ class GitTool:
# TODO what to do if origin not exist? # TODO what to do if origin not exist?
repo = Repo(repo_path) repo = Repo(repo_path)
url = [a for a in repo.remotes][0].url url = [a for a in repo.remotes][0].url
repo_info = self.get_transformed_repo_info_from_url(url, repo_info = self.get_transformed_repo_info_from_url(
repo_path=repo_path, url, repo_path=repo_path, get_obj=False, is_submodule=False
get_obj=False, )
is_submodule=False)
lst_result.append(repo_info) lst_result.append(repo_info)
with open(file_name) as file: with open(file_name) as file:
all_lines = file.readlines() all_lines = file.readlines()
@ -592,8 +680,10 @@ class GitTool:
# Validate first line is supported column # Validate first line is supported column
expected_header = "url,path,revision,clone-depth\n" expected_header = "url,path,revision,clone-depth\n"
if all_lines[0] != expected_header: if all_lines[0] != expected_header:
raise Exception(f"Not supported csv, please validate {file_name} " raise Exception(
f"with first line {expected_header}") f"Not supported csv, please validate {file_name} "
f"with first line {expected_header}"
)
# Ignore first line # Ignore first line
all_lines = all_lines[1:] all_lines = all_lines[1:]
@ -606,7 +696,7 @@ class GitTool:
line = line.strip() line = line.strip()
if not line: if not line:
continue continue
line_split = line.split(',') line_split = line.split(",")
if len(line_split) != 4: if len(line_split) != 4:
print(f"Error with line {line}, suppose to have only 4 ','.") print(f"Error with line {line}, suppose to have only 4 ','.")
exit(1) exit(1)
@ -615,12 +705,14 @@ class GitTool:
# If begin by http, need to finish by .git # If begin by http, need to finish by .git
if len(url) > 5 and url[0:4] == "http" and url[-4:] != ".git": if len(url) > 5 and url[0:4] == "http" and url[-4:] != ".git":
url = f"{url}.git" url = f"{url}.git"
repo_info = self.get_transformed_repo_info_from_url(url, repo_info = self.get_transformed_repo_info_from_url(
repo_path=repo_path, url,
get_obj=False, repo_path=repo_path,
sub_path=path, get_obj=False,
revision=revision, sub_path=path,
clone_depth=clone_depth) revision=revision,
clone_depth=clone_depth,
)
lst_result.append(repo_info) lst_result.append(repo_info)
return lst_result return lst_result
@ -634,11 +726,18 @@ class GitTool:
with open(file) as xml: with open(file) as xml:
xml_as_string = xml.read() xml_as_string = xml.read()
xml_dict = xmltodict.parse(xml_as_string, dict_constructor=dict) xml_dict = xmltodict.parse(xml_as_string, dict_constructor=dict)
manifest_filename = xml_dict.get("manifest").get("include").get("@name") manifest_filename = (
xml_dict.get("manifest").get("include").get("@name")
)
return manifest_filename return manifest_filename
def get_matching_repo(self, actual_repo="./", repo_compare_to="./", def get_matching_repo(
force_normalize_compare=False, sync_with_submodule=False): self,
actual_repo="./",
repo_compare_to="./",
force_normalize_compare=False,
sync_with_submodule=False,
):
""" """
Compare repo with .gitmodules files Compare repo with .gitmodules files
:param actual_repo: :param actual_repo:
@ -653,12 +752,15 @@ class GitTool:
# set_actual_repo = set( # set_actual_repo = set(
# [a[a.find("_") + 1:] for a in dct_repo_info_actual.keys()]) # [a[a.find("_") + 1:] for a in dct_repo_info_actual.keys()])
dct_repo_info_actual_adapted = {key[key.find("_") + 1:]: item for key, item in dct_repo_info_actual_adapted = {
dct_repo_info_actual.items()} key[key.find("_") + 1 :]: item
for key, item in dct_repo_info_actual.items()
}
set_actual_repo = set(dct_repo_info_actual_adapted.keys()) set_actual_repo = set(dct_repo_info_actual_adapted.keys())
lst_repo_info_compare = self.get_repo_info(repo_compare_to, lst_repo_info_compare = self.get_repo_info(
is_manifest=not sync_with_submodule) repo_compare_to, is_manifest=not sync_with_submodule
)
if force_normalize_compare: if force_normalize_compare:
for repo_info in lst_repo_info_compare: for repo_info in lst_repo_info_compare:
url_https = repo_info.get("url_https") url_https = repo_info.get("url_https")
@ -671,7 +773,9 @@ class GitTool:
name = f"{repo_name}" name = f"{repo_name}"
repo_info["name"] = name repo_info["name"] = name
dct_repo_info_compare = {a.get("name"): a for a in lst_repo_info_compare} dct_repo_info_compare = {
a.get("name"): a for a in lst_repo_info_compare
}
set_compare = set(dct_repo_info_compare.keys()) set_compare = set(dct_repo_info_compare.keys())
# TODO finish the match # TODO finish the match
@ -681,16 +785,17 @@ class GitTool:
lst_same_name_normalize = set_actual_repo.intersection(set_compare) lst_same_name_normalize = set_actual_repo.intersection(set_compare)
lst_missing_name_normalize = set_compare.difference(set_actual_repo) lst_missing_name_normalize = set_compare.difference(set_actual_repo)
lst_over_name_normalize = set_actual_repo.difference(set_compare) lst_over_name_normalize = set_actual_repo.difference(set_compare)
print(f"Has {len(lst_same_name_normalize)} sames, " print(
f"{len(lst_missing_name_normalize)} missing, " f"Has {len(lst_same_name_normalize)} sames, "
f"{len(lst_over_name_normalize)} more.") f"{len(lst_missing_name_normalize)} missing, "
f"{len(lst_over_name_normalize)} more."
)
lst_match = [] lst_match = []
for key in lst_same_name_normalize: for key in lst_same_name_normalize:
lst_match.append(( lst_match.append(
dct_repo_info_actual_adapted[key], (dct_repo_info_actual_adapted[key], dct_repo_info_compare[key])
dct_repo_info_compare[key] )
))
return lst_match, lst_missing_name_normalize, lst_over_name_normalize return lst_match, lst_missing_name_normalize, lst_over_name_normalize
@ -728,14 +833,18 @@ class GitTool:
repo_compare = Repo(compare_to.get("relative_path")) repo_compare = Repo(compare_to.get("relative_path"))
commit_compare = repo_compare.head.object.hexsha commit_compare = repo_compare.head.object.hexsha
if commit_original != commit_compare: if commit_original != commit_compare:
print(f"DIFF - {original.get('name')} - O {commit_original} - " print(
f"R {commit_compare}") f"DIFF - {original.get('name')} - O {commit_original} - "
f"R {commit_compare}"
)
lst_diff.append((original, compare_to)) lst_diff.append((original, compare_to))
if checkout_when_diff: if checkout_when_diff:
# Update all remote # Update all remote
for remote in repo_original.remotes: for remote in repo_original.remotes:
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(
remote.fetch)() wait_exponential_multiplier=1000,
stop_max_delay=15000,
)(remote.fetch)()
repo_original.git.checkout(commit_compare) repo_original.git.checkout(commit_compare)
else: else:
print(f"SAME - {original.get('name')}") print(f"SAME - {original.get('name')}")
@ -743,8 +852,9 @@ class GitTool:
print(f"finish same {len(lst_same)}, diff {len(lst_diff)}") print(f"finish same {len(lst_same)}, diff {len(lst_diff)}")
@staticmethod @staticmethod
def add_and_fetch_remote(repo_info: Struct, root_repo: Repo = None, def add_and_fetch_remote(
branch_name: str = ""): repo_info: Struct, root_repo: Repo = None, branch_name: str = ""
):
""" """
Deprecated function, not use anymore git submodule Deprecated function, not use anymore git submodule
:param repo_info: :param repo_info:
@ -754,42 +864,57 @@ class GitTool:
""" """
try: try:
working_repo = Repo(repo_info.relative_path) working_repo = Repo(repo_info.relative_path)
if repo_info.organization in [a.name for a in working_repo.remotes]: if repo_info.organization in [
print(f"Remote \"{repo_info.organization}\" already exist " a.name for a in working_repo.remotes
f"in {repo_info.relative_path}") ]:
print(
f'Remote "{repo_info.organization}" already exist '
f"in {repo_info.relative_path}"
)
return return
except git.NoSuchPathError: except git.NoSuchPathError:
print(f"New repo {repo_info.relative_path}") print(f"New repo {repo_info.relative_path}")
if not root_repo: if not root_repo:
print(f"Missing git repository to root for repo {repo_info.path}") print(
f"Missing git repository to root for repo {repo_info.path}"
)
return return
if branch_name: if branch_name:
submodule_repo = retry( submodule_repo = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000 )(root_repo.create_submodule)(
)(root_repo.create_submodule)(repo_info.path, repo_info.path, repo_info.path,
url=repo_info.url_https, repo_info.path,
branch=branch_name) url=repo_info.url_https,
branch=branch_name,
)
else: else:
submodule_repo = retry( submodule_repo = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000 )(root_repo.create_submodule)(
)(root_repo.create_submodule)(repo_info.path, repo_info.path, repo_info.path, repo_info.path, url=repo_info.url_https
url=repo_info.url_https) )
return return
# Add remote # Add remote
upstream_remote = retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( upstream_remote = retry(
working_repo.create_remote)(repo_info.organization, repo_info.url_https) wait_exponential_multiplier=1000, stop_max_delay=15000
print('Remote "%s" created for %s' % ( )(working_repo.create_remote)(
repo_info.organization, repo_info.url_https)) repo_info.organization, repo_info.url_https
)
print(
'Remote "%s" created for %s'
% (repo_info.organization, repo_info.url_https)
)
# Fetch the remote # Fetch the remote
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
upstream_remote.fetch)() upstream_remote.fetch
)()
print('Remote "%s" fetched' % repo_info.organization) print('Remote "%s" fetched' % repo_info.organization)
def get_pull_request_repo(self, upstream_url: str, github_token: str, def get_pull_request_repo(
organization_name: str = ""): self, upstream_url: str, github_token: str, organization_name: str = ""
):
""" """
:param upstream_url: :param upstream_url:
@ -802,7 +927,9 @@ class GitTool:
# Fork the repo # Fork the repo
status, user = gh.user.get() status, user = gh.user.get()
user_name = user['login'] if not organization_name else organization_name user_name = (
user["login"] if not organization_name else organization_name
)
status, lst_pull = gh.repos[user_name][parsed_url.repo].pulls.get() status, lst_pull = gh.repos[user_name][parsed_url.repo].pulls.get()
if type(lst_pull) is dict: if type(lst_pull) is dict:
print(f"For url {upstream_url}, got {lst_pull.get('message')}") print(f"For url {upstream_url}, got {lst_pull.get('message')}")
@ -812,34 +939,41 @@ class GitTool:
print(pull.get("html_url")) print(pull.get("html_url"))
return lst_pull return lst_pull
def fork_repo(self, upstream_url: str, github_token: str, def fork_repo(
organization_name: str = ""): self, upstream_url: str, github_token: str, organization_name: str = ""
):
# https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/about-scopes-for-oauth-apps/ # https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/about-scopes-for-oauth-apps/
gh = GitHub(token=github_token) gh = GitHub(token=github_token)
parsed_url = parse(upstream_url) parsed_url = parse(upstream_url)
# Fork the repo # Fork the repo
status, user = gh.user.get() status, user = gh.user.get()
user_name = user['login'] if not organization_name else organization_name user_name = (
user["login"] if not organization_name else organization_name
)
status, forked_repo = gh.repos[user_name][parsed_url.repo].get() status, forked_repo = gh.repos[user_name][parsed_url.repo].get()
if status == 404: if status == 404:
status, upstream_repo = ( status, upstream_repo = gh.repos[parsed_url.owner][
gh.repos[parsed_url.owner][parsed_url.repo].get()) parsed_url.repo
].get()
if status == 404: if status == 404:
print("Unable to find repo %s" % upstream_url) print("Unable to find repo %s" % upstream_url)
exit(1) exit(1)
args = {} args = {}
if organization_name: if organization_name:
args["organization"] = organization_name args["organization"] = organization_name
status, forked_repo = ( status, forked_repo = gh.repos[parsed_url.owner][
gh.repos[parsed_url.owner][parsed_url.repo].forks.post(**args)) parsed_url.repo
].forks.post(**args)
if status == 404: if status == 404:
print("Error when forking repo %s" % forked_repo) print("Error when forking repo %s" % forked_repo)
exit(1) exit(1)
else: else:
print("Forked %s to %s" % (upstream_url, forked_repo['html_url'])) print(
"Forked %s to %s" % (upstream_url, forked_repo["html_url"])
)
elif status == 202: elif status == 202:
print("Forked repo %s already exists" % forked_repo['full_name']) print("Forked repo %s already exists" % forked_repo["full_name"])
elif status != 200: elif status != 200:
print("Status not supported: %s - %s" % (status, forked_repo)) print("Status not supported: %s - %s" % (status, forked_repo))
exit(1) exit(1)

View file

@ -6,7 +6,7 @@ import logging
from git import Repo # pip install gitpython from git import Repo # pip install gitpython
from retrying import retry # pip install retrying from retrying import retry # pip install retrying
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -23,13 +23,18 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -38,13 +43,21 @@ def main():
config = get_config() config = get_config()
git_tool = GitTool() git_tool = GitTool()
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, lst_repo = git_tool.get_source_repo_addons(
add_repo_root=False) repo_path=config.dir, add_repo_root=False
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url( )
a.get("url"), repo_path=config.dir, get_obj=True, lst_repo_organization = [
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"), git_tool.get_transformed_repo_info_from_url(
revision=a.get("revision"), clone_depth=a.get("clone_depth")) a.get("url"),
for a in lst_repo] repo_path=config.dir,
get_obj=True,
is_submodule=a.get("is_submodule"),
sub_path=a.get("sub_path"),
revision=a.get("revision"),
clone_depth=a.get("clone_depth"),
)
for a in lst_repo
]
i = 0 i = 0
total = len(lst_repo) total = len(lst_repo)
@ -61,17 +74,22 @@ def main():
# 1. Add remote if not exist # 1. Add remote if not exist
try: try:
upstream_remote = git_repo.remote(upstream_name) upstream_remote = git_repo.remote(upstream_name)
print(f'Remote "{upstream_name}" already exists in {repo.relative_path}') print(
f'Remote "{upstream_name}" already exists in'
f" {repo.relative_path}"
)
except ValueError: except ValueError:
upstream_remote = retry( upstream_remote = retry(
wait_exponential_multiplier=1000, wait_exponential_multiplier=1000, stop_max_delay=15000
stop_max_delay=15000
)(git_repo.create_remote)(upstream_name, repo.url_https) )(git_repo.create_remote)(upstream_name, repo.url_https)
print('Remote "%s" created for %s' % (upstream_name, repo.url_https)) print(
'Remote "%s" created for %s' % (upstream_name, repo.url_https)
)
# 2. Fetch the remote source # 2. Fetch the remote source
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
upstream_remote.fetch)() upstream_remote.fetch
)()
print('Remote "%s" fetched' % upstream_name) print('Remote "%s" fetched' % upstream_name)
# 3. Rebase actual branch with new branch # 3. Rebase actual branch with new branch
@ -99,15 +117,19 @@ def main():
# push # push
try: try:
retry(wait_exponential_multiplier=1000, stop_max_delay=15000)( retry(wait_exponential_multiplier=1000, stop_max_delay=15000)(
git_repo.git.push)(repo.organization, rev) git_repo.git.push
)(repo.organization, rev)
except: except:
print("Cannot push, maybe need to push force or resolv rebase conflict", print(
file=sys.stderr) "Cannot push, maybe need to push force or resolv rebase"
" conflict",
file=sys.stderr,
)
print(f"cd {repo.path}") print(f"cd {repo.path}")
print(f"git diff ERPLibre/v#.#.#..HEAD") print(f"git diff ERPLibre/v#.#.#..HEAD")
print(f"git push --force {repo.organization} {rev}") print(f"git push --force {repo.organization} {rev}")
print(f"cd -") print(f"cd -")
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -9,7 +9,7 @@ from collections import OrderedDict, defaultdict
from pathlib import Path from pathlib import Path
import iscompatible import iscompatible
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script import git_tool from script import git_tool
@ -27,29 +27,45 @@ def get_config():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
Update pip dependency in Poetry, clear pyproject.toml, search all dependencies Update pip dependency in Poetry, clear pyproject.toml, search all dependencies
from requirements.txt, search conflict version and generate a new list. from requirements.txt, search conflict version and generate a new list.
Launch Poetry installation. Launch Poetry installation.
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"-f",
"--force",
action="store_true",
help="Force create new list of dependency, ignore poetry.lock.",
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
help="More information in execution, show stats.",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('-f', '--force', action="store_true",
help="Force create new list of dependency, ignore poetry.lock.")
parser.add_argument('-v', '--verbose', action="store_true",
help="More information in execution, show stats.")
args = parser.parse_args() args = parser.parse_args()
return args return args
def get_lst_requirements_txt(): def get_lst_requirements_txt():
# Ignore some item in list # Ignore some item in list
lst = [a for a in Path(".").rglob("requirements.[tT][xX][tT]") lst = [
if not os.path.dirname(a).startswith('.repo/') and not os.path.dirname(a).startswith('.venv/') a
] for a in Path(".").rglob("requirements.[tT][xX][tT]")
if not os.path.dirname(a).startswith(".repo/")
and not os.path.dirname(a).startswith(".venv/")
]
return lst return lst
@ -76,7 +92,7 @@ def combine_requirements(config):
dct_special_condition = defaultdict(list) dct_special_condition = defaultdict(list)
dct_requirements_module_filename = defaultdict(list) dct_requirements_module_filename = defaultdict(list)
for requirements_filename in lst_requirements_file: for requirements_filename in lst_requirements_file:
with open(requirements_filename, 'r') as f: with open(requirements_filename, "r") as f:
for a in f.readlines(): for a in f.readlines():
b = a.strip() b = a.strip()
if not b or b[0] == "#": if not b or b[0] == "#":
@ -86,10 +102,14 @@ def combine_requirements(config):
for sign in lst_sign: for sign in lst_sign:
if sign in b: if sign in b:
# Exception, some time the sign ; can be first, just check # Exception, some time the sign ; can be first, just check
if sign != ";" and ";" in b and b.find(sign) > b.find(";"): if (
module_name = b[:b.find(";")] sign != ";"
and ";" in b
and b.find(sign) > b.find(";")
):
module_name = b[: b.find(";")]
else: else:
module_name = b[:b.find(sign)] module_name = b[: b.find(sign)]
module_name = module_name.strip() module_name = module_name.strip()
# Special condition for ";", ignore it # Special condition for ";", ignore it
if ";" in b: if ";" in b:
@ -99,13 +119,15 @@ def combine_requirements(config):
if ignore_string in b: if ignore_string in b:
break break
lst_requirements_with_condition.add(module_name) lst_requirements_with_condition.add(module_name)
value = b[:b.find(";")].strip() value = b[: b.find(";")].strip()
dct_special_condition[module_name].append(b) dct_special_condition[module_name].append(b)
else: else:
value = b value = b
dct_requirements[module_name].add(value) dct_requirements[module_name].add(value)
filename = str(requirements_filename) filename = str(requirements_filename)
dct_requirements_module_filename[value].append(filename) dct_requirements_module_filename[value].append(
filename
)
break break
else: else:
dct_requirements[b].add(b) dct_requirements[b].add(b)
@ -115,16 +137,19 @@ def combine_requirements(config):
dct_requirements = get_manifest_external_dependencies(dct_requirements) dct_requirements = get_manifest_external_dependencies(dct_requirements)
dct_requirements_diff_version = {k: v for k, v in dct_requirements.items() if dct_requirements_diff_version = {
len(v) > 1} k: v for k, v in dct_requirements.items() if len(v) > 1
}
# dct_requirements_same_version = {k: v for k, v in dct_requirements.items() if # dct_requirements_same_version = {k: v for k, v in dct_requirements.items() if
# len(v) == 1} # len(v) == 1}
if config.verbose: if config.verbose:
# TODO show total repo to compare lst requirements # TODO show total repo to compare lst requirements
print(f"Total requirements.txt {len(lst_requirements_file)}, " print(
f"total module {len(lst_requirements)}, " f"Total requirements.txt {len(lst_requirements_file)}, total"
f"unique module {len(dct_requirements)}, " f" module {len(lst_requirements)}, unique module"
f"module with different version {len(dct_requirements_diff_version)}.") f" {len(dct_requirements)}, module with different version"
f" {len(dct_requirements_diff_version)}."
)
if dct_requirements_diff_version: if dct_requirements_diff_version:
# Validate compatibility # Validate compatibility
@ -143,20 +168,29 @@ def combine_requirements(config):
# TODO support me in iscompatible lib # TODO support me in iscompatible lib
no_version = result_number[0][1] no_version = result_number[0][1]
if "b" in no_version: if "b" in no_version:
result_number[0] = result_number[0][0], no_version[ result_number[0] = (
:no_version.find("b")] result_number[0][0],
elif not no_version[no_version.rfind(".") + 1:].isnumeric(): no_version[: no_version.find("b")],
result_number[0] = result_number[0][0], no_version[ )
:no_version.rfind(".")] elif not no_version[no_version.rfind(".") + 1 :].isnumeric():
result_number = iscompatible.string_to_tuple(result_number[0][1]) result_number[0] = (
result_number[0][0],
no_version[: no_version.rfind(".")],
)
result_number = iscompatible.string_to_tuple(
result_number[0][1]
)
lst_version_requirement.append((requirement, result_number)) lst_version_requirement.append((requirement, result_number))
# Check compatibility with all possibility # Check compatibility with all possibility
is_compatible = True is_compatible = True
if len(lst_version_requirement) > 1: if len(lst_version_requirement) > 1:
highest_value = sorted(lst_version_requirement, key=lambda tup: tup[1])[-1] highest_value = sorted(
lst_version_requirement, key=lambda tup: tup[1]
)[-1]
for version_requirement in lst_version_requirement: for version_requirement in lst_version_requirement:
is_compatible &= iscompatible.iscompatible(version_requirement[0], is_compatible &= iscompatible.iscompatible(
highest_value[1]) version_requirement[0], highest_value[1]
)
if is_compatible: if is_compatible:
result = highest_value[0] result = highest_value[0]
else: else:
@ -166,26 +200,39 @@ def combine_requirements(config):
erplibre_value = None erplibre_value = None
for version_requirement in lst_version_requirement: for version_requirement in lst_version_requirement:
filename_1 = dct_requirements_module_filename.get( filename_1 = dct_requirements_module_filename.get(
version_requirement[0]) version_requirement[0]
)
if priority_filename_requirement in filename_1: if priority_filename_requirement in filename_1:
erplibre_value = version_requirement[0] erplibre_value = version_requirement[0]
elif second_priority_filename_requirement in filename_1: elif (
second_priority_filename_requirement in filename_1
):
odoo_value = version_requirement[0] odoo_value = version_requirement[0]
if erplibre_value: if erplibre_value:
str_result_choose = f"Select {erplibre_value} because from ERPLibre" str_result_choose = (
f"Select {erplibre_value} because from ERPLibre"
)
result = erplibre_value result = erplibre_value
elif odoo_value: elif odoo_value:
str_result_choose = f"Select {odoo_value} because from Odoo" str_result_choose = (
f"Select {odoo_value} because from Odoo"
)
result = odoo_value result = odoo_value
else: else:
result = highest_value[0] result = highest_value[0]
str_result_choose = f"Select highest value {result}" str_result_choose = f"Select highest value {result}"
str_versions = " VS ".join( str_versions = " VS ".join(
[f"{a[0]} from {dct_requirements_module_filename.get(a[0])}" for [
a in lst_version_requirement]) f"{a[0]} from"
print(f"WARNING - Not compatible {str_versions} - " f" {dct_requirements_module_filename.get(a[0])}"
f"{str_result_choose}.") for a in lst_version_requirement
]
)
print(
f"WARNING - Not compatible {str_versions} - "
f"{str_result_choose}."
)
elif len(lst_version_requirement) == 1: elif len(lst_version_requirement) == 1:
result = lst_version_requirement[0][0] result = lst_version_requirement[0][0]
else: else:
@ -206,13 +253,13 @@ def combine_requirements(config):
for key in lst_ignored_key: for key in lst_ignored_key:
del dct_requirements[key] del dct_requirements[key]
with open("./.venv/build_dependency.txt", 'w') as f: with open("./.venv/build_dependency.txt", "w") as f:
f.writelines([f"{list(a)[0]}\n" for a in dct_requirements.values()]) f.writelines([f"{list(a)[0]}\n" for a in dct_requirements.values()])
def sorted_dependency_poetry(pyproject_filename): def sorted_dependency_poetry(pyproject_filename):
# Open pyproject.toml # Open pyproject.toml
with open(pyproject_filename, 'r') as f: with open(pyproject_filename, "r") as f:
dct_pyproject = toml.load(f) dct_pyproject = toml.load(f)
# Get dependencies and update list, sorted # Get dependencies and update list, sorted
@ -222,19 +269,23 @@ def sorted_dependency_poetry(pyproject_filename):
poetry = tool.get("poetry") poetry = tool.get("poetry")
if poetry: if poetry:
dependencies = poetry.get("dependencies") dependencies = poetry.get("dependencies")
python_dependency = ("python", dependencies.get("python", '')) python_dependency = ("python", dependencies.get("python", ""))
lst_dependency = [(k, v) for k, v in dependencies.items() if k != "python"] lst_dependency = [
(k, v) for k, v in dependencies.items() if k != "python"
]
lst_dependency = sorted(lst_dependency, key=lambda tup: tup[0]) lst_dependency = sorted(lst_dependency, key=lambda tup: tup[0])
poetry["dependencies"] = OrderedDict([python_dependency] + lst_dependency) poetry["dependencies"] = OrderedDict(
[python_dependency] + lst_dependency
)
# Rewrite pyproject.toml # Rewrite pyproject.toml
with open(pyproject_filename, 'w') as f: with open(pyproject_filename, "w") as f:
toml.dump(dct_pyproject, f) toml.dump(dct_pyproject, f)
def delete_dependency_poetry(pyproject_filename): def delete_dependency_poetry(pyproject_filename):
# Open pyproject.toml # Open pyproject.toml
with open(pyproject_filename, 'r') as f: with open(pyproject_filename, "r") as f:
dct_pyproject = toml.load(f) dct_pyproject = toml.load(f)
# Get dependencies and update list, sorted # Get dependencies and update list, sorted
@ -244,11 +295,11 @@ def delete_dependency_poetry(pyproject_filename):
poetry = tool.get("poetry") poetry = tool.get("poetry")
if poetry: if poetry:
dependencies = poetry.get("dependencies") dependencies = poetry.get("dependencies")
python_dependency = ("python", dependencies.get("python", '')) python_dependency = ("python", dependencies.get("python", ""))
poetry["dependencies"] = OrderedDict([python_dependency]) poetry["dependencies"] = OrderedDict([python_dependency])
# Rewrite pyproject.toml # Rewrite pyproject.toml
with open(pyproject_filename, 'w') as f: with open(pyproject_filename, "w") as f:
toml.dump(dct_pyproject, f) toml.dump(dct_pyproject, f)
@ -256,7 +307,7 @@ def get_manifest_external_dependencies(dct_requirements):
lst_manifest_file = get_lst_manifest_py() lst_manifest_file = get_lst_manifest_py()
lst_dct_ext_depend = [] lst_dct_ext_depend = []
for manifest_file in lst_manifest_file: for manifest_file in lst_manifest_file:
with open(manifest_file, 'r') as f: with open(manifest_file, "r") as f:
contents = f.read() contents = f.read()
try: try:
dct = ast.literal_eval(contents) dct = ast.literal_eval(contents)
@ -289,7 +340,7 @@ def call_poetry_add_build_dependency():
def get_list_ignored(): def get_list_ignored():
with open("./ignore_requirements.txt", 'r') as f: with open("./ignore_requirements.txt", "r") as f:
lst_ignore_requirements = [a.strip() for a in f.readlines()] lst_ignore_requirements = [a.strip() for a in f.readlines()]
return lst_ignore_requirements return lst_ignore_requirements
@ -298,7 +349,7 @@ def main():
# repo = Repo(root_path) # repo = Repo(root_path)
# lst_repo = get_all_repo() # lst_repo = get_all_repo()
config = get_config() config = get_config()
pyproject_toml_filename = f'{config.dir}pyproject.toml' pyproject_toml_filename = f"{config.dir}pyproject.toml"
delete_dependency_poetry(pyproject_toml_filename) delete_dependency_poetry(pyproject_toml_filename)
combine_requirements(config) combine_requirements(config)
@ -309,5 +360,5 @@ def main():
sorted_dependency_poetry(pyproject_toml_filename) sorted_dependency_poetry(pyproject_toml_filename)
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -4,7 +4,7 @@ import sys
import argparse import argparse
import logging import logging
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -24,18 +24,30 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
)
parser.add_argument(
"--organization",
dest="organization",
default="ERPLibre",
help="Choose organization to fork and change all repo.",
)
parser.add_argument(
"--github_token",
dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
parser.add_argument('--organization', dest="organization", default="ERPLibre",
help="Choose organization to fork and change all repo.")
parser.add_argument('--github_token', dest="github_token",
default=config.get(CST_EL_GITHUB_TOKEN),
help="GitHub token generated by user")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -49,12 +61,21 @@ def main():
raise ValueError("Missing github_token") raise ValueError("Missing github_token")
organization_name = config.organization organization_name = config.organization
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, add_repo_root=True) lst_repo = git_tool.get_source_repo_addons(
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url( repo_path=config.dir, add_repo_root=True
a.get("url"), repo_path=config.dir, organization_force=organization_name, )
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"), lst_repo_organization = [
revision=a.get("revision"), clone_depth=a.get("clone_depth")) git_tool.get_transformed_repo_info_from_url(
for a in lst_repo] a.get("url"),
repo_path=config.dir,
organization_force=organization_name,
is_submodule=a.get("is_submodule"),
sub_path=a.get("sub_path"),
revision=a.get("revision"),
clone_depth=a.get("clone_depth"),
)
for a in lst_repo
]
url_not_found_count = 0 url_not_found_count = 0
url_found_count = 0 url_found_count = 0
@ -66,9 +87,11 @@ def main():
print(f"Nb element {i}/{total} - {repo.project_name}") print(f"Nb element {i}/{total} - {repo.project_name}")
url = repo.url url = repo.url
status = git_tool.get_pull_request_repo(upstream_url=url, status = git_tool.get_pull_request_repo(
github_token=github_token, upstream_url=url,
organization_name=organization_name) github_token=github_token,
organization_name=organization_name,
)
if status is False: if status is False:
url_not_found_count += 1 url_not_found_count += 1
else: else:
@ -78,5 +101,5 @@ def main():
print(f"URL found: {url_found_count}") print(f"URL found: {url_found_count}")
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -7,7 +7,7 @@ from pathlib import Path
from git import Repo # pip install gitpython from git import Repo # pip install gitpython
from git.exc import GitCommandError from git.exc import GitCommandError
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
from script.git_tool import GitTool from script.git_tool import GitTool
@ -24,13 +24,18 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
)
parser.add_argument(
"-d",
"--dir",
dest="dir",
default="./",
help="Path of repo to change remote, including submodule.",
) )
parser.add_argument('-d', '--dir', dest="dir", default="./",
help="Path of repo to change remote, including submodule.")
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -39,13 +44,21 @@ def main():
config = get_config() config = get_config()
git_tool = GitTool() git_tool = GitTool()
lst_repo = git_tool.get_source_repo_addons(repo_path=config.dir, lst_repo = git_tool.get_source_repo_addons(
add_repo_root=False) repo_path=config.dir, add_repo_root=False
lst_repo_organization = [git_tool.get_transformed_repo_info_from_url( )
a.get("url"), repo_path=config.dir, get_obj=True, lst_repo_organization = [
is_submodule=a.get("is_submodule"), sub_path=a.get("sub_path"), git_tool.get_transformed_repo_info_from_url(
revision=a.get("revision"), clone_depth=a.get("clone_depth")) a.get("url"),
for a in lst_repo] repo_path=config.dir,
get_obj=True,
is_submodule=a.get("is_submodule"),
sub_path=a.get("sub_path"),
revision=a.get("revision"),
clone_depth=a.get("clone_depth"),
)
for a in lst_repo
]
lst_ignore_repo = ["odoo"] lst_ignore_repo = ["odoo"]
@ -68,7 +81,9 @@ def main():
is_checkout_branch = True is_checkout_branch = True
except GitCommandError: except GitCommandError:
try: try:
git_repo.git.checkout("-t", f"{repo.organization}/{branch_name}") git_repo.git.checkout(
"-t", f"{repo.organization}/{branch_name}"
)
is_checkout_branch = True is_checkout_branch = True
except GitCommandError: except GitCommandError:
pass pass
@ -93,7 +108,7 @@ def get_manifest_external_dependencies(repo):
lst_manifest_file = get_lst_manifest_py(repo.relative_path) lst_manifest_file = get_lst_manifest_py(repo.relative_path)
for manifest_file in lst_manifest_file: for manifest_file in lst_manifest_file:
has_change_manifest = False has_change_manifest = False
with open(manifest_file, 'r') as f: with open(manifest_file, "r") as f:
lst_content = f.readlines() lst_content = f.readlines()
i = 0 i = 0
for content in lst_content: for content in lst_content:
@ -102,16 +117,18 @@ def get_manifest_external_dependencies(repo):
has_change = True has_change = True
first_char_index = content.find("auto_install") first_char_index = content.find("auto_install")
index = content.find("True", first_char_index) index = content.find("True", first_char_index)
lst_content[i] = content[:index] + "False" + content[index + 4:] lst_content[i] = (
content[:index] + "False" + content[index + 4 :]
)
i += 1 i += 1
if has_change_manifest: if has_change_manifest:
print(f"Update file {manifest_file}") print(f"Update file {manifest_file}")
with open(manifest_file, 'w') as f: with open(manifest_file, "w") as f:
f.writelines(lst_content) f.writelines(lst_content)
return has_change return has_change
if __name__ == '__main__': if __name__ == "__main__":
main() main()

View file

@ -7,7 +7,7 @@ import git
from unidiff import PatchSet from unidiff import PatchSet
import re import re
new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '..')) new_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
sys.path.append(new_path) sys.path.append(new_path)
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -22,10 +22,10 @@ def get_config():
# TODO update description # TODO update description
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
description='''\ description="""\
''', """,
epilog='''\ epilog="""\
''' """,
) )
args = parser.parse_args() args = parser.parse_args()
return args return args
@ -34,7 +34,10 @@ def get_config():
def main(): def main():
config = get_config() config = get_config()
# rex = r"\s+(?=\d{2}(?:\d{2})?-\d{1,2}-\d{1,2}\b)" # rex = r"\s+(?=\d{2}(?:\d{2})?-\d{1,2}-\d{1,2}\b)"
rex = r"[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]" rex = (
r"[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])"
r" (2[0-3]|[01][0-9]):[0-5][0-9]"
)
# TODO support argument instead of hardcoded values # TODO support argument instead of hardcoded values
lst_path = [ lst_path = [
"./addons/TechnoLibre_odoo-code-generator-template", "./addons/TechnoLibre_odoo-code-generator-template",
@ -56,7 +59,7 @@ def main():
is_modified = False is_modified = False
lst_write_data = [] lst_write_data = []
# Delete code expression path caused by ERPLibre architecture # Delete code expression path caused by ERPLibre architecture
with open(file_real_path, 'r') as file: with open(file_real_path, "r") as file:
lst_data = file.readlines() lst_data = file.readlines()
for data in lst_data: for data in lst_data:
if data.startswith("#: code:addons/addons/"): if data.startswith("#: code:addons/addons/"):
@ -64,7 +67,7 @@ def main():
else: else:
lst_write_data.append(data) lst_write_data.append(data)
if is_modified: if is_modified:
with open(file_real_path, 'w') as file: with open(file_real_path, "w") as file:
file.writelines(lst_write_data) file.writelines(lst_write_data)
str_diff = repo.git.diff(diff.a_path) str_diff = repo.git.diff(diff.a_path)
@ -76,7 +79,10 @@ def main():
nb_line_target = len(hunk.target) nb_line_target = len(hunk.target)
if nb_line_source != nb_line_target: if nb_line_source != nb_line_target:
# TODO support different line # TODO support different line
_logger.warning(f"Source nb line different of target nb line for file {path}/{file_path}.") _logger.warning(
"Source nb line different of target nb line"
f" for file {path}/{file_path}."
)
continue continue
# try: # try:
# assert nb_line_source == nb_line_target, f"Not the same line of diff:\n{str_diff}" # assert nb_line_source == nb_line_target, f"Not the same line of diff:\n{str_diff}"
@ -88,22 +94,27 @@ def main():
result_target = re.split(rex, hunk.target[i]) result_target = re.split(rex, hunk.target[i])
else: else:
result_target = "" result_target = ""
if len(result_source) > 1 or len(result_target) > 1: if (
len(result_source) > 1
or len(result_target) > 1
):
line_to_change = hunk.target_start + i - 1 line_to_change = hunk.target_start + i - 1
lst_to_write.append((line_to_change, hunk.source[i][1:])) lst_to_write.append(
(line_to_change, hunk.source[i][1:])
)
# rewrite # rewrite
rewrite(file_real_path, lst_to_write) rewrite(file_real_path, lst_to_write)
def rewrite(file_path, lst_to_write): def rewrite(file_path, lst_to_write):
# TODO not optimal for big file # TODO not optimal for big file
with open(file_path, 'r') as file: with open(file_path, "r") as file:
data = file.readlines() data = file.readlines()
for line in lst_to_write: for line in lst_to_write:
data[line[0]] = line[1] data[line[0]] = line[1]
with open(file_path, 'w') as file: with open(file_path, "w") as file:
file.writelines(data) file.writelines(data)
if __name__ == '__main__': if __name__ == "__main__":
main() main()