[ADD] installation: add optional extra modules (CybroOdoo)
CybroOdoo repos are large and slow to clone, making them unsuitable for default installation. Moves them to opt-in per-version extra manifests, introduces .erplibre-state.json to track installation options per Odoo version, and surfaces the choice in the TODO CLI sub-menu. Switch auto-detects extra from state and warns when no state is recorded. Generated by Claude Code 2.1.87 model claude-sonnet-4-6 Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
This commit is contained in:
parent
795d4a0904
commit
32315a2dba
20 changed files with 420 additions and 76 deletions
|
|
@ -113,6 +113,38 @@ switch_odoo_12_update:
|
||||||
./script/version/update_env_version.py --erplibre_version odoo12.0_python3.7.17 --switch --switch_update
|
./script/version/update_env_version.py --erplibre_version odoo12.0_python3.7.17 --switch --switch_update
|
||||||
./script/make.sh config_gen_all
|
./script/make.sh config_gen_all
|
||||||
|
|
||||||
|
####################
|
||||||
|
# INSTALL WITH EXTRA (CybroOdoo)
|
||||||
|
####################
|
||||||
|
|
||||||
|
.PHONY: install_odoo_18_with_extra
|
||||||
|
install_odoo_18_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo18.0_python3.12.10 --install_dev --with_extra
|
||||||
|
|
||||||
|
.PHONY: install_odoo_17_with_extra
|
||||||
|
install_odoo_17_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo17.0_python3.10.18 --install_dev --with_extra
|
||||||
|
|
||||||
|
.PHONY: install_odoo_16_with_extra
|
||||||
|
install_odoo_16_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo16.0_python3.10.18 --install_dev --with_extra
|
||||||
|
|
||||||
|
.PHONY: install_odoo_15_with_extra
|
||||||
|
install_odoo_15_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo15.0_python3.8.20 --install_dev --with_extra
|
||||||
|
|
||||||
|
.PHONY: install_odoo_14_with_extra
|
||||||
|
install_odoo_14_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo14.0_python3.8.20 --install_dev --with_extra
|
||||||
|
|
||||||
|
.PHONY: install_odoo_13_with_extra
|
||||||
|
install_odoo_13_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo13.0_python3.7.17 --install_dev --with_extra
|
||||||
|
|
||||||
|
.PHONY: install_odoo_12_with_extra
|
||||||
|
install_odoo_12_with_extra:
|
||||||
|
./script/version/update_env_version.py --erplibre_version odoo12.0_python3.7.17 --install_dev --with_extra
|
||||||
|
|
||||||
.PHONY: install_odoo_all_version
|
.PHONY: install_odoo_all_version
|
||||||
install_odoo_all_version:
|
install_odoo_all_version:
|
||||||
./script/make.sh install_odoo_18
|
./script/make.sh install_odoo_18
|
||||||
|
|
|
||||||
12
manifest/git_manifest_extra_odoo12.0.xml
Normal file
12
manifest/git_manifest_extra_odoo12.0.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="ERPLibre_origin_CybroOdoo" fetch="https://github.com/ERPLibre/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
path="odoo12.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="ERPLibre_origin_CybroOdoo"
|
||||||
|
revision="dev_12.0"
|
||||||
|
groups="extra,odoo12.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
12
manifest/git_manifest_extra_odoo13.0.xml
Normal file
12
manifest/git_manifest_extra_odoo13.0.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="CybroOdoo" fetch="https://github.com/CybroOdoo/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
path="odoo13.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
revision="13.0"
|
||||||
|
groups="extra,odoo13.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
12
manifest/git_manifest_extra_odoo14.0.xml
Normal file
12
manifest/git_manifest_extra_odoo14.0.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="CybroOdoo" fetch="https://github.com/CybroOdoo/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
path="odoo14.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
revision="14.0"
|
||||||
|
groups="extra,odoo14.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
12
manifest/git_manifest_extra_odoo15.0.xml
Normal file
12
manifest/git_manifest_extra_odoo15.0.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="CybroOdoo" fetch="https://github.com/CybroOdoo/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
path="odoo15.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
revision="15.0"
|
||||||
|
groups="extra,odoo15.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
21
manifest/git_manifest_extra_odoo16.0.xml
Normal file
21
manifest/git_manifest_extra_odoo16.0.xml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="CybroOdoo" fetch="https://github.com/CybroOdoo/" />
|
||||||
|
<remote name="ERPLibre" fetch="https://github.com/ERPLibre/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
revision="16.0"
|
||||||
|
path="odoo16.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
groups="extra,odoo16.0"
|
||||||
|
/>
|
||||||
|
<project
|
||||||
|
name="CybroAddons.git"
|
||||||
|
path="odoo16.0/addons/CybroOdoo_CybroAddons"
|
||||||
|
remote="ERPLibre"
|
||||||
|
clone-depth="1"
|
||||||
|
revision="16.0_dev"
|
||||||
|
groups="extra,odoo16.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
20
manifest/git_manifest_extra_odoo17.0.xml
Normal file
20
manifest/git_manifest_extra_odoo17.0.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="CybroOdoo" fetch="https://github.com/CybroOdoo/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
path="odoo17.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
revision="17.0"
|
||||||
|
groups="extra,odoo17.0"
|
||||||
|
/>
|
||||||
|
<project
|
||||||
|
name="CybroAddons.git"
|
||||||
|
path="odoo17.0/addons/CybroOdoo_CybroAddons"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
clone-depth="1"
|
||||||
|
revision="17.0"
|
||||||
|
groups="extra,odoo17.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
21
manifest/git_manifest_extra_odoo18.0.xml
Normal file
21
manifest/git_manifest_extra_odoo18.0.xml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<manifest>
|
||||||
|
<remote name="CybroOdoo" fetch="https://github.com/CybroOdoo/" />
|
||||||
|
<remote name="ERPLibre_origin_CybroOdoo" fetch="https://github.com/ERPLibre/" />
|
||||||
|
|
||||||
|
<project
|
||||||
|
name="OpenHRMS.git"
|
||||||
|
revision="18.0"
|
||||||
|
path="odoo18.0/addons/CybroOdoo_OpenHRMS"
|
||||||
|
remote="CybroOdoo"
|
||||||
|
groups="extra,odoo18.0"
|
||||||
|
/>
|
||||||
|
<project
|
||||||
|
name="CybroAddons.git"
|
||||||
|
path="odoo18.0/addons/CybroOdoo_CybroAddons"
|
||||||
|
remote="ERPLibre_origin_CybroOdoo"
|
||||||
|
clone-depth="1"
|
||||||
|
revision="18.0_dev"
|
||||||
|
groups="extra,odoo18.0"
|
||||||
|
/>
|
||||||
|
</manifest>
|
||||||
|
|
@ -26,13 +26,6 @@
|
||||||
<remote name="ERPLibre_origin_pledra" fetch="https://github.com/ERPLibre/" />
|
<remote name="ERPLibre_origin_pledra" fetch="https://github.com/ERPLibre/" />
|
||||||
<remote name="ERPLibre_origin_tegin" fetch="https://github.com/ERPLibre/" />
|
<remote name="ERPLibre_origin_tegin" fetch="https://github.com/ERPLibre/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
path="odoo12.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="ERPLibre_origin_CybroOdoo"
|
|
||||||
revision="dev_12.0"
|
|
||||||
groups="addons,odoo12.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="Property-Management_odoo.git"
|
name="Property-Management_odoo.git"
|
||||||
path="odoo12.0/addons/kinjal-sorathiya_Property-Management_odoo"
|
path="odoo12.0/addons/kinjal-sorathiya_Property-Management_odoo"
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,6 @@
|
||||||
<remote name="pledra" fetch="https://github.com/pledra/" />
|
<remote name="pledra" fetch="https://github.com/pledra/" />
|
||||||
<remote name="tegin" fetch="https://github.com/tegin/" />
|
<remote name="tegin" fetch="https://github.com/tegin/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
path="odoo13.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
revision="13.0"
|
|
||||||
groups="addons,odoo13.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="access-addons.git"
|
name="access-addons.git"
|
||||||
path="odoo13.0/addons/itpp-labs_access-addons"
|
path="odoo13.0/addons/itpp-labs_access-addons"
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,6 @@
|
||||||
<remote name="pledra" fetch="https://github.com/pledra/" />
|
<remote name="pledra" fetch="https://github.com/pledra/" />
|
||||||
<remote name="tegin" fetch="https://github.com/tegin/" />
|
<remote name="tegin" fetch="https://github.com/tegin/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
path="odoo14.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
revision="14.0"
|
|
||||||
groups="addons,odoo14.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="access-addons.git"
|
name="access-addons.git"
|
||||||
path="odoo14.0/addons/itpp-labs_access-addons"
|
path="odoo14.0/addons/itpp-labs_access-addons"
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,6 @@
|
||||||
<remote name="pledra" fetch="https://github.com/pledra/" />
|
<remote name="pledra" fetch="https://github.com/pledra/" />
|
||||||
<remote name="tegin" fetch="https://github.com/tegin/" />
|
<remote name="tegin" fetch="https://github.com/tegin/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
path="odoo15.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
revision="15.0"
|
|
||||||
groups="addons,odoo15.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="access-addons.git"
|
name="access-addons.git"
|
||||||
path="odoo15.0/addons/itpp-labs_access-addons"
|
path="odoo15.0/addons/itpp-labs_access-addons"
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,6 @@
|
||||||
<remote name="pledra" fetch="https://github.com/pledra/" />
|
<remote name="pledra" fetch="https://github.com/pledra/" />
|
||||||
<remote name="tegin" fetch="https://github.com/tegin/" />
|
<remote name="tegin" fetch="https://github.com/tegin/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
revision="16.0"
|
|
||||||
path="odoo16.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
groups="addons,odoo16.0"
|
|
||||||
/>
|
|
||||||
<project
|
|
||||||
name="CybroAddons.git"
|
|
||||||
path="odoo16.0/addons/CybroOdoo_CybroAddons"
|
|
||||||
remote="ERPLibre"
|
|
||||||
clone-depth="1"
|
|
||||||
revision="16.0_dev"
|
|
||||||
groups="addons,odoo16.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="account-analytic.git"
|
name="account-analytic.git"
|
||||||
revision="16.0"
|
revision="16.0"
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,6 @@
|
||||||
<remote name="pledra" fetch="https://github.com/pledra/" />
|
<remote name="pledra" fetch="https://github.com/pledra/" />
|
||||||
<remote name="tegin" fetch="https://github.com/tegin/" />
|
<remote name="tegin" fetch="https://github.com/tegin/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
path="odoo17.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
revision="17.0"
|
|
||||||
groups="addons,odoo17.0"
|
|
||||||
/>
|
|
||||||
<project
|
|
||||||
name="CybroAddons.git"
|
|
||||||
path="odoo17.0/addons/CybroOdoo_CybroAddons"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
clone-depth="1"
|
|
||||||
revision="17.0"
|
|
||||||
groups="addons,odoo17.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="account-analytic.git"
|
name="account-analytic.git"
|
||||||
path="odoo17.0/addons/OCA_account-analytic"
|
path="odoo17.0/addons/OCA_account-analytic"
|
||||||
|
|
|
||||||
|
|
@ -33,21 +33,6 @@
|
||||||
<remote name="pledra" fetch="https://github.com/pledra/" />
|
<remote name="pledra" fetch="https://github.com/pledra/" />
|
||||||
<remote name="tegin" fetch="https://github.com/tegin/" />
|
<remote name="tegin" fetch="https://github.com/tegin/" />
|
||||||
|
|
||||||
<project
|
|
||||||
name="OpenHRMS.git"
|
|
||||||
revision="18.0"
|
|
||||||
path="odoo18.0/addons/CybroOdoo_OpenHRMS"
|
|
||||||
remote="CybroOdoo"
|
|
||||||
groups="addons,odoo18.0"
|
|
||||||
/>
|
|
||||||
<project
|
|
||||||
name="CybroAddons.git"
|
|
||||||
path="odoo18.0/addons/CybroOdoo_CybroAddons"
|
|
||||||
remote="ERPLibre_origin_CybroOdoo"
|
|
||||||
clone-depth="1"
|
|
||||||
revision="18.0_dev"
|
|
||||||
groups="addons,odoo18.0"
|
|
||||||
/>
|
|
||||||
<project
|
<project
|
||||||
name="account-analytic.git"
|
name="account-analytic.git"
|
||||||
revision="18.0"
|
revision="18.0"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ new_path = os.path.normpath(
|
||||||
sys.path.append(new_path)
|
sys.path.append(new_path)
|
||||||
|
|
||||||
from script.git.git_tool import GitTool
|
from script.git.git_tool import GitTool
|
||||||
|
from script.version.erplibre_state import get_version_extra
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -69,6 +70,14 @@ def get_config():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Add mobile project manifest",
|
help="Add mobile project manifest",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--with_extra",
|
||||||
|
action="store_true",
|
||||||
|
help=(
|
||||||
|
"Add extra modules manifest for current Odoo version"
|
||||||
|
" (e.g. CybroOdoo). Version read from .odoo-version."
|
||||||
|
),
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--with_new_manifest",
|
"--with_new_manifest",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
|
|
@ -93,6 +102,8 @@ def main():
|
||||||
config.with_OCA = True
|
config.with_OCA = True
|
||||||
if os.path.isdir(MOBILE_PATH):
|
if os.path.isdir(MOBILE_PATH):
|
||||||
config.with_mobile = True
|
config.with_mobile = True
|
||||||
|
if odoo_version and get_version_extra(odoo_version.strip()):
|
||||||
|
config.with_extra = True
|
||||||
|
|
||||||
input_paths = config.input
|
input_paths = config.input
|
||||||
if not input_paths:
|
if not input_paths:
|
||||||
|
|
@ -144,6 +155,15 @@ def main():
|
||||||
append_file_path_manifest(
|
append_file_path_manifest(
|
||||||
input_paths, DEFAULT_PATH_MANIFEST_MOBILE_CONF
|
input_paths, DEFAULT_PATH_MANIFEST_MOBILE_CONF
|
||||||
)
|
)
|
||||||
|
if config.with_extra and odoo_version:
|
||||||
|
path_extra = os.path.join(
|
||||||
|
"manifest",
|
||||||
|
f"git_manifest_extra_odoo{odoo_version.strip()}.xml",
|
||||||
|
)
|
||||||
|
if os.path.exists(path_extra):
|
||||||
|
input_paths.append(path_extra)
|
||||||
|
else:
|
||||||
|
print(f"WARNING: {path_extra} does not exist, skipping extra")
|
||||||
if not config.with_mobile or not config.with_OCA:
|
if not config.with_mobile or not config.with_OCA:
|
||||||
append_file_path_manifest(input_paths, DEFAULT_PATH_MANIFEST_CONF)
|
append_file_path_manifest(input_paths, DEFAULT_PATH_MANIFEST_CONF)
|
||||||
append_file_path_manifest(
|
append_file_path_manifest(
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,37 @@ class TODO:
|
||||||
return
|
return
|
||||||
|
|
||||||
cmd_intern = install_commands.get(odoo_version_input)[2]
|
cmd_intern = install_commands.get(odoo_version_input)[2]
|
||||||
|
|
||||||
|
# For numbered version selections, offer extra modules sub-menu
|
||||||
|
if odoo_version_input.isdigit():
|
||||||
|
extra_choices = {
|
||||||
|
"1": (
|
||||||
|
"1",
|
||||||
|
f"1: {t('Standard install (without extra modules)')}",
|
||||||
|
),
|
||||||
|
"2": (
|
||||||
|
"2",
|
||||||
|
f"2: {t('Install with extra modules (CybroOdoo - large, slow)')}",
|
||||||
|
),
|
||||||
|
"0": ("0", f"0: {t('Back')}"),
|
||||||
|
}
|
||||||
|
extra_input = ""
|
||||||
|
while extra_input not in extra_choices:
|
||||||
|
if extra_input:
|
||||||
|
print(
|
||||||
|
f"{t('Error, cannot understand value')} '{extra_input}'"
|
||||||
|
)
|
||||||
|
str_extra = (
|
||||||
|
f"💬 {t('Install type:')}\n\t"
|
||||||
|
+ "\n\t".join([a[1] for a in extra_choices.values()])
|
||||||
|
+ f"\n{t('Select: ')}"
|
||||||
|
)
|
||||||
|
extra_input = input(str_extra).strip()
|
||||||
|
if extra_input == "0":
|
||||||
|
return
|
||||||
|
if extra_input == "2":
|
||||||
|
cmd_intern = cmd_intern + " --with_extra"
|
||||||
|
|
||||||
print(f"{t('Will execute:')}\n{cmd_intern}")
|
print(f"{t('Will execute:')}\n{cmd_intern}")
|
||||||
|
|
||||||
# TODO use external script to detect terminal to use on system
|
# TODO use external script to detect terminal to use on system
|
||||||
|
|
|
||||||
|
|
@ -367,6 +367,18 @@ TRANSLATIONS = {
|
||||||
"fr": "Choisir une version :",
|
"fr": "Choisir une version :",
|
||||||
"en": "Choose a version:",
|
"en": "Choose a version:",
|
||||||
},
|
},
|
||||||
|
"Install type:": {
|
||||||
|
"fr": "Type d'installation :",
|
||||||
|
"en": "Install type:",
|
||||||
|
},
|
||||||
|
"Standard install (without extra modules)": {
|
||||||
|
"fr": "Installation standard (sans modules extra)",
|
||||||
|
"en": "Standard install (without extra modules)",
|
||||||
|
},
|
||||||
|
"Install with extra modules (CybroOdoo - large, slow)": {
|
||||||
|
"fr": "Installation avec modules extra (CybroOdoo - gros, lent)",
|
||||||
|
"en": "Install with extra modules (CybroOdoo - large, slow)",
|
||||||
|
},
|
||||||
# todo.json translatable prompt_descriptions
|
# todo.json translatable prompt_descriptions
|
||||||
"Test - Minimal base instance": {
|
"Test - Minimal base instance": {
|
||||||
"fr": "Test - Instance de base minimale",
|
"fr": "Test - Instance de base minimale",
|
||||||
|
|
|
||||||
161
script/version/erplibre_state.py
Normal file
161
script/version/erplibre_state.py
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# © 2026 TechnoLibre (http://www.technolibre.ca)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Utility module for reading and writing .erplibre-state.json.
|
||||||
|
|
||||||
|
This file tracks what is installed in the current ERPLibre workspace:
|
||||||
|
- Which Odoo versions are installed, and with which options (extra, etc.)
|
||||||
|
- Whether the mobile project is active
|
||||||
|
- The currently active Odoo version
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
STATE_FILE = ".erplibre-state.json"
|
||||||
|
|
||||||
|
_EMPTY_VERSION_ENTRY = {
|
||||||
|
"installed": False,
|
||||||
|
"extra": False,
|
||||||
|
"python": None,
|
||||||
|
"poetry": None,
|
||||||
|
"installed_at": None,
|
||||||
|
"switched_at": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
_EMPTY_STATE = {
|
||||||
|
"current_odoo_version": None,
|
||||||
|
"mobile": {
|
||||||
|
"active": False,
|
||||||
|
"installed_at": None,
|
||||||
|
},
|
||||||
|
"odoo_versions": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def read_state() -> dict:
|
||||||
|
"""Return the current state, or an empty state if the file does not exist."""
|
||||||
|
if not os.path.isfile(STATE_FILE):
|
||||||
|
return _deep_copy(_EMPTY_STATE)
|
||||||
|
try:
|
||||||
|
with open(STATE_FILE, "r", encoding="utf-8") as f:
|
||||||
|
return json.load(f)
|
||||||
|
except (json.JSONDecodeError, OSError) as e:
|
||||||
|
_logger.warning(f"Cannot read {STATE_FILE}: {e}. Using empty state.")
|
||||||
|
return _deep_copy(_EMPTY_STATE)
|
||||||
|
|
||||||
|
|
||||||
|
def write_state(state: dict) -> None:
|
||||||
|
"""Persist state to .erplibre-state.json."""
|
||||||
|
with open(STATE_FILE, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(state, f, indent=4, ensure_ascii=False)
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def set_version_installed(
|
||||||
|
odoo_version: str,
|
||||||
|
extra: bool = False,
|
||||||
|
python: str = None,
|
||||||
|
poetry: str = None,
|
||||||
|
) -> None:
|
||||||
|
"""Record that an Odoo version has been installed (or reinstalled)."""
|
||||||
|
state = read_state()
|
||||||
|
entry = state["odoo_versions"].get(odoo_version, _deep_copy(_EMPTY_VERSION_ENTRY))
|
||||||
|
entry["installed"] = True
|
||||||
|
entry["extra"] = extra
|
||||||
|
if python:
|
||||||
|
entry["python"] = python
|
||||||
|
if poetry:
|
||||||
|
entry["poetry"] = poetry
|
||||||
|
entry["installed_at"] = str(date.today())
|
||||||
|
state["odoo_versions"][odoo_version] = entry
|
||||||
|
state["current_odoo_version"] = odoo_version
|
||||||
|
write_state(state)
|
||||||
|
_logger.info(
|
||||||
|
f"State updated: odoo {odoo_version} installed"
|
||||||
|
f" (extra={extra}, python={python}, poetry={poetry})"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def set_version_switched(odoo_version: str) -> None:
|
||||||
|
"""Record that the workspace was switched to an Odoo version."""
|
||||||
|
state = read_state()
|
||||||
|
entry = state["odoo_versions"].get(odoo_version, _deep_copy(_EMPTY_VERSION_ENTRY))
|
||||||
|
entry["switched_at"] = str(date.today())
|
||||||
|
state["odoo_versions"][odoo_version] = entry
|
||||||
|
state["current_odoo_version"] = odoo_version
|
||||||
|
write_state(state)
|
||||||
|
|
||||||
|
|
||||||
|
def set_mobile_active(active: bool) -> None:
|
||||||
|
"""Record whether the mobile project is currently synced."""
|
||||||
|
state = read_state()
|
||||||
|
state["mobile"]["active"] = active
|
||||||
|
if active:
|
||||||
|
state["mobile"]["installed_at"] = str(date.today())
|
||||||
|
write_state(state)
|
||||||
|
_logger.info(f"State updated: mobile active={active}")
|
||||||
|
|
||||||
|
|
||||||
|
def get_version_extra(odoo_version: str) -> bool:
|
||||||
|
"""Return True if the given Odoo version was installed with extra modules."""
|
||||||
|
state = read_state()
|
||||||
|
entry = state["odoo_versions"].get(odoo_version)
|
||||||
|
if entry is None:
|
||||||
|
return False
|
||||||
|
return bool(entry.get("extra", False))
|
||||||
|
|
||||||
|
|
||||||
|
def get_version_installed(odoo_version: str) -> bool:
|
||||||
|
"""Return True if the given Odoo version has an installation record."""
|
||||||
|
state = read_state()
|
||||||
|
entry = state["odoo_versions"].get(odoo_version)
|
||||||
|
if entry is None:
|
||||||
|
return False
|
||||||
|
return bool(entry.get("installed", False))
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_version() -> str | None:
|
||||||
|
"""Return the currently active Odoo version, or None."""
|
||||||
|
return read_state().get("current_odoo_version")
|
||||||
|
|
||||||
|
|
||||||
|
def get_mobile_active() -> bool:
|
||||||
|
"""Return True if mobile is recorded as active."""
|
||||||
|
return bool(read_state().get("mobile", {}).get("active", False))
|
||||||
|
|
||||||
|
|
||||||
|
def print_state() -> None:
|
||||||
|
"""Log a human-readable summary of the current state."""
|
||||||
|
state = read_state()
|
||||||
|
current = state.get("current_odoo_version") or "unknown"
|
||||||
|
mobile = state.get("mobile", {})
|
||||||
|
mobile_status = "active" if mobile.get("active") else "inactive"
|
||||||
|
|
||||||
|
_logger.info(f"Current Odoo version : {current}")
|
||||||
|
_logger.info(f"Mobile context : {mobile_status}")
|
||||||
|
|
||||||
|
versions = state.get("odoo_versions", {})
|
||||||
|
if versions:
|
||||||
|
installed = [
|
||||||
|
f"{v}{' +extra' if d.get('extra') else ''}"
|
||||||
|
for v, d in sorted(versions.items())
|
||||||
|
if d.get("installed")
|
||||||
|
]
|
||||||
|
if installed:
|
||||||
|
_logger.info(f"Installed versions : {', '.join(installed)}")
|
||||||
|
else:
|
||||||
|
_logger.info("Installed versions : none recorded")
|
||||||
|
else:
|
||||||
|
_logger.info("Installed versions : none recorded")
|
||||||
|
|
||||||
|
|
||||||
|
def _deep_copy(d: dict) -> dict:
|
||||||
|
"""Simple deep copy for plain dicts/lists (no external deps)."""
|
||||||
|
return json.loads(json.dumps(d))
|
||||||
|
|
@ -12,6 +12,21 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
# erplibre_state is in the same directory; import lazily to avoid hard failure
|
||||||
|
# when the script runs outside the project root (e.g. during bare install).
|
||||||
|
try:
|
||||||
|
from script.version.erplibre_state import (
|
||||||
|
get_version_extra,
|
||||||
|
get_version_installed,
|
||||||
|
print_state,
|
||||||
|
set_version_installed,
|
||||||
|
set_version_switched,
|
||||||
|
)
|
||||||
|
|
||||||
|
_STATE_AVAILABLE = True
|
||||||
|
except ImportError:
|
||||||
|
_STATE_AVAILABLE = False
|
||||||
|
|
||||||
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
@ -124,6 +139,14 @@ def get_config():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Force all, include force_install, force_repo.",
|
help="Force all, include force_install, force_repo.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--with_extra",
|
||||||
|
action="store_true",
|
||||||
|
help=(
|
||||||
|
"Install or switch with extra modules (e.g. CybroOdoo)."
|
||||||
|
" State is saved in .erplibre-state.json."
|
||||||
|
),
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.force:
|
if args.force:
|
||||||
|
|
@ -200,6 +223,11 @@ class Update:
|
||||||
_logger.info(
|
_logger.info(
|
||||||
f"Mobile context: {'active (' + MOBILE_PATH + ')' if self.mobile_active else 'inactive'}"
|
f"Mobile context: {'active (' + MOBILE_PATH + ')' if self.mobile_active else 'inactive'}"
|
||||||
)
|
)
|
||||||
|
if _STATE_AVAILABLE:
|
||||||
|
extra = get_version_extra(self.odoo_version)
|
||||||
|
_logger.info(
|
||||||
|
f"Extra modules (CybroOdoo): {'active' if extra else 'inactive'}"
|
||||||
|
)
|
||||||
erplibre_version_to_search = ERPLIBRE_TEMPLATE_VERSION % (
|
erplibre_version_to_search = ERPLIBRE_TEMPLATE_VERSION % (
|
||||||
self.odoo_version,
|
self.odoo_version,
|
||||||
self.python_version,
|
self.python_version,
|
||||||
|
|
@ -413,15 +441,38 @@ class Update:
|
||||||
if self.config.install_dev:
|
if self.config.install_dev:
|
||||||
_logger.info("Installation.")
|
_logger.info("Installation.")
|
||||||
status = self.install_erplibre()
|
status = self.install_erplibre()
|
||||||
|
if _STATE_AVAILABLE and not status:
|
||||||
|
set_version_installed(
|
||||||
|
self.new_version_odoo,
|
||||||
|
extra=bool(self.config.with_extra),
|
||||||
|
python=self.new_version_python,
|
||||||
|
poetry=self.new_version_poetry,
|
||||||
|
)
|
||||||
elif (
|
elif (
|
||||||
self.config.is_in_switch
|
self.config.is_in_switch
|
||||||
and self.config.is_in_switch_force_update
|
and self.config.is_in_switch_force_update
|
||||||
):
|
):
|
||||||
_logger.info("Switch")
|
_logger.info("Switch")
|
||||||
self.execute_log.append(f"System update")
|
self.execute_log.append(f"System update")
|
||||||
status = os.system(
|
# Auto-detect extra from state, warn if no state recorded
|
||||||
"./script/manifest/update_manifest_local_dev.sh"
|
with_extra = bool(self.config.with_extra)
|
||||||
)
|
if _STATE_AVAILABLE and not with_extra:
|
||||||
|
if not get_version_installed(self.new_version_odoo):
|
||||||
|
_logger.warning(
|
||||||
|
f"No installation state found for odoo"
|
||||||
|
f" {self.new_version_odoo}. Proceeding without"
|
||||||
|
f" extra modules (CybroOdoo). To install with"
|
||||||
|
f" extra: make"
|
||||||
|
f" install_odoo_{self.new_version_odoo.replace('.', '')}_with_extra"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
with_extra = get_version_extra(self.new_version_odoo)
|
||||||
|
manifest_script = "./script/manifest/update_manifest_local_dev.sh"
|
||||||
|
if with_extra:
|
||||||
|
manifest_script += " --with_extra"
|
||||||
|
status = os.system(manifest_script)
|
||||||
|
if _STATE_AVAILABLE and not status:
|
||||||
|
set_version_switched(self.new_version_odoo)
|
||||||
|
|
||||||
# To support multiple addons directory, remove TEMP
|
# To support multiple addons directory, remove TEMP
|
||||||
# for addons_path in os.listdir("."):
|
# for addons_path in os.listdir("."):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue