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

时间:2015-06-28 21:25:43

标签: syntax-error yaml indentation travis-ci

我有一些用我的.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文件的缩进,那将会很棒。

2 个答案:

答案 0 :(得分:6)

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

实际上问题是早些时候开始的,你想要做的是指定要作为多行字符串的操作。你可以用多种方式在YAML中指定它们,但最干净的是使用literal scalar指示符&#34; |&#34;,它会保留换行符:

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重新缩进工具。

Reindenters for Python采用工作代码并使缩进保持一致(替换TAB,每个级别总是相同的缩进)。对具有语法错误的代码进行Python代码重新缩进,要么不起作用,要么可能产生不正确的结果。

YAML的Reindenters面临着同样的问题:如果输入没有意义怎么办(你和我清楚的是,程序并不总是清楚)。只是将所有不能很好地解析为多行标量的东西都不是通用的解决方案。

除此之外,大多数YAML解析器都会丢弃一些有关文件读取的信息,您不希望通过重新缩进来丢失,包括EOL注释,手工制作的锚名称,映射键排序等等。违反了规范中的要求。

如果您想统一缩进(正确的)YAML,可以使用属于yaml包的[ruamel.yaml][2]实用程序(免责声明:我是该程序包的作者)。您与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 ...

不幸的是,在查找错误方面没有多大帮助,通过.travis.yml运行的正确yaml round-trip .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评论。它只是多行字符串的一部分。然而,将保留对第一行之前或之后的行的注释。

答案 1 :(得分:5)

错误意味着您的语法错误,而且这个特殊内容很难跟踪,因为它可能意味着多个内容,错误的缩进,包括缺少双引号,或者您需要确保双重引用某些特殊字符。

如果您在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发送代码,其工作方式与Travis WebLint类似。

实施例

以下语法不正确:

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

因为评论有错误的缩进:

  

[x]语法错误:():找不到预期的&#39; - &#39;解析第3行第3列的块集合时的指标

这是有效的语法:

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

上述问题尤其发生在Vim中编辑文件时,它正在进行注释缩进,使它们从头开始。