如何修复YAML语法错误:解析块时未找到预期的“-”指示符?

42

我有一些代码写在我的.travis.yml文件中,是为了一个Python库。使用lint.travis-ci.org,我知道我的YAML文件中存在一些缩进问题。这是错误指向的部分:

install:

  - if [[ "${TEST_PY3}" == "false" ]]; then
      pip install Cython;
      python setup.py build; # To build networkx-metis
      mkdir core; # For the installation of networkx core
      cd core;
      git clone https://github.com/orkohunter/networkx.git;
      cd networkx/;
      git checkout addons;
      python setup.py install;
      cd ..;
    fi

我错在哪里了?错误信息如下

syntax error: (<unknown>): did not find expected '-' indicator while parsing a block collection at line 32 column 3

如果有一个像autopep8这样的工具可以修复YAML文件的缩进,那将是非常棒的。


“询问我们推荐或寻找书籍、工具、软件库、教程或其他外部资源的问题”是 Stack Overflow 的禁止主题,因为它们往往会吸引带有个人观点的答案和垃圾邮件。此外,“yaml linter”在谷歌上有15k次搜索结果,所以建议您进行一些研究。 - jonrsharpe
1
是的,15k次点击加1。我不是在谈论验证,而是纠正我的文件。所有这些谷歌搜索都提供了验证。我已经做了一些研究,找不到任何工具、软件库等,因此没有机会得到有偏见的答案。谢谢。 - Himanshu Mishra
然而,像所有推荐问题一样,这个问题在Stack Overflow上是不适合的。如果您能提供一个目的和一些客观要求(您当前的问题缺乏),它可能适用于SoftwareRecs - 请参见http://softwarerecs.stackexchange.com/help/on-topic - jonrsharpe
谢谢帮助。 - Himanshu Mishra
@HimanshuMishra,你的“我错在哪里?”问题很适合这个网站。但是询问像autopep8这样的工具就不太合适了。我修改了问题,使其符合[so]的范围。 - Anthon
3个回答

19

你的文件中没有32行(可能是因为你从示例中剥离了非必要数据),但缩进级别指向带有fi的行。

实际上,问题开始得更早,你要做的是将要执行的操作指定为多行字符串。你可以用多种方式在YAML中指定这些内容,但最干净的方法是使用文字标量指示符 "|",它会保留换行符:

install:

  - |
    if [[ "${TEST_PY3}" == "false" ]]; then
      pip install Cython;
      python setup.py build; # To build networkx-metis
      mkdir core; # For the installation of networkx core
      cd core;
      git clone https://github.com/orkohunter/networkx.git;
      cd networkx/;
      git checkout addons;
      python setup.py install;
      cd ..;
    fi

对于这种错误,没有自动的YAML重新缩进工具。

Python的重新缩进器将可行代码并使缩进一致(替换TAB,每个级别始终相同缩进)。在语法错误的代码上重新缩进Python代码要么不起作用,要么可能会产生非正确结果。

YAML的重新缩进器面临着同样的问题:如果输入没有意义怎么办(对你和我来说很清楚,但对程序来说不总是很清楚)。仅将无法解析的所有内容转换为多行标量不是通用解决方案。

此外,大多数YAML解析器在读取文件时会丢弃一些信息,您不希望它们在重新缩进时丢失,包括EOL注释、手工制作的锚点名称、映射键排序等。而且还要符合规范的要求。

如果您想统一缩进(正确的)YAML,则可以使用ruamel.yaml包中的yaml实用程序(免责声明:我是该包的作者)。您用于yaml round-trip .travis.yml的原始输入将如下所示:

 ...
  in "<byte string>", line 3, column 3:
      - if [[ "${TEST_PY3}" == "false" ... 
      ^
expected <block end>, but found '<scalar>'
  in "<byte string>", line 6, column 7:
          mkdir core; # For the installati ...

很遗憾,这并没有帮助我们找到错误,通过运行yaml round-trip .travis.yml命令可获取正确的.travis.yml版本,并且它会在第二次轮回(即第一次轮回时会丢失额外空格)时稳定。而yaml round-trip .travis.yml --save则可以提供给你:

install:
- |
  if [[ "${TEST_PY3}" == "false" ]]; then
    pip install Cython;
    python setup.py build; # To build networkx-metis
    mkdir core; # For the installation of networkx core
    cd core;
    git clone https://github.com/orkohunter/networkx.git;
    cd networkx/;
    git checkout addons;
    python setup.py install;
    cd ..;
  fi

请注意,在这里# TO build networkx-metis并不是YAML注释,它只是多行字符串的一部分。然而,在第一行之前或最后一行之后的注释将会被保留。


8

这个错误意味着你有语法错误,并且这种错误很难追踪,因为它可能意味着多种情况,如缩进错误,包括缺少双引号或需要确保对某些特殊字符加上双引号。

如果你在 git 仓库中跟踪你的 .travis.yml 文件,在使用 travis 命令时可以轻松检查以前的版本并进行比较。

例如:

$ travis lint <(git show HEAD^:.travis.yml )
Warnings for /dev/fd/63:
[x] syntax error: (<unknown>): did not find expected '-' indicator while parsing a block collection at line 61 column 3
$ travis lint <(git show HEAD~2:.travis.yml)
Hooray, /dev/fd/63 looks valid :)

HEAD~2 表示检查落后于 2 个提交,因此需要增加数字直到命令可以正常执行为止。找到相应的数字后,比较如下:

git diff HEAD~2 .travis.yml

否则,将其分成较小的部分或持续删除一些部分,直到它能够正常工作。
使用ruby是检查您的YAML语法的替代方法:
ruby -e "require 'yaml';puts YAML.load_file('.travis.yml')"

因此,您不需要每次通过travis进行POST代码,它的工作方式类似于Travis WebLint


示例

以下语法是不正确的:

language: python
before_script:
  - |
    true
# Some comment.
    true

因为注释的缩进不正确,如下所示:

[x] 语法错误:():在解析块集合时未找到预期的'-'指示符,在第3行第3列

这是有效的语法:

language: python
before_script:
  - |
    true
    # Some comment.
    true

上述问题在使用Vim编辑文件时特别容易出现,这是因为Vim对注释进行了缩进,使它们从开头开始。

0
对我来说,我的文件中报告了第17行的错误,但实际上是在我的配置文件的第84行有一个无效的注释(我使用了--而不是#)...更正注释后,“第17行”的错误消失了。
#justyamlthings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接