diff --git a/README.md b/README.md index 33b57b83..5c41abb5 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,12 @@ Please note that the _`[]`_ portion of the command should be the url to you Make sure to [send us a PR][omf-pulls-link] to update the registry. +#### `omf channel` + +Gets or changes the update channel. + +Two channels are available by default: the `stable` channel provides stable updates with the latest tagged version of Oh My Fish, and `dev` which provides the latest changes under development. The update channel currently set determines what version `omf update` will upgrade to. + #### `omf doctor` Use to troubleshoot before [opening an issue][omf-issues-new]. diff --git a/bin/install b/bin/install index 252020fe..564e4d2a 100755 --- a/bin/install +++ b/bin/install @@ -21,6 +21,7 @@ function main set -g OMF_PATH "$OMF_PATH_DEFAULT" set -g OMF_CONFIG "$OMF_CONFIG_DEFAULT" + set -g OMF_CHANNEL stable # Ensure repository URL ends with .git set OMF_REPO_URI (echo $OMF_REPO_URI | command sed 's/\.git//').git @@ -33,6 +34,7 @@ function main Install Oh My Fish Options: + --channel= Download a specific release channel, either \"stable\" or \"dev\" (default is \"$OMF_CHANNEL\"). --config= Put config in a specific path (default is $OMF_CONFIG_DEFAULT). --help, -h Show this help message. --noninteractive Disable interactive questions (assume no, use with --yes to assume yes). @@ -43,6 +45,15 @@ Options: " return 0 + case '--channel=stable' + set -g OMF_CHANNEL stable + + case '--channel=dev' + set -g OMF_CHANNEL dev + + case '--channel=*' + abort "Unknown release channel \""(echo "$argv[1]" | command cut -d= -f2)"\"." + case '--config=*' echo "$argv[1]" | command cut -d= -f2 | command sed -e "s#~#$HOME#" | read -g OMF_CONFIG @@ -139,12 +150,23 @@ end # Downloads and installs the framework from GitHub. function install_from_github + say "Using release channel \"$OMF_CHANNEL\"." say "Cloning $OMF_REPO_BRANCH from $OMF_REPO_URI..." - if not command git clone -q --depth 1 -b $OMF_REPO_BRANCH $OMF_REPO_URI "$OMF_PATH" + if not command git clone -q -b "$OMF_REPO_BRANCH" "$OMF_REPO_URI" "$OMF_PATH" abort "Error cloning repository!" end + if test $OMF_CHANNEL = stable + # Get the commit for the latest release. + set -l hash (command git --git-dir "$OMF_PATH/.git" --work-tree "$OMF_PATH" rev-list --tags='v*' --max-count=1 ^ /dev/null) + # Get the release tag. + and set -l tag (command git --git-dir "$OMF_PATH/.git" --work-tree "$OMF_PATH" describe --tags $hash) + # Checkout the release. + and command git --git-dir "$OMF_PATH/.git" --work-tree "$OMF_PATH" checkout --quiet tags/$tag + or report error "Error getting latest version!" + end + set_git_remotes end @@ -275,6 +297,8 @@ function install_config test -f "$OMF_CONFIG/bundle"; or echo "theme default" > "$OMF_CONFIG/bundle" + test -f "$OMF_CONFIG/channel"; + or echo $OMF_CHANNEL > "$OMF_CONFIG/channel" test -f "$OMF_CONFIG/theme" or echo "default" > "$OMF_CONFIG/theme" @@ -433,11 +457,17 @@ function is_version_compatible -a lhs rhs set -q argv[2] or return 1 - # Sort the versions to get the lesser one. - set -l sorted (printf "$lhs\n$rhs\n" | command sort -n -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4) + # Right-hand side must be the largest version. + test "$rhs" = (get_latest_version "$lhs" "$rhs") +end + - # Left-hand side must be the smallest version. - test "$lhs" = "$sorted[1]" +# Returns the newest version from a given list of versions. +function get_latest_version + # Sort the version in descending order and output the top result. + for v in $argv + echo "$v" + end | command sort -r -n -t '.' -k 1,1 -k 2,2 -k 3,3 -k 4,4 | command head -n 1 end diff --git a/init.fish b/init.fish index 51514fdc..2ca476bc 100644 --- a/init.fish +++ b/init.fish @@ -43,5 +43,4 @@ end emit perf:timer:start "Oh My Fish init user config path" require --no-bundle --path $OMF_CONFIG emit perf:timer:finish "Oh My Fish init user config path" -set -g OMF_VERSION "2" emit perf:timer:finish "Oh My Fish initialisation" diff --git a/pkg/omf/completions/omf.fish b/pkg/omf/completions/omf.fish index 904073ad..7089a15f 100644 --- a/pkg/omf/completions/omf.fish +++ b/pkg/omf/completions/omf.fish @@ -20,6 +20,7 @@ end complete -c omf -f -n "__fish_seen_subcommand_from d desc describe" -a (printf "%s " (omf.packages.list --database --plugin)) complete -c omf -f -n "__fish_seen_subcommand_from t theme" -a "$installed_themes" +complete -c omf -f -n "__fish_seen_subcommand_from channel" -a "stable dev" complete -c omf -f -n "__fish_seen_subcommand_from help" -a "install theme remove update list describe cd new submit destroy doctor" complete -c omf -f -a list -n "__fish_use_subcommand" -d "List local packages" @@ -35,3 +36,4 @@ complete -c omf -f -a submit -n "__fish_use_subcommand" -d "Submit a package t complete -c omf -f -a help -n "__fish_use_subcommand" -d "Display this help" complete -c omf -f -a destroy -n "__fish_use_subcommand" -d "Remove Oh My Fish" complete -c omf -f -a doctor -n "__fish_use_subcommand" -d "Troubleshoot Oh My Fish" +complete -c omf -f -a channel -n "__fish_use_subcommand" -d "Gets or changes the update channel" diff --git a/pkg/omf/functions/cli/omf.cli.channel.fish b/pkg/omf/functions/cli/omf.cli.channel.fish new file mode 100644 index 00000000..3c631963 --- /dev/null +++ b/pkg/omf/functions/cli/omf.cli.channel.fish @@ -0,0 +1,14 @@ +function omf.cli.channel + switch (count $argv) + case 0 + omf.channel.get + + case 1 + omf.channel.set $argv + + case '*' + echo (omf::err)"Invalid number of arguments"(omf::off) 1^&2 + omf help channel + return $OMF_INVALID_ARG + end +end diff --git a/pkg/omf/functions/cli/omf.cli.help.fish b/pkg/omf/functions/cli/omf.cli.help.fish index 03b271b6..2343e0cf 100644 --- a/pkg/omf/functions/cli/omf.cli.help.fish +++ b/pkg/omf/functions/cli/omf.cli.help.fish @@ -14,6 +14,25 @@ Change directory to root or plugin/theme directory. omf cd l " + case "channel" + echo \n"\ +Gets or changes the update channel. + +Two channels are available by default: the "(omf::em)"stable"(omf::off)" channel provides stable +updates with the latest tagged version of Oh My Fish, and "(omf::em)"dev"(omf::off)" which provides +the latest changes under development. The update channel currently set +determines what version "(omf::em)"omf update"(omf::off)" will upgrade to. + +"(omf::dim)"Usage:"(omf::off)" + omf channel Print the currently selected update channel + omf channel "(omf::em)""(omf::off)" Switch to the given update channel + +"(omf::dim)"Examples:"(omf::off)" + omf channel + omf channel stable + omf channel dev +" + case "d" "describe" echo "\ Get information about what packages do. diff --git a/pkg/omf/functions/cli/omf.cli.update.fish b/pkg/omf/functions/cli/omf.cli.update.fish index 0a1e6ff4..0f42105d 100644 --- a/pkg/omf/functions/cli/omf.cli.update.fish +++ b/pkg/omf/functions/cli/omf.cli.update.fish @@ -13,8 +13,14 @@ function omf.cli.update if set -q update_core omf.core.update + + if type -q omf.version + set OMF_VERSION (omf.version) + end + if test $status -ne 1 echo (omf::em)"Oh My Fish is up to date."(omf::off) + echo (omf::em)"You are now using Oh My Fish version $OMF_VERSION."(omf::off) else echo (omf::err)"Oh My Fish failed to update."(omf::off) echo "Please open a new issue here → "(omf::em)"github.com/oh-my-fish/oh-my-fish/issues"(omf::off) diff --git a/pkg/omf/functions/cli/omf.cli.version.fish b/pkg/omf/functions/cli/omf.cli.version.fish index 61cfc171..1cfe7e6e 100644 --- a/pkg/omf/functions/cli/omf.cli.version.fish +++ b/pkg/omf/functions/cli/omf.cli.version.fish @@ -1,3 +1,3 @@ function omf.cli.version - echo "Oh My Fish! $OMF_VERSION" + echo "Oh My Fish version "(omf.version) end diff --git a/pkg/omf/functions/core/omf.channel.get.fish b/pkg/omf/functions/core/omf.channel.get.fish new file mode 100644 index 00000000..aaf24934 --- /dev/null +++ b/pkg/omf/functions/core/omf.channel.get.fish @@ -0,0 +1,17 @@ +function omf.channel.get + # Check for an environment variable override. + if set -q OMF_CHANNEL + echo $OMF_CHANNEL + return 0 + end + + # Check the channel file. + if test -f $OMF_CONFIG/channel + read -l channel < $OMF_CONFIG/channel + and echo $channel + and return 0 + end + + # Assume 'stable' if not specified. + echo stable +end diff --git a/pkg/omf/functions/core/omf.channel.set.fish b/pkg/omf/functions/core/omf.channel.set.fish new file mode 100644 index 00000000..d9d2a5a4 --- /dev/null +++ b/pkg/omf/functions/core/omf.channel.set.fish @@ -0,0 +1,11 @@ +function omf.channel.set -a name + # If an argument is specified, set the update channel. + if begin; test -z "$name"; or not contains -- $name stable dev; end + echo (omf::err)"'$name' is not a valid channel."(omf::off) 1^&2 + return 1 + end + + echo $name > $OMF_CONFIG/channel + echo "Update channel set to "(omf::em)"$name"(omf::off)"." + echo "To switch to the latest $name version, run "(omf::em)"omf update"(omf::off)"." +end diff --git a/pkg/omf/functions/core/omf.core.update.fish b/pkg/omf/functions/core/omf.core.update.fish index 2cf343af..1e10ea27 100644 --- a/pkg/omf/functions/core/omf.core.update.fish +++ b/pkg/omf/functions/core/omf.core.update.fish @@ -1,3 +1,44 @@ function omf.core.update - omf.repo.pull $OMF_PATH + # If on the stable channel, checkout the latest tag. + if test (omf.channel.get) = stable + # If the channel isn't explicitly set and we are currently tracking a branch instead of a version, the user probably + # upgraded from an old version. Let them know that we will start updating to stable versions. + if begin; not test -f $OMF_CONFIG/channel; and command git -C "$OMF_PATH" symbolic-ref -q HEAD > /dev/null; end + set_color $fish_color_quote ^/dev/null; or set_color yellow --bold + echo ">> You have been switched to the stable release channel of Oh My Fish." + echo ">> To switch back to the development channel, run `omf channel dev`." + set_color normal + end + + # Determine the remote to fetch from. + set -l remote origin + if test (command git -C "$OMF_PATH" config --get remote.upstream.url) + set remote upstream + end + + # Fetch the latest tags. + command git -C "$OMF_PATH" fetch --quiet --tags $remote + # Get the commit for the latest release. + and set -l hash (command git -C "$OMF_PATH" rev-list --tags='v*' --max-count=1 ^ /dev/null) + # Get the release tag. + and set -l tag (command git -C "$OMF_PATH" describe --tags $hash) + # Checkout the release. + and command git -C "$OMF_PATH" checkout --quiet tags/$tag + and return 0 + + # Something went wrong. + echo (omf::err)"No release versions found."(omf::off) + return 1 + else + # Determine the branch to use for the dev channel. + set -q OMF_DEV_BRANCH + or set -l OMF_DEV_BRANCH master + + # Switch to the master branch if we are in a detached head. + command git -C "$OMF_PATH" symbolic-ref -q HEAD > /dev/null + or command git -C "$OMF_PATH" checkout $OMF_DEV_BRANCH --quiet + + # Pull the latest for the current branch. + omf.repo.pull $OMF_PATH + end end diff --git a/pkg/omf/functions/core/omf.version.fish b/pkg/omf/functions/core/omf.version.fish new file mode 100644 index 00000000..74644238 --- /dev/null +++ b/pkg/omf/functions/core/omf.version.fish @@ -0,0 +1,3 @@ +function omf.version + command git -C "$OMF_PATH" describe --tags --match 'v*' --always | cut -c 2- +end diff --git a/pkg/omf/functions/omf.fish b/pkg/omf/functions/omf.fish index 15c96616..9a296683 100644 --- a/pkg/omf/functions/omf.fish +++ b/pkg/omf/functions/omf.fish @@ -64,9 +64,15 @@ function omf -d "Oh My Fish" case "u" "update" omf.cli.update $arguments + case "channel" + omf.cli.channel $arguments + case "search" omf.cli.search $arguments + case "version" + omf.cli.version $arguments + case "*" echo (omf::err)"$argv[1] option not recognized"(omf::off) 1^&2 return $OMF_UNKNOWN_OPT