zoukankan      html  css  js  c++  java
  • homebrew 安装 formula 的不同历史版本——以安装 node 为例

    homebrew 安装 formula 的不同历史版本——以安装 node 为例

    系统环境

    • macOS Mojave 10.14
    • Homebrew 1.8.0
      Homebrew/homebrew-core (git revision 586b0f; last commit 2018-10-27)
      Homebrew/homebrew-cask (git revision 76ddc; last commit 2018-10-27)

    背景

    最近 nodejs 发布了 11.0.0 版本,而我是用 brew 安装了名为 node 的这个 formula ,现在 brew upgrade 会自动将 node 更新到最新版本,于是我遇到了一些问题:

    1. 一些需要编译安装的依赖包还不支持 node@11 ;
    2. 不知道如何自动切换两个 formula ( node 和 node@10 )之间的可执行文件;
    3. 是否能够设定某个 formula 不自动更新?

    在经过一番折腾后,现在我删掉了 node 和 node@10 两个 formula ,包括之前安装的历史版本(所以算是多走了一点弯路),想要同时保留 10 和 11 两个大版本,并可方便切换。

    前置条件

    若下列条件不满足,可能导致需要额外的操作来解决环境问题,这些操作不在本文讨论范围内:

    1. 只通过 homebrew 来安装 node ;
    2. 没有使用如 n / nvm 等 node 版本管理工具;
    3. 某种意义下连接性良好的网络。

    适用情况

    本文覆盖了如下四种情况:

    1. 某个 formula 跟随着更新上来,没有运行过 cleanup 或 force uninstall ,想切回旧版本的(见关键点三);
    2. 全新安装且只想安装某个 formula (如 node 而非 node@10 ),但又想先用着旧版本的(见解决方案一);
    3. 某个 formula 在用的是旧版本,但想切换编译选项(如 --with-openssl@1.1 )重新安装(同上);
    4. 在两个 formula 之间切换,如一个是 LTS 版的,一个是不稳定版的(见解决方案二)。

    关键点

    如何在 brew install / upgrade 时禁止自动更新

    这一步很关键,否则我们总是会安装到最新版本。只要在运行命令前,设置环境变量 HOMEBREW_NO_AUTO_UPDATE 为 1 就可以了,比如:

    $ HOMEBREW_NO_AUTO_UPDATE=1 brew install node
    

    也可以直接写进 shell 配置文件中(如 .bashrc / .zshrc 等):

    export HOMEBREW_NO_AUTO_UPDATE=1
    

    查看某个 formula 的本地已安装版本

    有两种方式可查看,一是 brew list --versions ,输出以空格分隔,简洁明了,推荐使用:

    $ brew list node --versions
    node 11.0.0 10.12.0
    $ brew list zsh --versions |tr ' ' '
    '
    node
    11.0.0
    10.12.0
    

    二是 brew info 在查看 formula 信息时也可看到本地已安装的版本:

    $ brew info node
    $ brew info node |grep -i '/cellar'
    /usr/local/Cellar/node/10.12.0 (3,668 files, 41.7MB)
    /usr/local/Cellar/node/11.0.0 (3,665 files, 42MB) *
    

    后面带有的星号 * 表示当前激活的版本。

    切换某个 formula 的版本

    自有的 brew switch 命令即可,之前感觉 brew 较易上手,安装后没看文档直接用到现在,所以不知道这个命令。命令的说明也很直观:

    brew switch formula version:
        Symlink all of the specific version of formula's install to Homebrew prefix.
    

    直接键盘一顿敲就行了,如 brew switch node 10.12.0

    解决方案

    安装某个 formula 的历史版本

    1. 切换到 brew 的仓库目录下

      $ cd "$(brew --repo homebrew/core)"
      
    2. 查看某个 formula 的 git 历史记录

      $ git log master -- Formula/node.rb
      

      在里面找到想要的历史版本,比如这个就挺像我所需要的:

      commit b801cc6b71e7c09448b4f823e493710665de68eb
      Author: BrewTestBot <homebrew-test-bot@lists.sfconservancy.org>
      Date:   Thu Oct 11 00:12:43 2018 +0000
      
          node: update 10.12.0 bottle.
      
    3. 检出 git 历史提交

      $ git checkout b801cc6b71e7c09448b4f823e493710665de68eb
      
    4. 在禁止自动更新的前提下安装这个 formula

      $ HOMEBREW_NO_AUTO_UPDATE=1 brew install node --with-openssl@1.1
      
    5. 由于刚才第 3 步后处于分离头指针状态下,记得要切回来

      $ git checkout master
      
    6. 升级这个 formula 试试

      $ brew upgrade node
      
    7. 检查当前版本,应该是最新的,现在再把它切回来

      $ node -v
      v11.0.0
      $ brew switch node 10.12.0
      Cleaning /usr/local/Cellar/node/10.12.0
      Cleaning /usr/local/Cellar/node/11.0.0
      7 links created for /usr/local/Cellar/node/10.12.0
      $ node -v
      v10.12.0
      

    在两个 formula 之间切换

    我们也可以在 node 和 node@10 两个 formula 之间切换文件链接。但是注意,这种方法可能会在运行 brew doctor 时产生警告,因为可能会有一个不是 keg-only 的包没有被链接到 Cellar 中(如为了使用 node@10 而解除了 node 的链接),这个警告可以不去理会,但必须记住我们做过这样的操作。

    1. 假定已经安装了 node ,现在安装 node@10 ,键盘一顿乱敲

      $ brew install node@10
      

      通常像这样名字后面带有版本号的 formula 都是 keg-only 的,简单来说就是 brew 不会自动帮我们链接文件

    2. 先解除 node 的文件链接

      $ brew unlink node
      
    3. 链接 node@10 的文件

      $ brew link node@10
      

      这时会提示这个包是 keg-only 的,需要加上 --force 选项。如果第 2 步没有进行,还会提示你需要先解除 node 的链接,或者直接用 --overwrite 选项覆盖原有的链接。由于 npm 目录一定需要覆盖,所以我们总是可以打开 --overwrite 选项:

      $ brew link node@10 --force --overwrite
      
    4. 检查当前版本,在解决方案一中提到过了,方法也有很多种,此处略过。

    后续问题

    1. 全局安装的包支持的 node 版本可能不同
      是的,这个问题一定会存在,建议通过切换 npm prefix 路径解决,把不同版本 node 下安装的全局包隔离开来。当然 nvm 等方案也可以解决问题,但本文是不一样的烟火。

      $ mkdir -p ~/.npm-node10/npm-global
      $ npm config set prefix ~/.npm-node10/npm-global
      $ export PATH="$HOME/.npm-node10/npm-global/bin:$PATH"
      

      手动切换确实比较繁琐,可以写个 shell 脚本把切换 formula 和切换 npm prefix 结合起来。

    2. 如何固定某个 formula 的版本?
      虽然说不运行 brew upgrade 就一直是固定的版本,但如果想只固定某个 formula 的版本而允许其他可以升级,也是极好的。自带的 pin 、 unpin 命令就是用来解决这一问题,如: brew pin node

    3. 如何删除某个 formula 的旧版本?
      尽管 brew cleanup 可以删除一个 formula 的所有旧版本,但通常我们可能只想删除某几个太旧且多余的版本而不是全部。 brew 没有提供这样的命令,我们可以直接从 Cellar 里面删除:

      $ brew info node |grep -i '/cellar'
      /usr/local/Cellar/node/10.12.0 (3,668 files, 41.7MB)
      /usr/local/Cellar/node/11.0.0 (3,665 files, 42MB) *
      $ rm -rf /usr/local/Cellar/node/10.12.0
      

      初步测试未发现有副作用,欢迎讨论和建议。

    4. 如何在升级时自动删除旧版本?
      根据 brew upgrade 命令的说明,设置一个 HOMEBREW_UPGRADE_CLEANUP 环境变量就好了,比较简单。

    参考资料

    1. Tips and Tricks - Homebrew Documentation
    2. Homebrew terminology - Homebrew Documentation
    3. FAQ - Homebrew Documentation
    4. homebrew - how to install older versions - Stack Overflow
    5. Homebrew install specific version of formula? - Stack Overflow
    6. Using Homebrew how do I remove some specific versions but not all old versions - Stack Overflow



    本文基于 知识共享许可协议知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 发布,欢迎引用、转载或演绎,但是必须保留本文的署名 BlackStorm 以及本文链接 http://www.cnblogs.com/BlackStorm/p/homebrew-install-old-versions-take-node-for-example.html ,且未经许可不能用于商业目的。如有疑问或授权协商请与我联系

  • 相关阅读:
    FMDB 使用方法
    Masonry
    iOS请求服务器数据去空NSNull
    NSProgress
    根据图标名称动态设置TreeList图标
    控制显示行头列(Indicator)
    窗体内元素遍历-通用方法(DevExpress 中BarManager的遍历)
    BarManager相关使用
    C# 枚举变量
    dev TreeList 获取可视区域节点方法
  • 原文地址:https://www.cnblogs.com/BlackStorm/p/homebrew-install-old-versions-take-node-for-example.html
Copyright © 2011-2022 走看看