有什么替代方法可以编写bash脚本来更新项目的依赖关系?

时间:2019-07-08 11:53:04

标签: bash npm

我写了一个脚本来更新项目的依赖关系(只有未成年人和补丁)。我想自动执行升级过程,因为所有版本都是精确的,而且据我所知,没有办法暗示npm update我想改变一切。

简而言之,它获取正在运行的npm outdated的输出,根据条件构建软件包列表,并在最后将其提供给npm install。一切都按预期工作,但是我想知道是否可以更简洁的方式编写它,例如无需创建临时文本文件?我也在寻找一些一般性反馈。

P.S。我只是从bash脚本开始,所以请饶恕我:D非常感谢您的建议!

以下是npm outdated的示例输出:

Package                          Current  Wanted  Latest  Location
@commitlint/cli                    7.5.0   .....   8.0.0    .....
@commitlint/config-conventional    7.5.0   .....   8.0.0    .....
eslint                            5.13.0   .....   6.0.1    .....
eslint-plugin-jsx-a11y             6.2.0   .....   6.2.3    .....
eslint-plugin-react               7.12.4   .....  7.14.2    .....
eslint-plugin-react-hooks          1.6.0   .....   1.6.1    .....

代码如下:

# Temporary file to hold output of `npm outdated` command
OUTPUT=updates.log
PACKAGES_TO_UPDATE=()

function get_major_version { echo $(echo $1 | grep -o -E '^[0-9]{1,2}'); }

# https://stackoverflow.com/questions/1527049/how-can-i-join-elements-of-an-array-in-bash
function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }

# Redirect output once.
{
  npm outdated
} > $OUTPUT

wait

{
  # Skip first line as it contains column headers.
  read

  while read package current wanted latest location
    do
      # Filter out major updates.
      if [ "$(get_major_version $current)" = "$(get_major_version $latest)" ]; then
        PACKAGES_TO_UPDATE+=("${package}@latest")
      fi
  done
} < $OUTPUT

npm install "${PACKAGES_TO_UPDATE[@]}"

rm $OUTPUT

1 个答案:

答案 0 :(得分:1)

使用 Process Substitution 获得更简洁的语法:

PACKAGES_TO_UPDATE=()

function get_major_version { echo $(echo $1 | grep -o -E '^[0-9]{1,2}'); }
function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }

while read package current wanted latest location; do
  if [ "$(get_major_version $current)" = "$(get_major_version $latest)" ]; then
    PACKAGES_TO_UPDATE+=("${package}@latest")
  fi
done < <(npm outdated|awk 'NR>1')

npm install "${PACKAGES_TO_UPDATE[@]}"

来自bash man

  Process Substitution
       Process substitution is supported on systems that support named pipes  (FIFOs)  or  the  /dev/fd
       method  of naming open files.  It takes the form of <(list) or >(list).  The process list is run
       with its input or output connected to a FIFO or some file in /dev/fd.  The name of this file  is
       passed  as  an  argument  to the current command as the result of the expansion.  If the >(list)
       form is used, writing to the file will provide input for list.  If the <(list) form is used, the
       file passed as an argument should be read to obtain the output of list.

说明

  • npm outdated|awk 'NR>1':在这里,我们将npm outdated的输出通过管道传递到awk,这又切断了不必要的标题('NR>1'意味着从第二行开始读取),因此我们可以避免多余的read。让我们以 alias 作为 input_process

  • <(input_process):使用与读取文件相同的机制执行该过程,并将其输出传递到while read循环。