mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
[enh] add support for manifest in toml
This commit is contained in:
parent
9b86a9dd8b
commit
ca9cb79935
1 changed files with 156 additions and 21 deletions
|
@ -41,7 +41,7 @@ from datetime import datetime
|
||||||
|
|
||||||
from moulinette import msignals, m18n, msettings
|
from moulinette import msignals, m18n, msettings
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_json
|
from moulinette.utils.filesystem import read_json, read_toml
|
||||||
|
|
||||||
from yunohost.service import service_log, service_status, _run_service_command
|
from yunohost.service import service_log, service_status, _run_service_command
|
||||||
from yunohost.utils import packages
|
from yunohost.utils import packages
|
||||||
|
@ -271,8 +271,8 @@ def app_list(filter=None, raw=False, installed=False, with_backup=False):
|
||||||
continue
|
continue
|
||||||
# FIXME : What if it's not !?!?
|
# FIXME : What if it's not !?!?
|
||||||
|
|
||||||
with open(os.path.join(APPS_SETTING_PATH, app, 'manifest.json')) as json_manifest:
|
manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
||||||
app_dict[app] = {"manifest": json.load(json_manifest)}
|
app_dict[app] = {"manifest": manifest}
|
||||||
|
|
||||||
app_dict[app]['repository'] = None
|
app_dict[app]['repository'] = None
|
||||||
|
|
||||||
|
@ -365,16 +365,14 @@ def app_info(app, show_status=False, raw=False):
|
||||||
ret['upgradable'] = upgradable
|
ret['upgradable'] = upgradable
|
||||||
ret['change_url'] = os.path.exists(os.path.join(app_setting_path, "scripts", "change_url"))
|
ret['change_url'] = os.path.exists(os.path.join(app_setting_path, "scripts", "change_url"))
|
||||||
|
|
||||||
with open(os.path.join(APPS_SETTING_PATH, app, 'manifest.json')) as json_manifest:
|
manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
||||||
manifest = json.load(json_manifest)
|
|
||||||
|
|
||||||
ret['version'] = manifest.get('version', '-')
|
ret['version'] = manifest.get('version', '-')
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# Retrieve manifest and status
|
# Retrieve manifest and status
|
||||||
with open(app_setting_path + '/manifest.json') as f:
|
manifest = _get_manifest_of_app(app_setting_path)
|
||||||
manifest = json.loads(str(f.read()))
|
|
||||||
status = _get_app_status(app, format_date=True)
|
status = _get_app_status(app, format_date=True)
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
|
@ -490,7 +488,7 @@ def app_change_url(operation_logger, app, domain, path):
|
||||||
))
|
))
|
||||||
raise YunohostError('app_location_unavailable', apps="\n".join(apps))
|
raise YunohostError('app_location_unavailable', apps="\n".join(apps))
|
||||||
|
|
||||||
manifest = json.load(open(os.path.join(APPS_SETTING_PATH, app, "manifest.json")))
|
manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
||||||
|
|
||||||
# Retrieve arguments list for change_url script
|
# Retrieve arguments list for change_url script
|
||||||
# TODO: Allow to specify arguments
|
# TODO: Allow to specify arguments
|
||||||
|
@ -688,8 +686,12 @@ def app_upgrade(app=[], url=None, file=None):
|
||||||
json.dump(status, f)
|
json.dump(status, f)
|
||||||
|
|
||||||
# Replace scripts and manifest and conf (if exists)
|
# Replace scripts and manifest and conf (if exists)
|
||||||
os.system('rm -rf "%s/scripts" "%s/manifest.json %s/conf"' % (app_setting_path, app_setting_path, app_setting_path))
|
os.system('rm -rf "%s/scripts" "%s/manifest.toml %s/manifest.json %s/conf"' % (app_setting_path, app_setting_path, app_setting_path))
|
||||||
os.system('mv "%s/manifest.json" "%s/scripts" %s' % (extracted_app_folder, extracted_app_folder, app_setting_path))
|
|
||||||
|
if os.path.exists(os.path.join(extracted_app_folder, "manifest.json")):
|
||||||
|
os.system('mv "%s/manifest.json" "%s/scripts" %s' % (extracted_app_folder, extracted_app_folder, app_setting_path))
|
||||||
|
if os.path.exists(os.path.join(extracted_app_folder, "manifest.toml")):
|
||||||
|
os.system('mv "%s/manifest.toml" "%s/scripts" %s' % (extracted_app_folder, extracted_app_folder, app_setting_path))
|
||||||
|
|
||||||
for file_to_copy in ["actions.json", "actions.toml", "config_panel.json", "config_panel.toml", "conf"]:
|
for file_to_copy in ["actions.json", "actions.toml", "config_panel.json", "config_panel.toml", "conf"]:
|
||||||
if os.path.exists(os.path.join(extracted_app_folder, file_to_copy)):
|
if os.path.exists(os.path.join(extracted_app_folder, file_to_copy)):
|
||||||
|
@ -730,6 +732,7 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
from yunohost.permission import permission_add, permission_update, permission_remove, permission_sync_to_user
|
from yunohost.permission import permission_add, permission_update, permission_remove, permission_sync_to_user
|
||||||
ldap = _get_ldap_interface()
|
ldap = _get_ldap_interface()
|
||||||
|
|
||||||
|
# Fetch or extract sources
|
||||||
if not os.path.exists(INSTALL_TMP):
|
if not os.path.exists(INSTALL_TMP):
|
||||||
os.makedirs(INSTALL_TMP)
|
os.makedirs(INSTALL_TMP)
|
||||||
|
|
||||||
|
@ -742,7 +745,6 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
}
|
}
|
||||||
|
|
||||||
def confirm_install(confirm):
|
def confirm_install(confirm):
|
||||||
|
|
||||||
# Ignore if there's nothing for confirm (good quality app), if --force is used
|
# Ignore if there's nothing for confirm (good quality app), if --force is used
|
||||||
# or if request on the API (confirm already implemented on the API side)
|
# or if request on the API (confirm already implemented on the API side)
|
||||||
if confirm is None or force or msettings.get('interface') == 'api':
|
if confirm is None or force or msettings.get('interface') == 'api':
|
||||||
|
@ -851,7 +853,10 @@ def app_install(operation_logger, app, label=None, args=None, no_remove_on_failu
|
||||||
# Execute App install script
|
# Execute App install script
|
||||||
os.system('chown -hR admin: %s' % INSTALL_TMP)
|
os.system('chown -hR admin: %s' % INSTALL_TMP)
|
||||||
# Move scripts and manifest to the right place
|
# Move scripts and manifest to the right place
|
||||||
os.system('cp %s/manifest.json %s' % (extracted_app_folder, app_setting_path))
|
if os.path.exists(os.path.join(extracted_app_folder, "manifest.json")):
|
||||||
|
os.system('cp %s/manifest.json %s' % (extracted_app_folder, app_setting_path))
|
||||||
|
if os.path.exists(os.path.join(extracted_app_folder, "manifest.toml")):
|
||||||
|
os.system('cp %s/manifest.toml %s' % (extracted_app_folder, app_setting_path))
|
||||||
os.system('cp -R %s/scripts %s' % (extracted_app_folder, app_setting_path))
|
os.system('cp -R %s/scripts %s' % (extracted_app_folder, app_setting_path))
|
||||||
|
|
||||||
for file_to_copy in ["actions.json", "actions.toml", "config_panel.json", "config_panel.toml", "conf"]:
|
for file_to_copy in ["actions.json", "actions.toml", "config_panel.json", "config_panel.toml", "conf"]:
|
||||||
|
@ -1087,8 +1092,7 @@ def app_debug(app):
|
||||||
Keyword argument:
|
Keyword argument:
|
||||||
app
|
app
|
||||||
"""
|
"""
|
||||||
with open(APPS_SETTING_PATH + app + '/manifest.json') as f:
|
manifest = _get_manifest_of_app(os.path.join(APPS_SETTING_PATH, app))
|
||||||
manifest = json.loads(f.read())
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'name': manifest['id'],
|
'name': manifest['id'],
|
||||||
|
@ -1986,9 +1990,8 @@ def _extract_app_from_file(path, remove=False):
|
||||||
if len(os.listdir(extracted_app_folder)) == 1:
|
if len(os.listdir(extracted_app_folder)) == 1:
|
||||||
for folder in os.listdir(extracted_app_folder):
|
for folder in os.listdir(extracted_app_folder):
|
||||||
extracted_app_folder = extracted_app_folder + '/' + folder
|
extracted_app_folder = extracted_app_folder + '/' + folder
|
||||||
with open(extracted_app_folder + '/manifest.json') as json_manifest:
|
manifest = _get_manifest_of_app(extracted_app_folder)
|
||||||
manifest = json.loads(str(json_manifest.read()))
|
manifest['lastUpdate'] = int(time.time())
|
||||||
manifest['lastUpdate'] = int(time.time())
|
|
||||||
except IOError:
|
except IOError:
|
||||||
raise YunohostError('app_install_files_invalid')
|
raise YunohostError('app_install_files_invalid')
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
|
@ -2000,6 +2003,139 @@ def _extract_app_from_file(path, remove=False):
|
||||||
return manifest, extracted_app_folder
|
return manifest, extracted_app_folder
|
||||||
|
|
||||||
|
|
||||||
|
def _get_manifest_of_app(path):
|
||||||
|
"Get app manifest stored in json or in toml"
|
||||||
|
|
||||||
|
# sample data to get an idea of what is going on
|
||||||
|
# this toml extract:
|
||||||
|
#
|
||||||
|
# license = "free"
|
||||||
|
# url = "https://example.com"
|
||||||
|
# multi_instance = true
|
||||||
|
# version = "1.0~ynh1"
|
||||||
|
# packaging_format = 1
|
||||||
|
# services = ["nginx", "php7.0-fpm", "mysql"]
|
||||||
|
# id = "ynhexample"
|
||||||
|
# name = "YunoHost example app"
|
||||||
|
#
|
||||||
|
# [requirements]
|
||||||
|
# yunohost = ">= 3.5"
|
||||||
|
#
|
||||||
|
# [maintainer]
|
||||||
|
# url = "http://example.com"
|
||||||
|
# name = "John doe"
|
||||||
|
# email = "john.doe@example.com"
|
||||||
|
#
|
||||||
|
# [description]
|
||||||
|
# fr = "Exemple de package d'application pour YunoHost."
|
||||||
|
# en = "Example package for YunoHost application."
|
||||||
|
#
|
||||||
|
# [arguments]
|
||||||
|
# [arguments.install.domain]
|
||||||
|
# type = "domain"
|
||||||
|
# example = "example.com"
|
||||||
|
# [arguments.install.domain.ask]
|
||||||
|
# fr = "Choisissez un nom de domaine pour ynhexample"
|
||||||
|
# en = "Choose a domain name for ynhexample"
|
||||||
|
#
|
||||||
|
# will be parsed into this:
|
||||||
|
#
|
||||||
|
# OrderedDict([(u'license', u'free'),
|
||||||
|
# (u'url', u'https://example.com'),
|
||||||
|
# (u'multi_instance', True),
|
||||||
|
# (u'version', u'1.0~ynh1'),
|
||||||
|
# (u'packaging_format', 1),
|
||||||
|
# (u'services', [u'nginx', u'php7.0-fpm', u'mysql']),
|
||||||
|
# (u'id', u'ynhexample'),
|
||||||
|
# (u'name', u'YunoHost example app'),
|
||||||
|
# (u'requirements', OrderedDict([(u'yunohost', u'>= 3.5')])),
|
||||||
|
# (u'maintainer',
|
||||||
|
# OrderedDict([(u'url', u'http://example.com'),
|
||||||
|
# (u'name', u'John doe'),
|
||||||
|
# (u'email', u'john.doe@example.com')])),
|
||||||
|
# (u'description',
|
||||||
|
# OrderedDict([(u'fr',
|
||||||
|
# u"Exemple de package d'application pour YunoHost."),
|
||||||
|
# (u'en',
|
||||||
|
# u'Example package for YunoHost application.')])),
|
||||||
|
# (u'arguments',
|
||||||
|
# OrderedDict([(u'install',
|
||||||
|
# OrderedDict([(u'domain',
|
||||||
|
# OrderedDict([(u'type', u'domain'),
|
||||||
|
# (u'example',
|
||||||
|
# u'example.com'),
|
||||||
|
# (u'ask',
|
||||||
|
# OrderedDict([(u'fr',
|
||||||
|
# u'Choisissez un nom de domaine pour ynhexample'),
|
||||||
|
# (u'en',
|
||||||
|
# u'Choose a domain name for ynhexample')]))])),
|
||||||
|
#
|
||||||
|
# and needs to be converted into this:
|
||||||
|
#
|
||||||
|
# {
|
||||||
|
# "name": "YunoHost example app",
|
||||||
|
# "id": "ynhexample",
|
||||||
|
# "packaging_format": 1,
|
||||||
|
# "description": {
|
||||||
|
# ¦ "en": "Example package for YunoHost application.",
|
||||||
|
# ¦ "fr": "Exemple de package d’application pour YunoHost."
|
||||||
|
# },
|
||||||
|
# "version": "1.0~ynh1",
|
||||||
|
# "url": "https://example.com",
|
||||||
|
# "license": "free",
|
||||||
|
# "maintainer": {
|
||||||
|
# ¦ "name": "John doe",
|
||||||
|
# ¦ "email": "john.doe@example.com",
|
||||||
|
# ¦ "url": "http://example.com"
|
||||||
|
# },
|
||||||
|
# "requirements": {
|
||||||
|
# ¦ "yunohost": ">= 3.5"
|
||||||
|
# },
|
||||||
|
# "multi_instance": true,
|
||||||
|
# "services": [
|
||||||
|
# ¦ "nginx",
|
||||||
|
# ¦ "php7.0-fpm",
|
||||||
|
# ¦ "mysql"
|
||||||
|
# ],
|
||||||
|
# "arguments": {
|
||||||
|
# ¦ "install" : [
|
||||||
|
# ¦ ¦ {
|
||||||
|
# ¦ ¦ ¦ "name": "domain",
|
||||||
|
# ¦ ¦ ¦ "type": "domain",
|
||||||
|
# ¦ ¦ ¦ "ask": {
|
||||||
|
# ¦ ¦ ¦ ¦ "en": "Choose a domain name for ynhexample",
|
||||||
|
# ¦ ¦ ¦ ¦ "fr": "Choisissez un nom de domaine pour ynhexample"
|
||||||
|
# ¦ ¦ ¦ },
|
||||||
|
# ¦ ¦ ¦ "example": "example.com"
|
||||||
|
# ¦ ¦ },
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(path, "manifest.toml")):
|
||||||
|
manifest_toml = read_toml(os.path.join(path, "manifest.toml"))
|
||||||
|
|
||||||
|
manifest = manifest_toml.copy()
|
||||||
|
|
||||||
|
if "arguments" not in manifest:
|
||||||
|
return manifest
|
||||||
|
|
||||||
|
if "install" not in manifest["arguments"]:
|
||||||
|
return manifest
|
||||||
|
|
||||||
|
install_arguments = []
|
||||||
|
for name, values in manifest_toml.get("arguments", {}).get("install", {}).items():
|
||||||
|
args = values.copy()
|
||||||
|
args["name"] = name
|
||||||
|
|
||||||
|
install_arguments.append(args)
|
||||||
|
|
||||||
|
manifest["arguments"]["install"] = install_arguments
|
||||||
|
|
||||||
|
return manifest
|
||||||
|
elif os.path.exists(os.path.join(path, "manifest.json")):
|
||||||
|
return read_json(os.path.join(path, "manifest.json"))
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _get_git_last_commit_hash(repository, reference='HEAD'):
|
def _get_git_last_commit_hash(repository, reference='HEAD'):
|
||||||
"""
|
"""
|
||||||
Attempt to retrieve the last commit hash of a git repository
|
Attempt to retrieve the last commit hash of a git repository
|
||||||
|
@ -2080,8 +2216,7 @@ def _fetch_app_from_git(app):
|
||||||
subprocess.check_call([
|
subprocess.check_call([
|
||||||
'git', 'reset', '--hard', branch
|
'git', 'reset', '--hard', branch
|
||||||
], cwd=extracted_app_folder)
|
], cwd=extracted_app_folder)
|
||||||
with open(extracted_app_folder + '/manifest.json') as f:
|
manifest = _get_manifest_of_app(extracted_app_folder)
|
||||||
manifest = json.loads(str(f.read()))
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise YunohostError('app_sources_fetch_failed')
|
raise YunohostError('app_sources_fetch_failed')
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
|
@ -2133,8 +2268,7 @@ def _fetch_app_from_git(app):
|
||||||
'git', 'reset', '--hard',
|
'git', 'reset', '--hard',
|
||||||
str(app_info['git']['revision'])
|
str(app_info['git']['revision'])
|
||||||
], cwd=extracted_app_folder)
|
], cwd=extracted_app_folder)
|
||||||
with open(extracted_app_folder + '/manifest.json') as f:
|
manifest = _get_manifest_of_app(extracted_app_folder)
|
||||||
manifest = json.loads(str(f.read()))
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
raise YunohostError('app_sources_fetch_failed')
|
raise YunohostError('app_sources_fetch_failed')
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
|
@ -2762,6 +2896,7 @@ def _patch_php5(app_folder):
|
||||||
files_to_patch.extend(glob.glob("%s/scripts/*" % app_folder))
|
files_to_patch.extend(glob.glob("%s/scripts/*" % app_folder))
|
||||||
files_to_patch.extend(glob.glob("%s/scripts/.*" % app_folder))
|
files_to_patch.extend(glob.glob("%s/scripts/.*" % app_folder))
|
||||||
files_to_patch.append("%s/manifest.json" % app_folder)
|
files_to_patch.append("%s/manifest.json" % app_folder)
|
||||||
|
files_to_patch.append("%s/manifest.toml" % app_folder)
|
||||||
|
|
||||||
for filename in files_to_patch:
|
for filename in files_to_patch:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue