1
0
Fork 0
mirror of https://github.com/YunoHost/apps.git synced 2024-09-03 20:06:07 +02:00

Merge branch 'update_app_levels' of https://github.com/YunoHost/apps into update_app_levels

This commit is contained in:
Éric Gaspar 2024-07-20 09:44:09 +02:00
commit 3a44c9b426
10 changed files with 810 additions and 90 deletions

View file

@ -202,7 +202,7 @@ url = "https://github.com/YunoHost-Apps/backdrop_ynh"
[baikal]
added_date = 1674232499 # 2023/01/20
category = "synchronization"
level = 8
level = 6
potential_alternative_to = [ "Microsoft Outlook" ]
state = "working"
subtags = [ "calendar", "contacts" ]
@ -245,7 +245,7 @@ added_date = 1674232499 # 2023/01/20
antifeatures = [ "deprecated-software" ]
category = "publishing"
deprecated_date = 1717071136 # 2024/05/30
level = 7
level = 6
potential_alternative_to = [ "Blogger", "Coldfusion", "Wix" ]
state = "working"
subtags = [ "blog" ]
@ -339,6 +339,14 @@ state = "working"
subtags = [ "monitoring" ]
url = "https://github.com/YunoHost-Apps/cachet_ynh"
[caerp]
added_date = 1674232499 # 2023/01/20
category = "productivity_and_management"
level = 0
state = "notworking"
subtags = [ "accounting", "business_and_ngos" ]
url = "https://github.com/Yunohost-Apps/caerp_ynh"
[calckey]
added_date = 1674232499 # 2023/01/20
antifeatures = [ "deprecated-software" ]
@ -535,7 +543,7 @@ url = "https://github.com/YunoHost-Apps/concrete5_ynh"
[conduit]
added_date = 1691780437 # 2023/08/11
category = "communication"
level = 7
level = 8
potential_alternative_to = [ "Discord", "Facebook Messenger", "Signal", "Skype", "Telegram", "Whatsapp" ]
state = "working"
subtags = [ "chat" ]
@ -606,7 +614,7 @@ url = "https://github.com/YunoHost-Apps/crabfit_ynh"
[cryptpad]
added_date = 1674232499 # 2023/01/20
category = "office"
level = 6
level = 8
potential_alternative_to = [ "Google Docs" ]
state = "working"
subtags = [ "text" ]
@ -681,7 +689,7 @@ url = "https://github.com/YunoHost-Apps/dendrite_ynh"
[dex]
added_date = 1674232499 # 2023/01/20
category = "system_tools"
level = 6
level = 8
state = "working"
subtags = [ "network" ]
url = "https://github.com/YunoHost-Apps/dex_ynh"
@ -716,7 +724,7 @@ url = "https://github.com/YunoHost-Apps/diaspora_ynh"
[digiscreen]
added_date = 1674232499 # 2023/01/20
category = "wat"
level = 6
level = 0
state = "working"
url = "https://github.com/YunoHost-Apps/digiscreen_ynh"
@ -730,7 +738,7 @@ url = "https://github.com/YunoHost-Apps/digisteps_ynh"
[digitools]
added_date = 1674232499 # 2023/01/20
category = "small_utilities"
level = 8
level = 0
state = "working"
url = "https://github.com/YunoHost-Apps/digitools_ynh"
@ -802,7 +810,7 @@ url = "https://github.com/YunoHost-Apps/django-for-runners_ynh"
[django-fritzconnection]
added_date = 1674232499 # 2023/01/20
category = "system_tools"
level = 3
level = 8
state = "working"
subtags = [ "network" ]
url = "https://github.com/YunoHost-Apps/django-fritzconnection_ynh"
@ -810,7 +818,7 @@ url = "https://github.com/YunoHost-Apps/django-fritzconnection_ynh"
[django_example]
added_date = 1674232499 # 2023/01/20
category = "dev"
level = 8
level = 3
state = "working"
subtags = [ "programming" ]
url = "https://github.com/YunoHost-Apps/django_example_ynh"
@ -851,7 +859,7 @@ url = "https://github.com/YunoHost-Apps/domoticz_ynh"
added_date = 1674232499 # 2023/01/20
branch = "main"
category = "dev"
level = 8
level = 0
state = "working"
subtags = [ "programming" ]
url = "https://github.com/YunoHost-Apps/dont-code_ynh"
@ -909,7 +917,7 @@ url = "https://github.com/YunoHost-Apps/easyappointments_ynh"
[elabftw]
added_date = 1674232499 # 2023/01/20
category = "productivity_and_management"
level = 8
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/elabftw_ynh"
@ -969,7 +977,7 @@ url = "https://github.com/YunoHost-Apps/emailpoubelle_ynh"
[emoncms]
added_date = 1674232499 # 2023/01/20
category = "iot"
level = 8
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/emoncms_ynh"
@ -992,14 +1000,6 @@ level = 7
state = "working"
url = "https://github.com/YunoHost-Apps/encryptor-decryptor_ynh"
[endi]
added_date = 1674232499 # 2023/01/20
category = "productivity_and_management"
level = 0
state = "working"
subtags = [ "accounting", "business_and_ngos" ]
url = "https://github.com/Yunohost-Apps/endi_ynh"
[epicyon]
added_date = 1674232499 # 2023/01/20
category = "social_media"
@ -1030,7 +1030,7 @@ url = "https://github.com/YunoHost-Apps/ethercalc_ynh"
[etherpad]
added_date = 1694300530 # 2023/09/09
category = "office"
level = 6
level = 7
potential_alternative_to = [ "G Suite", "Google Docs", "Microsoft Office", "Microsoft Word", "Office 365" ]
state = "working"
subtags = [ "text" ]
@ -1290,7 +1290,7 @@ url = "https://github.com/YunoHost-Apps/gamja_ynh"
[gancio]
added_date = 1696575541 # 2023/10/06
category = "social_media"
level = 7
level = 6
state = "working"
subtags = [ "events" ]
url = "https://github.com/YunoHost-Apps/gancio_ynh"
@ -1350,7 +1350,7 @@ url = "https://github.com/YunoHost-Apps/gitlab_ynh"
[gitlab-runner]
added_date = 1674232499 # 2023/01/20
category = "dev"
level = 8
level = 6
state = "working"
subtags = [ "forge" ]
url = "https://github.com/YunoHost-Apps/gitlab-runner_ynh"
@ -1389,7 +1389,7 @@ url = "https://github.com/YunoHost-Apps/glowingbear_ynh"
[glpi]
added_date = 1674232499 # 2023/01/20
category = "productivity_and_management"
level = 6
level = 8
potential_alternative_to = [ "Cherwell", "Freshdesk", "Ivanti", "Peregrine Systems (AssetCenter)", "Remedy (BMC Software)", "ServiceNow" ]
state = "working"
subtags = [ "task" ]
@ -1431,7 +1431,7 @@ url = "https://github.com/YunoHost-Apps/gotosocial_ynh"
[grafana]
added_date = 1674232499 # 2023/01/20
category = "system_tools"
level = 8
level = 1
state = "working"
subtags = [ "monitoring" ]
url = "https://github.com/YunoHost-Apps/grafana_ynh"
@ -1675,7 +1675,7 @@ url = "https://github.com/YunoHost-Apps/immich_ynh"
[incus]
added_date = 1710508401 # 2024/03/15
category = "system_tools"
level = 7
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/incus_ynh"
@ -1691,7 +1691,7 @@ url = "https://github.com/YunoHost-Apps/indexhibit_ynh"
added_date = 1691920584 # 2023/08/13
branch = "main"
category = "system_tools"
level = 7
level = 6
state = "working"
subtags = [ "db", "monitoring" ]
url = "https://github.com/YunoHost-Apps/influxdb_v2_ynh"
@ -1750,7 +1750,7 @@ added_date = 1674232499 # 2023/01/20
antifeatures = [ "deprecated-software", "package-not-maintained" ]
category = "communication"
deprecated_date = 1714590228 # 2024/05/01
level = 7
level = 6
state = "working"
subtags = [ "chat" ]
url = "https://github.com/YunoHost-Apps/jappix_ynh"
@ -1979,7 +1979,7 @@ url = "https://github.com/YunoHost-Apps/leed_ynh"
[lemmy]
added_date = 1674232499 # 2023/01/20
category = "social_media"
level = 8
level = 0
potential_alternative_to = [ "Hacker News", "Lobste.rs", "Reddit" ]
state = "working"
url = "https://github.com/YunoHost-Apps/lemmy_ynh"
@ -2208,7 +2208,7 @@ url = "https://github.com/YunoHost-Apps/mantis_ynh"
[mastodon]
added_date = 1674232499 # 2023/01/20
category = "social_media"
level = 6
level = 8
potential_alternative_to = [ "X" ]
state = "working"
subtags = [ "microblogging" ]
@ -2226,7 +2226,7 @@ url = "https://github.com/YunoHost-Apps/matomo_ynh"
[matrix-appservice-irc]
added_date = 1675621561 # 2023/02/05
category = "communication"
level = 7
level = 6
state = "working"
subtags = [ "chat" ]
url = "https://github.com/YunoHost-Apps/matrix-appservice-irc_ynh"
@ -2280,7 +2280,7 @@ url = "https://github.com/YunoHost-Apps/mautrix_facebook_ynh"
[mautrix_signal]
added_date = 1674232499 # 2023/01/20
category = "communication"
level = 7
level = 6
potential_alternative_to = [ "Signal" ]
state = "working"
subtags = [ "chat" ]
@ -2486,7 +2486,7 @@ url = "https://github.com/YunoHost-Apps/motioneye_ynh"
[movim]
added_date = 1674232499 # 2023/01/20
category = "social_media"
level = 6
level = 8
potential_alternative_to = [ "Facebook Messenger", "Facebook", "MSN" ]
state = "working"
subtags = [ "microblogging" ]
@ -2570,7 +2570,7 @@ url = "https://github.com/YunoHost-Apps/mytinytodo_ynh"
added_date = 1674232499 # 2023/01/20
antifeatures = [ "not-totally-free-upstream" ]
category = "iot"
level = 6
level = 8
state = "working"
url = "https://github.com/YunoHost-Apps/n8n_ynh"
@ -2652,7 +2652,7 @@ url = "https://github.com/YunoHost-Apps/nodered_ynh"
[nomad]
added_date = 1674232499 # 2023/01/20
category = "dev"
level = 8
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/nomad_ynh"
@ -2733,7 +2733,7 @@ added_date = 1674232499 # 2023/01/20
antifeatures = [ "deprecated-software" ]
category = "office"
deprecated_date = 1708403676 # 2024/02/20
level = 7
level = 6
state = "working"
subtags = [ "text" ]
url = "https://github.com/YunoHost-Apps/opennote_ynh"
@ -2824,14 +2824,14 @@ url = "https://github.com/YunoHost-Apps/owncast_ynh"
[owncast-emojiwall]
added_date = 1696593645 # 2023/10/06
category = "small_utilities"
level = 7
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/owncast-emojiwall_ynh"
[owncloud]
added_date = 1674232499 # 2023/01/20
category = "synchronization"
level = 7
level = 8
potential_alternative_to = [ "Apple iCloud", "Dropbox", "Google Drive", "Microsoft OneDrive" ]
state = "working"
subtags = [ "files" ]
@ -2840,7 +2840,7 @@ url = "https://github.com/YunoHost-Apps/owncloud_ynh"
[owntracks]
added_date = 1674232499 # 2023/01/20
category = "small_utilities"
level = 8
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/owntracks_ynh"
@ -2891,7 +2891,7 @@ url = "https://github.com/YunoHost-Apps/peertube_ynh"
added_date = 1674232499 # 2023/01/20
antifeatures = [ "not-totally-free-upstream" ]
category = "social_media"
level = 7
level = 8
state = "working"
subtags = [ "videos" ]
url = "https://github.com/YunoHost-Apps/peertube-search-index_ynh"
@ -2915,7 +2915,7 @@ url = "https://github.com/YunoHost-Apps/pelican_ynh"
[penpot]
added_date = 1708540527 # 2024/02/21
category = "dev"
level = 6
level = 7
state = "working"
subtags = [ "design" ]
url = "https://github.com/YunoHost-Apps/penpot_ynh"
@ -3245,7 +3245,7 @@ url = "https://github.com/YunoHost-Apps/pufferpanel_ynh"
[pydio]
added_date = 1674232499 # 2023/01/20
category = "synchronization"
level = 8
level = 6
potential_alternative_to = [ "Google Drive", "Microsoft OneDrive" ]
state = "working"
subtags = [ "files" ]
@ -3697,7 +3697,7 @@ url = "https://github.com/YunoHost-Apps/snappymail_ynh"
[snipeit]
added_date = 1674232499 # 2023/01/20
category = "productivity_and_management"
level = 6
level = 8
state = "working"
subtags = [ "business_and_ngos" ]
url = "https://github.com/YunoHost-Apps/snipeit_ynh"
@ -3775,7 +3775,7 @@ url = "https://github.com/YunoHost-Apps/squid3_ynh"
[ssbroom]
added_date = 1674232499 # 2023/01/20
category = "communication"
level = 7
level = 8
state = "working"
url = "https://github.com/YunoHost-Apps/ssbroom_ynh"
@ -3881,7 +3881,7 @@ url = "https://github.com/YunoHost-Apps/syncthing_ynh"
[tandoor]
added_date = 1674232499 # 2023/01/20
category = "small_utilities"
level = 6
level = 8
state = "working"
url = "https://github.com/YunoHost-Apps/tandoor_ynh"
@ -3981,7 +3981,7 @@ url = "https://github.com/YunoHost-Apps/tinyfilemanager_ynh"
[tldraw]
added_date = 1674232499 # 2023/01/20
category = "office"
level = 6
level = 8
potential_alternative_to = [ "Lucidchart" ]
state = "working"
subtags = [ "draw" ]
@ -4186,7 +4186,7 @@ url = "https://github.com/labriqueinternet/vpnclient_ynh"
[wallabag2]
added_date = 1674232499 # 2023/01/20
category = "reading"
level = 8
level = 6
state = "working"
url = "https://github.com/YunoHost-Apps/wallabag2_ynh"
@ -4506,7 +4506,7 @@ url = "https://github.com/YunoHost-Apps/zusam_ynh"
[zwave-js-ui]
added_date = 1674232499 # 2023/01/20
category = "iot"
level = 6
level = 8
state = "working"
url = "https://github.com/YunoHost-Apps/zwave-js-ui_ynh"

View file

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -79,7 +79,7 @@ function autoupdate_app_sources()
date >> $log
git_pull_and_update_cron_and_restart_services_if_needed
tools/autoupdate_app_sources/venv/bin/python3 tools/autoupdate_app_sources/autoupdate_app_sources.py \
--edit --commit --pr --paste -j1 \
--latest-commit-weekly --edit --commit --pr --paste -j1 \
&> $log || sendxmpppy "[appsourcesautoupdate] App sources auto-update failed miserably"
}

View file

@ -216,6 +216,7 @@ class AppAutoUpdater:
raise RuntimeError("There's no resources.sources in manifest.toml ?")
self.main_upstream = self.manifest.get("upstream", {}).get("code")
self.latest_commit_weekly = False
def run(
self, edit: bool = False, commit: bool = False, pr: bool = False
@ -240,9 +241,10 @@ class AppAutoUpdater:
if source == "main":
main_version = version
branch_name = f"ci-auto-update-{version}"
pr_title = commit_msg = f"Upgrade to v{version}"
if msg:
commit_msg += f"\n{msg}"
pr_title = f"Upgrade to v{version}"
if msg:
commit_msg += f"\n- `{source}` v{version}: {msg}"
self.repo.manifest_raw = self.replace_version_and_asset_in_manifest(
self.repo.manifest_raw,
@ -255,6 +257,11 @@ class AppAutoUpdater:
if state == State.up_to_date:
return (State.up_to_date, "", "", "")
if main_version == "":
self.repo.manifest_raw = self.bump_version(
self.repo.manifest_raw, self.current_version, bump_ynh_level=True
)
if edit:
self.repo.edit_manifest(self.repo.manifest_raw)
@ -384,7 +391,7 @@ class AppAutoUpdater:
f"Unknown update strategy '{strategy}' for '{name}', expected one of {STRATEGIES}"
)
result = self.get_latest_version_and_asset(strategy, asset, autoupdate)
result = self.get_latest_version_and_asset(strategy, asset, infos)
if result is None:
return None
new_version, assets, more_info = result
@ -451,8 +458,9 @@ class AppAutoUpdater:
return next(iter(matching_assets.items()))
def get_latest_version_and_asset(
self, strategy: str, asset: Union[str, dict], autoupdate
self, strategy: str, asset: Union[str, dict], infos: dict[str, Any]
) -> Optional[tuple[str, Union[str, dict[str, str]], str]]:
autoupdate = infos.get("autoupdate")
upstream = autoupdate.get("upstream", self.main_upstream).strip("/")
version_re = autoupdate.get("version_regex", None)
allow_prereleases = autoupdate.get("allow_prereleases", False)
@ -495,6 +503,11 @@ class AppAutoUpdater:
latest_assets = latest_release["tarball_url"]
# get the release changelog link
latest_release_html_url = latest_release["html_url"]
if latest_release_html_url is None or latest_release_html_url == "":
latest_release_html_url = api.changelog_for_ref(
latest_version_orig, "", RefType.releases
)
if asset == "tarball":
latest_tarball = api.url_for_ref(latest_version_orig, RefType.tags)
return latest_version, latest_tarball, latest_release_html_url
@ -532,9 +545,16 @@ class AppAutoUpdater:
tags, self.app_id, version_re
)
latest_tarball = api.url_for_ref(latest_version_orig, RefType.tags)
return latest_version, latest_tarball, ""
return (
latest_version,
latest_tarball,
api.changelog_for_ref(latest_version, "", RefType.tags),
)
if revision_type == "commit":
if self.latest_commit_weekly and datetime.now().weekday() != 0:
logging.warning("Skipped autoupdater because we're not monday")
return None
if asset != "tarball":
raise ValueError(
"For the latest commit strategies, only asset = 'tarball' is supported"
@ -548,7 +568,23 @@ class AppAutoUpdater:
)
version_format = autoupdate.get("force_version", "%Y.%m.%d")
latest_version = latest_commit_date.strftime(version_format)
return latest_version, latest_tarball, ""
return (
latest_version,
latest_tarball,
api.changelog_for_ref(
latest_commit["sha"], self.get_old_ref(infos), RefType.commits
),
)
return None
@staticmethod
def get_old_ref(infos: dict[str, Any]) -> str:
regex = r".*[\/-]([a-f0-9]+)\."
if isinstance(infos["url"], str):
return re.match(regex, infos["url"]).group(1)
if isinstance(infos["url"], dict):
for _, url in infos["url"]:
return re.match(regex, url).group(1)
return None
def replace_version_and_asset_in_manifest(
@ -576,19 +612,34 @@ class AppAutoUpdater:
]
if is_main:
def repl(m: re.Match) -> str:
return m.group(1) + new_version + '~ynh1"'
content = re.sub(
r"(\s*version\s*=\s*[\"\'])([^~\"\']+)(\~ynh\d+[\"\'])", repl, content
)
content = self.bump_version(content, new_version)
for old, new in replacements:
content = content.replace(old, new)
return content
def bump_version(
self, content: str, new_version: str, bump_ynh_level: bool = False
) -> str:
ynh_level = 1
if bump_ynh_level:
ynh_level = (
int(
re.search(
r"\s*version\s*=\s*[\"\'][^~\"\']+~ynh(\d+)[\"\']", content
).group(1)
)
+ 1
)
def repl(m: re.Match) -> str:
return m.group(1) + new_version + f'~ynh{ynh_level}"'
return re.sub(
r"(\s*version\s*=\s*[\"\'])([^~\"\']+)(~ynh\d+[\"\'])", repl, content
)
def paste_on_haste(data):
# NB: we hardcode this here and can't use the yunopaste command
@ -631,10 +682,12 @@ class StdoutSwitch:
def run_autoupdate_for_multiprocessing(data) -> tuple[str, tuple[State, str, str, str]]:
app, edit, commit, pr = data
app, edit, commit, pr, latest_commit_weekly = data
stdoutswitch = StdoutSwitch()
try:
result = AppAutoUpdater(app).run(edit=edit, commit=commit, pr=pr)
autoupdater = AppAutoUpdater(app)
autoupdater.latest_commit_weekly = latest_commit_weekly
result = autoupdater.run(edit=edit, commit=commit, pr=pr)
return (app, result)
except Exception:
log_str = stdoutswitch.reset()
@ -652,6 +705,13 @@ def main() -> None:
type=Path,
help="If not passed, the script will run on the catalog. Github keys required.",
)
parser.add_argument(
"-w",
"--latest-commit-weekly",
action=argparse.BooleanOptionalAction,
default=False,
help="For latest_commit versions, only run weekly to prevent too many PRs",
)
parser.add_argument(
"--edit",
action=argparse.BooleanOptionalAction,
@ -694,7 +754,10 @@ def main() -> None:
with multiprocessing.Pool(processes=args.processes) as pool:
tasks = pool.imap(
run_autoupdate_for_multiprocessing,
((app, args.edit, args.commit, args.pr) for app in apps),
(
(app, args.edit, args.commit, args.pr, args.latest_commit_weekly)
for app in apps
),
)
for app, result in tqdm.tqdm(tasks, total=len(apps), ascii=" ·#"):
state, current_version, main_version, pr_url = result

View file

@ -2,4 +2,3 @@ requests
PyGithub
toml
tqdm
GitPython

View file

@ -10,6 +10,7 @@ import requests
class RefType(Enum):
tags = 1
commits = 2
releases = 3
class GithubAPI:
@ -41,13 +42,20 @@ class GithubAPI:
def url_for_ref(self, ref: str, ref_type: RefType) -> str:
"""Get a URL for a ref."""
if ref_type == RefType.tags:
if ref_type == RefType.tags or ref_type == RefType.releases:
return f"{self.upstream}/archive/refs/tags/{ref}.tar.gz"
elif ref_type == RefType.commits:
return f"{self.upstream}/archive/{ref}.tar.gz"
else:
raise NotImplementedError
def changelog_for_ref(self, new_ref: str, old_ref: str, ref_type: RefType) -> str:
"""Get a changelog for a ref."""
if ref_type == RefType.commits:
return f"{self.upstream}/compare/{old_ref}...{new_ref}"
else:
return f"{self.upstream}/releases/tag/{new_ref}"
class GitlabAPI:
def __init__(self, upstream: str):
@ -135,11 +143,24 @@ class GitlabAPI:
return retval
def url_for_ref(self, ref: str, ref_type: RefType) -> str:
def url_for_ref(self, ref: str, _: RefType) -> str:
name = self.project_path.split("/")[-1]
clean_ref = ref.replace("/", "-")
return f"{self.forge_root}/{self.project_path}/-/archive/{ref}/{name}-{clean_ref}.tar.bz2"
def changelog_for_ref(self, new_ref: str, old_ref: str, ref_type: RefType) -> str:
"""Get a changelog for a ref."""
if ref_type == RefType.commits:
return (
f"{self.forge_root}/{self.project_path}/-/compare/{old_ref}...{new_ref}"
)
elif ref_type == RefType.tags:
return f"{self.forge_root}/{self.project_path}/-/tags/{new_ref}"
elif ref_type == RefType.releases:
return f"{self.forge_root}/{self.project_path}/-/releases/{new_ref}"
else:
raise NotImplementedError
class GiteaForgejoAPI:
def __init__(self, upstream: str):
@ -173,6 +194,15 @@ class GiteaForgejoAPI:
"""Get a list of releases for project."""
return self.internal_api(f"repos/{self.project_path}/releases")
def url_for_ref(self, ref: str, ref_type: RefType) -> str:
def url_for_ref(self, ref: str, _: RefType) -> str:
"""Get a URL for a ref."""
return f"{self.forge_root}/{self.project_path}/archive/{ref}.tar.gz"
def changelog_for_ref(self, new_ref: str, old_ref: str, ref_type: RefType) -> str:
"""Get a changelog for a ref."""
if ref_type == RefType.commits:
return (
f"{self.forge_root}/{self.project_path}/compare/{old_ref}...{new_ref}"
)
else:
return f"{self.forge_root}/{self.project_path}/releases/tag/{new_ref}"

View file

@ -0,0 +1,557 @@
#!/usr/bin/env python3
import argparse
import os
import re
def cleanup():
comment_blocks_to_cleanup = [
r"#=+\s*\n# GENERIC START\S*\s*\n#=+\s*\n# IMPORT GENERIC HELPERS\n#=+\s*\n",
r"#=+\s*\n# EXPERIMENTAL HELPERS\s*\n#=+\s*\n",
r"#=+\s*\n# FUTURE OFFICIAL HELPERS\s*\n#=+\s*\n",
r"#=+\s*\n# PERSONAL HELPERS\s*\n#=+\s*\n",
r"#=+\s*\n# GENERIC FINALIZATION\s*\n",
r"#=+\s*\n# GENERIC FINALISATION\s*\n",
r"#=+\s*\n# STANDARD MODIFICATIONS\s*\n",
r"#=+\s*\n# STANDARD UPGRADE STEPS\s*\n",
r"#=+\s*\n# SPECIFIC UPGRADE\s*\n",
r"#=+\s*\n# CHECK VERSION\s*\n#=+\s*\n",
r"#=+\s*\n# DECLARE DATA AND CONF FILES TO BACKUP\s*\n#=+\s*\n",
]
removememaybes = [
"ynh_legacy_permissions_exists",
"ynh_legacy_permissions_delete_all",
"ynh_webpath_available",
"ynh_webpath_register",
"ynh_psql_test_if_first_run",
"ynh_backup_before_upgrade",
"ynh_restore_upgradebackup",
"ynh_find_port",
"ynh_port_available",
"ynh_require_ram",
"--ignore_swap",
"--only_swap",
"ynh_print_log",
"ynh_print_OFF",
"ynh_print_ON",
"local legacy_args",
"ynh_abort_if_errors",
"ynh_clean_setup",
]
replaces = [
# Unecessary exec_warn_less
(r"ynh_exec_warn_less ynh_secure_remove", "ynh_secure_remove"),
(r"ynh_exec_warn_less ynh_systemd_action", "ynh_systemctl"),
(r"ynh_exec_warn_less ynh_install_nodejs", "ynh_install_nodejs"),
(r"ynh_exec_warn_less ynh_install_go", "ynh_install_go"),
(r"ynh_exec_warn_less ynh_install_ruby", "ynh_install_ruby"),
(r"ynh_exec_warn_less ynh_composer_exec", "ynh_composer_exec"),
(r"ynh_exec_warn_less ynh_install_composer", "ynh_install_composer"),
# Setting get/set
(r" ?--app=? ?\"?\$app\"?", ""),
# Misc
(r"ynh_validate_ip4", "ynh_validate_ip --family=4"),
(r"ynh_validate_ip4", "ynh_validate_ip --family=6"),
(r"\$\(ynh_get_debian_release\)", "$YNH_DEBIAN_VERSION"),
(r"ynh_read_manifest --manifest\S*", "ynh_read_manifest"),
(r"--manifest_key", "--key"),
(r"COMMON VARIABLES\s*$", "COMMON VARIABLES AND CUSTOM HELPERS"),
(r"ynh_string_random ([0-9])", "ynh_string_random --length=\\1"),
(
r"ynh_backup_if_checksum_is_different --file=?",
"ynh_backup_if_checksum_is_different ",
),
(r"ynh_store_file_checksum --file=?", "ynh_store_file_checksum "),
(r"ynh_delete_file_checksum --file=?", "ynh_delete_file_checksum "),
(r"\[\[?.*PACKAGE_CHECK_EXEC.*eq.*1.*\]\]?", "ynh_in_ci_tests"),
(r"\[\[?.*PACKAGE_CHECK_EXEC.*=.*1.*\]\]?", "ynh_in_ci_tests"),
(r"\[\[?.*PACKAGE_CHECK_EXEC.*ne.*1.*\]\]?", "! ynh_in_ci_tests"),
(r"\[\[?.*PACKAGE_CHECK_EXEC.*eq.*0.*\]\]?", "! ynh_in_ci_tests"),
(r"\[\[?.*PACKAGE_CHECK_EXEC.*ne.*0.*\]\]?", "ynh_in_ci_tests"),
# ynh_setup_source
(r"--full_replace=1", "--full_replace"),
(r"sources/patches", "patches"),
(r"sources/extra_files/app", "sources"),
(r"sources/extra_files", "sources"),
(
r"((chmod|chown).*\"?\$install_dir\"?)\s*$",
"#REMOVEME? Assuming the install dir is setup using ynh_setup_source, the proper chmod/chowns are now already applied and it shouldn't be necessary to tweak perms | \\1",
),
# Logging
(r"ynh_print_err", "ynh_print_warn"),
(r"ynh_exec_quiet ?", ""),
(r"ynh_exec_fully_quiet ?", ""),
(r"ynh_exec_warn_less", "ynh_hide_warnings"),
(r"--message=?", ""),
(r"--time ", ""),
(r"--last", ""),
(r"\s*--weight=?\S*", ""),
# rm
(r"ynh_secure_remove( --file=?)? ?", "ynh_safe_rm "),
# Conf / templating
(r"__NAME__", "__APP__"),
(r"__NAMETOCHANGE__", "__APP__"),
(r"ynh_render_template", "ynh_config_add --jinja"),
(r"ynh_add_config", "ynh_config_add"),
(r'--template="../conf/', '--template="'),
(r"ynh_replace_vars --file=", "ynh_replace_vars "),
(r"ynh_replace_vars", "_ynh_replace_vars"),
(
r"((chmod|chown)\s[^-+].*\"?(\$install_dir\"?/.*(config|.env|settings|credentials)\S*|\$data_dir\"?/\S+|/etc/(sudoers.d|cron.d|\$app)\"?/\S+|\$(config|cron_path)\"?))",
"#REMOVEME? Assuming the file is setup using ynh_config_add, the proper chmod/chowns are now already applied and it shouldn't be necessary to tweak perms | \\1",
),
# Upgrade stuff
(
r"ynh_compare_current_package_version.*lt.*version\s?=?\"?([0-9\.]+~ynh[0-9])\"?",
"ynh_app_upgrading_from_version_before \\1",
),
(
r"ynh_compare_current_package_version.*le.*version\s?=?\"?([0-9\.]+~ynh[0-9])\"?",
"ynh_app_upgrading_from_version_before_or_equal_to \\1",
),
(r"upgrade_type=\S*", ""),
(
r'if \[\s+"?\$upgrade_type"?\s+==\s+"?UPGRADE_APP"? \]',
"# FIXME: this is still supported but the recommendation is now to *always* re-setup the app sources wether or not the upstream sources changed\nif ynh_app_upstream_version_changed",
),
# Backup/store
(r"ynh_restore\s*$", "ynh_restore_everything"),
# -> Specific trick to remove the --not_mandatory here, but replace it with || true for the other occurences
(r'ynh_restore_file --origin_path="\$data_dir" \S*', 'ynh_restore "$data_dir"'),
(r"ynh_restore_file", "ynh_restore"),
(r"--src_path=?", ""),
(r"--origin_path=?", ""),
(r"--is_big\S*", ""),
(r"--not_mandatory", "|| true"),
# Fail2ban
(r"--max_retry=\S*", ""),
(r"--ports\S*", ""),
(r"ynh_add_fail2ban_config --use_template", "ynh_config_add_fail2ban"),
(r"ynh_add_fail2ban_config", "ynh_config_add_fail2ban"),
(r"ynh_remove_fail2ban_config", "ynh_config_remove_fail2ban"),
# MySQL/Postgresql
(r"ynh_mysql_dump_db \S*\$db_name\"?\s", "ynh_mysql_dump_db "),
(r"ynh_psql_dump_db \S*\$db_name\"?\s", "ynh_psql_dump_db "),
(r"ynh_mysql_connect_as [^<\\]*\s", "ynh_mysql_db_shell "),
(r"ynh_psql_connect_as [^<\\]*\s", "ynh_psql_db_shell "),
(r"ynh_mysql_execute_as_root --sql=?", "ynh_mysql_db_shell <<< "),
(r"ynh_psql_execute_as_root --sql=?", "ynh_psql_db_shell <<< "),
(r'ynh_mysql_execute_as_root "', 'ynh_mysql_db_shell <<< "'),
(r'ynh_psql_execute_as_root "', 'ynh_psql_db_shell <<< "'),
(r"ynh_mysql_execute_as_root '", "ynh_mysql_db_shell <<< '"),
(r"ynh_psql_execute_as_root '", "ynh_psql_db_shell <<< '"),
(r"ynh_psql_execute_as_root --database=?", "ynh_psql_db_shell "),
(r"ynh_mysql_execute_as_root --database=?", "ynh_psql_db_shell "),
(r"--sql=", "<<< "),
(
r"ynh_mysql_execute_file_as_root --database=\"?(\S+)\"? --file=\"?(\S+)\"?",
'ynh_mysql_db_shell "\\1" < "\\2"',
),
(
r"ynh_mysql_execute_file_as_root --file=\"?(\S+)\"? --database=\"?(\S+)\"?",
'ynh_mysql_db_shell "\\2" < "\\1"',
),
(
r"ynh_psql_execute_file_as_root --database=\"?(\S+)\"? --file=\"?(\S+)\"?",
'ynh_psql_db_shell "\\1" < "\\2"',
),
(
r"ynh_psql_execute_file_as_root --file=\"?(\S+)\"? --database=\"?(\S+)\"?",
'ynh_psql_db_shell "\\2" < "\\1"',
),
(r'sql_db_shell "?\$db_name"?', "sql_db_shell "),
(r'--database="?\$db_name"?', ""),
(r'--database="?\$app"?', ""),
(r"ynh_mysql_setup_db", "# FIXMEhelpers2.1 ynh_mysql_create_db"),
(
r"ynh_mysql_remove_db",
"# FIXMEhelpers2.1 ynh_mysql_drop_db && ynh_mysql_drop_user",
),
(r"ynh_psql_setup_db", "# FIXMEhelpers2.1 ynh_psql_create_db"),
(
r"ynh_psql_remove_db",
"# FIXMEhelpers2.1 ynh_psql_drop_db && ynh_psql_drop_user",
),
# PHP / composer
(r" ?--phpversion=\S*", ""),
(r" ?--composerversion=\S*", ""),
(r" ?--usage=\S*", ""),
(r" ?--footprint=\S*", ""),
(
r"--group=www-data",
"# FIXMEhelpers2.1 : --group=www-data to be replaced with php_group=www-data to be added in _common.sh",
),
(r"YNH_COMPOSER_VERSION=", "composer_version="),
(r' --workdir="\$install_dir"', ""),
(r"--workdir=\$install_dir ", ""),
(
r"--workdir",
"# FIXMEhelpers2.1 (replace with composer_workdir=... prior to calling this helper, default is $intall_dir) --workdir",
),
(r"phpversion", "php_version"),
(r"PHPVERSION", "PHP_VERSION"),
(r"ynh_add_fpm_config", "ynh_config_add_phpfpm"),
(r"ynh_remove_fpm_config", "ynh_config_remove_phpfpm"),
(
r"ynh_install_composer",
"ynh_composer_install\nynh_composer_exec install --no-dev ",
),
(r'--install_args="?([^"]+)"?(\s|$)', "\\1\\2"),
(r'--commands="([^"]+)"(\s|$)', "\\1\\2"),
(
r"(^fpm_usage=)",
"#REMOVEME? Everything about fpm_usage is removed in helpers2.1... | \\1",
),
(
r"(^.*\$fpm_usage)",
"#REMOVEME? Everything about fpm_usage is removed in helpers2.1... | \\1",
),
(
r"(^fpm_footprint=)",
"#REMOVEME? Everything about fpm_footprint is removed in helpers2.1... | \\1",
),
(
r"(^.*\$fpm_footprint)",
"#REMOVEME? Everything about fpm_footprint is removed in helpers2.1... | \\1",
),
(
r"(^set__fpm_footprint)",
"#REMOVEME? Everything about fpm_footprint is removed in helpers2.1... | \\1",
),
(
r"(^fpm_free_footprint=)",
"#REMOVEME? Everything about fpm_free_footprint is removed in helpers2.1... | \\1",
),
(
r"(^.*\$fpm_free_footprint)",
"#REMOVEME? Everything about fpm_free_footprint is removed in helpers2.1... | \\1",
),
(
r"(^set__fpm_free_footprint)",
"#REMOVEME? Everything about fpm_free_footprint is removed in helpers2.1... | \\1",
),
# Nodejs
(r'"?\$?ynh_node"?', "node"),
(r"NODEJS_VERSION=", "nodejs_version="),
(r"ynh_install_nodejs \S*", "ynh_nodejs_install"),
(r"ynh_install_nodejs", "ynh_nodejs_install"),
(r"ynh_remove_nodejs", "ynh_nodejs_remove"),
(r"ynh_use_nodejs", ""),
(r'"?\$ynh_node_load_PATH"?', ""),
(r'"?\$ynh_node_load_path"?', ""),
(r'"?\$?ynh_npm"?', "npm"),
(r"(export )?COREPACK_ENABLE_DOWNLOAD_PROMPT=0", ""),
(r"env\s+npm", "npm"),
(r"env\s+pnpm", "pnpm"),
(r"env\s+yarn", "yarn"),
(r"env\s+corepack", "corepack"),
# Ruby
(r'"?\$?ynh_ruby"?', "ruby"),
(r'"?\$?ynh_gem"?', "gem"),
(r"RUBY_VERSION=", "ruby_version="),
(r"ynh_install_ruby \S*", "ynh_ruby_install"),
(r"ynh_install_ruby", "ynh_ruby_install"),
(r"ynh_remove_ruby", "ynh_ruby_remove"),
(r"ynh_use_ruby", ""),
(r'"?\$ynh_ruby_load_PATH"?', ""),
(r'"?\$ynh_ruby_load_path"?', ""),
# Go
(r"^\s*GO_VERSION=", "go_version="),
(r'"?\$?ynh_go"?', "go"),
(r"ynh_install_go \S*", "ynh_go_install"),
(r"ynh_install_go", "ynh_go_install"),
(r"ynh_remove_go", "ynh_go_remove"),
(r"ynh_use_go", ""),
# Mongodb
(r"YNH_MONGO_VERSION", "mongo_version"),
(r"ynh_install_mongo \S*", "ynh_install_mongo"),
(r" --eval", ""),
# ynh_replace_string
(r"ynh_replace_string", "ynh_replace"),
(r"ynh_replace_special_string", "ynh_replace_regex"),
(r"--match_string", "--match"),
(r"--replace_string", "--replace"),
(r"--target_file", "--file"),
(
r"(ynh_replace ('|\"))",
"# FIXMEhelpers2.1: ynh_replace used with positional args. Please add the keywords: --match=, --replace=, --file=\n\\1",
),
# Nginx
(r"ynh_add_nginx_config", "ynh_config_add_nginx"),
(r"ynh_remove_nginx_config", "ynh_config_remove_nginx"),
(r"ynh_change_url_nginx_config", "ynh_config_change_url_nginx"),
# Systemd
(r'--log_path="/var/log/\$app/\$app.log"', ""),
(r'--service="?\$app"?(\s|$)', "\\1"),
(r"--service_name", "--service"),
(r"--line_match", "--wait_until"),
(r' --template="systemd.service"', ""),
(r"ynh_add_systemd_config", "ynh_config_add_systemd"),
(r"ynh_remove_systemd_config --service=?", "ynh_config_remove_systemd"),
(r"ynh_remove_systemd_config", "ynh_config_remove_systemd"),
(r"ynh_systemd_action", "ynh_systemctl"),
# Logrotate
(r"ynh_use_logrotate", "ynh_config_add_logrotate"),
(r"ynh_remove_logrotate", "ynh_config_remove_logrotate"),
(r"--specific_user\S*", ""),
(r"--logfile=?", ""),
(r" ?--non-?append", ""),
(
r"((chmod|chown).*\"?/var/log/\"?\$app)",
"#REMOVEME? Assuming ynh_config_add_logrotate is called, the proper chmod/chowns are now already applied and it shouldn't be necessary to tweak perms | \\1",
),
# Apt
(r"ynh_package_is_installed (--package=)?", "_ynh_apt_package_is_installed"),
(r"ynh_package_version (--package=)?", "_ynh_apt_package_version"),
(r"ynh_package_install", "_ynh_apt_install"),
(
r"ynh_install_extra_app_dependencies",
"ynh_apt_install_dependencies_from_extra_repository",
),
(r"ynh_install_app_dependencies", "ynh_apt_install_dependencies"),
(r"ynh_remove_app_dependencies", "ynh_apt_remove_dependencies"),
(r"ynh_package_autopurge", "_ynh_apt autoremove --purge"),
# Exec as / sudo
(r'ynh_exec_as "?\$app"?( env)?', "ynh_exec_as_app"),
(r'sudo -u "?\$app"?( env)?', "ynh_exec_as_app"),
# Cringy messages?
("Modifying a config file...", "Updating configuration..."),
("Updating a configuration file...", "Updating configuration..."),
("Adding a configuration file...", "Adding $app's configuration..."),
(
"Restoring the systemd configuration...",
"Restoring $app's systemd service...",
),
("Configuring a systemd service...", "Configuring $app's systemd service..."),
("Stopping a systemd service...", "Stopping $app's systemd service..."),
("Starting a systemd service...", "Starting $app's systemd service..."),
# Recommend ynh_app_setting_set_default
(
r"( *if \[.*-z.*:-}.*\].*\n?.*then\n\s+(\S+)=(.+)\n\s+ynh_app_setting_set.*\n\s*fi\n)",
"# FIXMEhelpers2.1: maybe replace with: ynh_app_setting_set_default --key=\\2 --value=\\3\n\\1",
),
# Trailing spaces
(r"\s+$", "\n"),
]
replaces = [
(re.compile(pattern, flags=re.M), replace) for pattern, replace in replaces
]
comment_blocks_to_cleanup = [
re.compile(pattern, flags=re.M) for pattern in comment_blocks_to_cleanup
]
for s in [
"_common.sh",
"install",
"remove",
"upgrade",
"backup",
"restore",
"change_url",
"config",
]:
script = f"scripts/{s}"
if not os.path.exists(script):
continue
content = open(script).read()
if s == "remove":
content = re.sub(
r"(ynh_secure_remove .*/var/log/\$app.*)",
r"#REMOVEME? (Apps should not remove their log dir during remove ... this should only happen if --purge is used, and be handled by the core...) \1",
content,
)
for pattern in comment_blocks_to_cleanup:
content = pattern.sub("", content)
for pattern, replace in replaces:
content = pattern.sub(replace, content)
for remove in removememaybes:
content = content.replace(remove, r"#REMOVEME? " + remove)
open(script, "w").write(content)
# Specific PHP FPM conf patch
if os.path.exists("conf/extra_php-fpm.conf"):
content = open("conf/extra_php-fpm.conf").read()
pattern_upload_max_filesize = r"\nphp_\S*\[upload_max_filesize\] = (\S*)"
pattern_post_max_size = r"\nphp_\S*\[post_max_size\] = (\S*)"
pattern_memory_limit = r"\nphp_\S*\[memory_limit\] = (\S*)"
upload_max_filesize = re.findall(pattern_upload_max_filesize, "\n" + content)
memory_limit = re.findall(pattern_memory_limit, "\n" + content)
if memory_limit:
content = re.sub(pattern_memory_limit, "", content)
memory_limit = memory_limit[0]
install = open("scripts/install").read()
install = re.sub(
"(source /usr/share/yunohost/helpers)",
"\\1\n\nynh_app_setting_set --key=php_memory_limit --value="
+ memory_limit,
install,
)
open("scripts/install", "w").write(install)
upgrade = open("scripts/upgrade").read()
upgrade = re.sub(
"(source /usr/share/yunohost/helpers)",
"\\1\n\nynh_app_setting_set_default --key=php_memory_limit --value="
+ memory_limit,
upgrade,
)
open("scripts/upgrade", "w").write(upgrade)
if upload_max_filesize:
content = re.sub(pattern_upload_max_filesize, "", content)
content = re.sub(pattern_post_max_size, "", content)
upload_max_filesize = upload_max_filesize[0]
if upload_max_filesize != "50M":
install = open("scripts/install").read()
install = re.sub(
"(source /usr/share/yunohost/helpers)",
"\\1\n\nynh_app_setting_set --key=php_upload_max_filesize --value="
+ upload_max_filesize,
install,
)
open("scripts/install", "w").write(install)
upgrade = open("scripts/upgrade").read()
upgrade = re.sub(
"(source /usr/share/yunohost/helpers)",
"\\1\n\nynh_app_setting_set_default --key=php_upload_max_filesize --value="
+ upload_max_filesize,
upgrade,
)
open("scripts/upgrade", "w").write(upgrade)
new_conf_is_empty = all(
line.strip() == "" or line.strip()[0] == ";" for line in content.split("\n")
)
if new_conf_is_empty:
os.system("git rm --quiet -f conf/extra_php-fpm.conf")
else:
open("conf/extra_php-fpm.conf", "w").write(content)
conf_replaces = [
(r"__NAME__", "__APP__"),
(r"__NAMETOCHANGE__", "__APP__"),
(r"__USER__", "__APP__"),
("__YNH_NODE__", "__NODEJS_DIR__/node"),
("__YNH_NPM__", "__NODEJS_DIR__/npm"),
("__YNH_NODE_LOAD_PATH__", "PATH=__PATH_WITH_NODEJS__"),
("__YNH_RUBY_LOAD_PATH__", "PATH=__PATH_WITH_RUBY__"),
("__YNH_GO_LOAD_PATH__", "PATH=__PATH_WITH_GO__"),
("__YNH_RUBY__", "__RUBY_DIR__/ruby"),
("__PHPVERSION__", "__PHP_VERSION__"),
]
for currentpath, folders, files in os.walk("conf"):
for file in files:
path = os.path.join(currentpath, file)
try:
content = open(path).read()
except UnicodeDecodeError:
# Not text?
continue
for pattern, replace in conf_replaces:
content = content.replace(pattern, replace)
open(path, "w").write(content)
git_cmds = [
"git rm --quiet sources/extra_files/*/.gitignore 2>/dev/null",
"git rm --quiet sources/patches/.gitignore 2>/dev/null",
"git mv sources/extra_files/* sources/ 2>/dev/null",
"git mv sources/app/* sources/ 2>/dev/null",
"git mv sources/patches patches/ 2>/dev/null",
"test -e conf/app.sh && git rm --quiet conf/app.src",
"test -e check_process && git rm --quiet check_process",
"test -e scripts/actions && git rm -rf --quiet scripts/actions",
"test -e config_panel.json && git rm --quiet config_panel.json",
"test -e config_panel.toml.example && git rm --quiet config_panel.toml.example",
"git rm $(find ./ -name .DS_Store) 2>/dev/null",
r"grep -q '\*\~' .gitignore 2>/dev/null || echo '*~' >> .gitignore",
r"grep -q '\*.sw\[op\]' .gitignore || echo '*.sw[op]' >> .gitignore",
r"grep -q '\.DS_Store' .gitignore || echo '.DS_Store' >> .gitignore",
"git add .gitignore",
]
for cmd in git_cmds:
os.system(cmd)
# If there's a config panel but the only options are the stupid php usage/footprint stuff
if (
os.path.exists("config_panel.toml")
and os.system(
r"grep -oE '^\s*\[\S+\.\S+\.\S+]' config_panel.toml | grep -qv php_fpm_config"
)
!= 0
):
os.system("git rm --quiet -f config_panel.toml")
os.system("git rm --quiet -f scripts/config")
# Remove scripts/config if no config panel ... most of the time this is only the example config script :|
if os.path.exists("scripts/config") and not os.path.exists("config_panel.toml"):
os.system("git rm --quiet -f scripts/config")
webapp_serving_raw_assets_probably = False
if os.path.exists("conf/nginx.conf"):
nginx_conf = open("conf/nginx.conf").read()
if "alias " in nginx_conf or "root " in nginx_conf:
webapp_serving_raw_assets_probably = True
if os.path.isdir("patches"):
for file in os.listdir("patches"):
if "-" not in file:
continue
source_name, patch_name = file.split("-", 1)
if source_name == "app":
source_name = "main"
os.system(f"mkdir -p 'patches/{source_name}'")
os.system(f"git mv patches/{file} patches/{source_name}/{patch_name}")
# Add helpers_version = '2.1' after yunohost requirement in manifest
raw_manifest = open("manifest.toml", "r").read()
if "helpers_version" not in raw_manifest:
raw_manifest = re.sub(
"(yunohost = .*)", '\\1\nhelpers_version = "2.1"', raw_manifest
)
raw_manifest = re.sub(
r'yunohost = ">= 11\..*"', 'yunohost = ">= 11.2.18"', raw_manifest
)
if webapp_serving_raw_assets_probably:
raw_manifest = re.sub(
r"( *)\[resources.install_dir\]",
'\\1[resources.install_dir]\n\\1group = "www-data:r-x"',
raw_manifest,
)
open("manifest.toml", "w").write(raw_manifest)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Attempt to automatically apply changes to use YunoHost helpers v2.1 on a v2 app"
)
parser.add_argument("app_path", help="Path to the app to convert")
args = parser.parse_args()
if not os.path.exists(args.app_path + "/manifest.toml"):
raise Exception("There is no manifest.toml. Is this really an app directory ?")
os.chdir(args.app_path)
cleanup()

View file

@ -8,23 +8,26 @@ msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-03-31 19:33+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"PO-Revision-Date: 2024-07-11 14:56+0000\n"
"Last-Translator: cjdw <cjdw@users.noreply.translate.yunohost.org>\n"
"Language-Team: Indonesian <https://translate.yunohost.org/projects/yunohost/"
"readme-generator/id/>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.4.3\n"
"Generated-By: Babel 2.14.0\n"
#: templates/ALL_README.md.j2:11
#, python-format
msgid "Read the README in %(language)s"
msgstr ""
msgstr "Baca README dalam bahasa %(language)s"
#: templates/README.md.j2:2
msgid "Packaging an app, starting from this example"
msgstr ""
msgstr "Memaket satu aplikasi, dimulai dari contoh ini"
#: templates/README.md.j2:4
msgid ""
@ -32,22 +35,29 @@ msgid ""
"github.com/new?template_name=example_ynh&template_owner=YunoHost) button on "
"the Github repo"
msgstr ""
"Salin aplikasi ini sebelum mengerjakannya, menggunakan tombol ['Gunakan "
"templat ini'](https://github.com/"
"new?template_name=example_ynh&template_owner=YunoHost) di repo Github"
#: templates/README.md.j2:5
msgid "Edit the `manifest.toml` with app specific info"
msgstr ""
msgstr "Edit `manifest.toml` dengan info khas aplikasi"
#: templates/README.md.j2:6
msgid ""
"Edit the `install`, `upgrade`, `remove`, `backup` and `restore` scripts, and "
"any relevant conf files in `conf/`"
msgstr ""
"Edit skrip `install`, `upgrade`, `remove`, `backup` and `restore`, dan "
"setiap berkas conf yang relevan dalam `conf/`"
#: templates/README.md.j2:7
msgid ""
"Using the [script helpers documentation](https://yunohost.org/"
"packaging_apps_helpers)"
msgstr ""
"Menggunakan [dokumentasi pembantu skrip](https://yunohost.org/"
"packaging_apps_helpers)"
#: templates/README.md.j2:8
msgid ""
@ -101,16 +111,16 @@ msgstr ""
#: templates/README.md.j2:24
msgid "Maintenance status"
msgstr ""
msgstr "Status pemeliharaan"
#: templates/README.md.j2:26
#, python-format
msgid "Install %(application_name)s with YunoHost"
msgstr ""
msgstr "Pasang %(application_name)s dengan YunoHost"
#: templates/README.md.j2:28
msgid "Read this README in other languages."
msgstr ""
msgstr "Baca README ini dengan bahasa yang lain."
#: templates/README.md.j2:30
#, python-format
@ -118,57 +128,62 @@ msgid ""
"This package allows you to install %(application_name)s quickly and simply "
"on a YunoHost server."
msgstr ""
"Paket ini memperbolehkan Anda untuk memasang %(application_name)s secara "
"cepat dan mudah pada server YunoHost."
#: templates/README.md.j2:31
msgid ""
"If you don't have YunoHost, please consult [the guide](https://yunohost.org/"
"install) to learn how to install it."
msgstr ""
"Bila Anda tidak mempunyai YunoHost, silakan berkonsultasi dengan "
"[panduan](https://yunohost.org/install) untuk mempelajari bagaimana untuk "
"memasangnya."
#: templates/README.md.j2:33
msgid "Overview"
msgstr ""
msgstr "Ringkasan"
#: templates/README.md.j2:37
msgid "Shipped version:"
msgstr ""
msgstr "Versi terkirim:"
#: templates/README.md.j2:41
msgid "Demo:"
msgstr ""
msgstr "Demo:"
#: templates/README.md.j2:45
msgid "Screenshots"
msgstr ""
msgstr "Tangkapan Layar"
#: templates/README.md.j2:48
#, python-format
msgid "Screenshot of %(application_name)s"
msgstr ""
msgstr "Tangkapan Layar pada %(application_name)s"
#: templates/README.md.j2:53
msgid "Disclaimers / important information"
msgstr ""
msgstr "Sangkalan / informasi penting"
#: templates/README.md.j2:59
msgid "Antifeatures"
msgstr ""
msgstr "Antifitur"
#: templates/README.md.j2:66
msgid "Documentation and resources"
msgstr ""
msgstr "Dokumentasi dan sumber daya"
#: templates/README.md.j2:68
msgid "Official app website:"
msgstr ""
msgstr "Website aplikasi resmi:"
#: templates/README.md.j2:70
msgid "Official user documentation:"
msgstr ""
msgstr "Dokumentasi pengguna resmi:"
#: templates/README.md.j2:72
msgid "Official admin documentation:"
msgstr ""
msgstr "Dokumentasi admin resmi:"
#: templates/README.md.j2:74
msgid "Upstream app code repository:"

View file

@ -26,6 +26,14 @@ upstream = "https://github.com/akaunting/akaunting"
website = "https://akaunting.com/"
added_date = 1695656621 # 2023/09/25
[aktivisda]
name = "Aktivisda"
description = "Web application to create visuals using an organization's graphic charter."
upstream = "https://framagit.org/aktivisda/aktivisda"
website = "https://aktivisda.earth"
added_date = 1720803998 # 2024/07/12
[amara]
name = "Amara"
description = "Collaborative translation of subtitles for videosCollaborative translation of subtitles for videos"
@ -55,6 +63,14 @@ upstream = "https://github.com/anonaddy/anonaddy"
website = "https://anonaddy.com/"
added_date = 1695656621 # 2023/09/25
[anytype]
name = "Anytype"
description = "Local-first note taking and knowledge management software."
upstream = "https://github.com/anyproto/any-sync"
website = "https://anytype.io"
added_date = 1720804319 # 2024/07/12
[appflowy]
name = "Appflowy"
description = "Alternative to Notion"
@ -481,6 +497,14 @@ upstream = "https://github.com/docker/distribution/"
website = ""
added_date = 1695656621 # 2023/09/25
[docmost]
name = "Docmost."
description = "Wiki and documentation software"
upstream = "https://github.com/docmost/docmost"
website = "https://docmost.com/"
added_date = 1721053354 # 2024/07/15
[docspell]
name = "Docspell"
description = "Simple document organizer"
@ -771,6 +795,14 @@ upstream = "https://github.com/graphhopper/graphhopper"
website = "https://www.graphhopper.com/"
added_date = 1695656621 # 2023/09/25
[graylog]
name = "Graylog"
description = "log management platform"
upstream = "https://github.com/Graylog2/graylog2-server"
website = "https://www.graylog.org/"
added_date = 1721053741 # 2024/07/15
[greenlight]
name = "Greenlight"
description = "A really simple end-user interface for your BigBlueButton server"
@ -2017,6 +2049,14 @@ upstream = "https://github.com/sismics/docs"
website = "https://teedy.io/"
added_date = 1695656621 # 2023/09/25
[tee-worlds]
name = "Tee Worlds"
description = "An online multiplayer game. Battle with up to 16 players in a variety of game modes."
upstream = "https://github.com/teeworlds/teeworlds"
website = "https://teeworlds.com/"
added_date = 1720804005 # 2024/07/12
[teleport]
name = "Teleport"
description = "Multi-protocol access proxy which understands SSH, HTTPS, RDP, Kubernetes API, MySQL, MongoDB and PostgreSQL wire protocols."
@ -2059,6 +2099,14 @@ upstream = "https://github.com/tmate-io/tmate"
website = "https://tmate.io/"
added_date = 1695656621 # 2023/09/25
[tootgroup]
name = "tootgroup"
description = "fediverse bot that re-toots content of a group of accounts on its own account"
upstream = "https://github.com/oe4dns/tootgroup.py"
website = ""
added_date = 1720804539 # 2024/07/12
[trivy]
name = "trivy"
description = "OSS Vulnerability and Misconfiguration Scanning."
@ -2073,6 +2121,14 @@ upstream = "https://foss.heptapod.net/tryton/"
website = "https://www.tryton.org/"
added_date = 1698609501 # 2023/10/29
[tube-archivist]
name = "Tube Archivist"
description = "Tube Archivist indexes and organizes archived YouTube videos through a convenient web interface."
upstream = "https://github.com/tubearchivist/tubearchivist"
website = "https://www.tubearchivist.com/"
added_date = 1720873225 # 2024/07/13
[tubesync]
name = "tubesync"
description = "Syncs YouTube channels and playlists to a locally hosted media server"