[update] Implement --update-to
repo
Authored by: Grub4K, pukkandan
This commit is contained in:
parent
d2e84d5eb0
commit
665472a7de
4 changed files with 41 additions and 23 deletions
13
README.md
13
README.md
|
@ -196,12 +196,15 @@ There are currently two release channels for binaries, `stable` and `nightly`.
|
||||||
The `nightly` channel has releases built after each push to the master branch, and will have the most recent fixes and additions, but also have more risk of regressions. They are available in [their own repo](https://github.com/yt-dlp/yt-dlp-nightly-builds/releases).
|
The `nightly` channel has releases built after each push to the master branch, and will have the most recent fixes and additions, but also have more risk of regressions. They are available in [their own repo](https://github.com/yt-dlp/yt-dlp-nightly-builds/releases).
|
||||||
|
|
||||||
When using `--update`/`-U`, a release binary will only update to its current channel.
|
When using `--update`/`-U`, a release binary will only update to its current channel.
|
||||||
This release channel can be changed by using the `--update-to` option. `--update-to` can also be used to upgrade or downgrade to specific tags from a channel.
|
`--update-to CHANNEL` can be used to switch to a different channel when a newer version is available. `--update-to [CHANNEL@]TAG` can also be used to upgrade or downgrade to specific tags from a channel.
|
||||||
|
|
||||||
|
You may also use `--update-to <repository>` (`<owner>/<repository>`) to update to a channel on a completely different repository. Be careful with what repository you are updating to though, there is no verification done for binaries from different repositories.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
* `yt-dlp --update-to nightly` change to `nightly` channel and update to its latest release
|
* `yt-dlp --update-to nightly` change to `nightly` channel and update to its latest release
|
||||||
* `yt-dlp --update-to stable@2023.02.17` upgrade/downgrade to release to `stable` channel tag `2023.02.17`
|
* `yt-dlp --update-to stable@2023.02.17` upgrade/downgrade to release to `stable` channel tag `2023.02.17`
|
||||||
* `yt-dlp --update-to 2023.01.06` upgrade/downgrade to tag `2023.01.06` if it exists on the current channel
|
* `yt-dlp --update-to 2023.01.06` upgrade/downgrade to tag `2023.01.06` if it exists on the current channel
|
||||||
|
* `yt-dlp --update-to example/yt-dlp@2023.03.01` upgrade/downgrade to the release from the `example/yt-dlp` repository, tag `2023.03.01`
|
||||||
|
|
||||||
<!-- MANPAGE: BEGIN EXCLUDED SECTION -->
|
<!-- MANPAGE: BEGIN EXCLUDED SECTION -->
|
||||||
## RELEASE FILES
|
## RELEASE FILES
|
||||||
|
@ -360,10 +363,10 @@ If you fork the project on GitHub, you can run your fork's [build workflow](.git
|
||||||
-U, --update Update this program to the latest version
|
-U, --update Update this program to the latest version
|
||||||
--no-update Do not check for updates (default)
|
--no-update Do not check for updates (default)
|
||||||
--update-to [CHANNEL]@[TAG] Upgrade/downgrade to a specific version.
|
--update-to [CHANNEL]@[TAG] Upgrade/downgrade to a specific version.
|
||||||
CHANNEL and TAG defaults to "stable" and
|
CHANNEL can be a repository as well. CHANNEL
|
||||||
"latest" respectively if omitted; See
|
and TAG default to "stable" and "latest"
|
||||||
"UPDATE" for details. Supported channels:
|
respectively if omitted; See "UPDATE" for
|
||||||
stable, nightly
|
details. Supported channels: stable, nightly
|
||||||
-i, --ignore-errors Ignore download and postprocessing errors.
|
-i, --ignore-errors Ignore download and postprocessing errors.
|
||||||
The download will be considered successful
|
The download will be considered successful
|
||||||
even if the postprocessing fails
|
even if the postprocessing fails
|
||||||
|
|
|
@ -939,7 +939,7 @@ def _real_main(argv=None):
|
||||||
ydl.cache.remove()
|
ydl.cache.remove()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
updater = Updater(ydl, opts.update_self if isinstance(opts.update_self, str) else None)
|
updater = Updater(ydl, opts.update_self)
|
||||||
if opts.update_self and updater.update() and actual_use:
|
if opts.update_self and updater.update() and actual_use:
|
||||||
if updater.cmd:
|
if updater.cmd:
|
||||||
return updater.restart()
|
return updater.restart()
|
||||||
|
|
|
@ -323,7 +323,7 @@ def create_parser():
|
||||||
help='Print program version and exit')
|
help='Print program version and exit')
|
||||||
general.add_option(
|
general.add_option(
|
||||||
'-U', '--update',
|
'-U', '--update',
|
||||||
action='store_true', dest='update_self',
|
action='store_const', dest='update_self', const=CHANNEL,
|
||||||
help=format_field(
|
help=format_field(
|
||||||
is_non_updateable(), None, 'Check if updates are available. %s',
|
is_non_updateable(), None, 'Check if updates are available. %s',
|
||||||
default=f'Update this program to the latest {CHANNEL} version'))
|
default=f'Update this program to the latest {CHANNEL} version'))
|
||||||
|
@ -335,9 +335,9 @@ def create_parser():
|
||||||
'--update-to',
|
'--update-to',
|
||||||
action='store', dest='update_self', metavar='[CHANNEL]@[TAG]',
|
action='store', dest='update_self', metavar='[CHANNEL]@[TAG]',
|
||||||
help=(
|
help=(
|
||||||
'Upgrade/downgrade to a specific version. CHANNEL and TAG defaults to '
|
'Upgrade/downgrade to a specific version. CHANNEL can be a repository as well. '
|
||||||
f'"{CHANNEL}" and "latest" respectively if omitted; See "UPDATE" for details. '
|
f'CHANNEL and TAG default to "{CHANNEL.partition("@")[0]}" and "latest" respectively if omitted; '
|
||||||
f'Supported channels: {", ".join(UPDATE_SOURCES)}'))
|
f'See "UPDATE" for details. Supported channels: {", ".join(UPDATE_SOURCES)}'))
|
||||||
general.add_option(
|
general.add_option(
|
||||||
'-i', '--ignore-errors',
|
'-i', '--ignore-errors',
|
||||||
action='store_true', dest='ignoreerrors',
|
action='store_true', dest='ignoreerrors',
|
||||||
|
|
|
@ -129,27 +129,36 @@ class Updater:
|
||||||
self.ydl = ydl
|
self.ydl = ydl
|
||||||
|
|
||||||
self.target_channel, sep, self.target_tag = (target or CHANNEL).rpartition('@')
|
self.target_channel, sep, self.target_tag = (target or CHANNEL).rpartition('@')
|
||||||
if not sep and self.target_tag in UPDATE_SOURCES: # stable => stable@latest
|
# stable => stable@latest
|
||||||
self.target_channel, self.target_tag = self.target_tag, None
|
if not sep and ('/' in self.target_tag or self.target_tag in UPDATE_SOURCES):
|
||||||
|
self.target_channel = self.target_tag
|
||||||
|
self.target_tag = None
|
||||||
elif not self.target_channel:
|
elif not self.target_channel:
|
||||||
self.target_channel = CHANNEL
|
self.target_channel = CHANNEL.partition('@')[0]
|
||||||
|
|
||||||
if not self.target_tag:
|
if not self.target_tag:
|
||||||
self.target_tag, self._exact = 'latest', False
|
self.target_tag = 'latest'
|
||||||
|
self._exact = False
|
||||||
elif self.target_tag != 'latest':
|
elif self.target_tag != 'latest':
|
||||||
self.target_tag = f'tags/{self.target_tag}'
|
self.target_tag = f'tags/{self.target_tag}'
|
||||||
|
|
||||||
@property
|
if '/' in self.target_channel:
|
||||||
def _target_repo(self):
|
self._target_repo = self.target_channel
|
||||||
try:
|
if self.target_channel not in (CHANNEL, *UPDATE_SOURCES.values()):
|
||||||
return UPDATE_SOURCES[self.target_channel]
|
self.ydl.report_warning(
|
||||||
except KeyError:
|
f'You are switching to an {self.ydl._format_err("unofficial", "red")} executable '
|
||||||
return self._report_error(
|
f'from {self.ydl._format_err(self._target_repo, self.ydl.Styles.EMPHASIS)}. '
|
||||||
f'Invalid update channel {self.target_channel!r} requested. '
|
f'Run {self.ydl._format_err("at your own risk", "light red")}')
|
||||||
f'Valid channels are {", ".join(UPDATE_SOURCES)}', True)
|
self.restart = self._blocked_restart
|
||||||
|
else:
|
||||||
|
self._target_repo = UPDATE_SOURCES.get(self.target_channel)
|
||||||
|
if not self._target_repo:
|
||||||
|
self._report_error(
|
||||||
|
f'Invalid update channel {self.target_channel!r} requested. '
|
||||||
|
f'Valid channels are {", ".join(UPDATE_SOURCES)}', True)
|
||||||
|
|
||||||
def _version_compare(self, a, b, channel=CHANNEL):
|
def _version_compare(self, a, b, channel=CHANNEL):
|
||||||
if channel != self.target_channel:
|
if self._exact and channel != self.target_channel:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if _VERSION_RE.fullmatch(f'{a}.{b}'):
|
if _VERSION_RE.fullmatch(f'{a}.{b}'):
|
||||||
|
@ -372,6 +381,12 @@ class Updater:
|
||||||
_, _, returncode = Popen.run(self.cmd)
|
_, _, returncode = Popen.run(self.cmd)
|
||||||
return returncode
|
return returncode
|
||||||
|
|
||||||
|
def _blocked_restart(self):
|
||||||
|
self._report_error(
|
||||||
|
'Automatically restarting into custom builds is disabled for security reasons. '
|
||||||
|
'Restart yt-dlp to use the updated version', expected=True)
|
||||||
|
return self.ydl._download_retcode
|
||||||
|
|
||||||
|
|
||||||
def run_update(ydl):
|
def run_update(ydl):
|
||||||
"""Update the program file with the latest version from the repository
|
"""Update the program file with the latest version from the repository
|
||||||
|
|
Loading…
Reference in a new issue