web-dev-qa-db-fra.com

Comment corriger l'erreur de syntaxe YAML: n'a pas trouvé l'indicateur '-' attendu lors de l'analyse d'un bloc?

J'ai du code écrit dans mon .travis.yml écrit pour une bibliothèque Python. En utilisant lint.travis-ci.org , j'ai appris qu'il y avait un problème d'indentation dans mon fichier YAML. Voici la partie vers laquelle l'erreur pointe

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

Où ai-je tort? L'erreur dit

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

Ce serait formidable s'il y avait un outil comme autopep8 pour corriger l'indentation des fichiers YAML.

17
Himanshu Mishra

Vous n'avez pas 32 lignes dans votre fichier (probablement parce que vous avez supprimé les données non essentielles de l'exemple), mais le niveau d'indentation pointe vers la ligne avec fi.

En fait, le problème commence plus tôt et ce que vous voulez faire est de spécifier l'action à entreprendre en tant que chaîne multiligne. Vous pouvez spécifier ceux dans YAML de plusieurs façons, mais le plus propre est d'utiliser l'indicateur scalaire littéral "| ", qui conserve les nouvelles lignes:

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

Il n'y a pas d'outil de ré-indentation YAML automatique pour ce type d'erreurs.

Réindentateurs pour Python prendre le code de travail et rendre l'indentation cohérente (en remplaçant les TAB, toujours le même retrait par niveau). Python réindentation du code sur le code avec des erreurs de syntaxe) , ne fonctionne pas ou peut produire des résultats incorrects.

Les réindenteurs pour YAML sont confrontés au même problème: que faire si l'entrée n'a pas de sens (et ce qui est clair pour vous et moi, n'est pas toujours clair pour un programme). Faire simplement tout ce qui n'est pas bien analysé dans un scalaire multiligne n'est pas une solution générique.

En dehors de cela, la plupart des analyseurs YAML jettent des informations sur la lecture dans les fichiers, que vous ne voudriez pas perdre en ré-indentant, y compris les commentaires EOL, les noms d'ancres fabriqués à la main, le mappage de l'ordre des clés, etc. Tout cela sans violer les exigences dans la spécification.

Si vous souhaitez indenter uniformément votre YAML (correct), vous pouvez utiliser l'utilitaire yaml qui fait partie de [ruamel.yaml][2] package (avertissement: je suis l'auteur de ce package). Votre saisie d'origine utilisée avec yaml round-trip .travis.yml donnerait:

 ...
  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 ...

Malheureusement pas beaucoup plus utile pour trouver l'erreur, le bon .travis.yml version exécutée yaml round-trip .travis.yml vous dira qu'il se stabilise au deuxième aller-retour (c'est-à-dire qu'au premier l'espace blanc supplémentaire est perdu). Et yaml round-trip .travis.yml --save vous donne:

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

Veuillez noter que dans ce # TO build networkx-metis n'est pas un commentaire YAML. Il fait juste partie de la chaîne multi-lignes. Un commentaire sur une ligne avant la première ou après la dernière serait cependant conservé.

7
Anthon

L'erreur signifie que vous avez une erreur de syntaxe et ce détail est difficile à suivre, car cela pourrait signifier plusieurs choses, une indentation incorrecte, y compris des guillemets manquants ou vous devez vous assurer de citer deux caractères spéciaux.

Si vous gardez une trace de votre .travis.yml dans le référentiel git, en utilisant la commande travis, vous pouvez facilement vérifier les versions précédentes et comparer.

Par exemple:

$ 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 vérifie 2 commits derrière, alors continuez à augmenter le nombre jusqu'à ce que ça marche, une fois trouvé, puis comparez comme:

git diff HEAD~2 .travis.yml

Sinon, séparez-les en petits morceaux ou continuez à retirer certaines sections jusqu'à ce que cela fonctionne.


Utiliser Ruby est un autre moyen de vérifier votre syntaxe YAML:

Ruby -e "require 'yaml';puts YAML.load_file('.travis.yml')"

vous n'avez donc pas besoin de POST votre code à chaque fois via travis qui fonctionne de la même manière que Travis WebLint .


Exemple

La syntaxe suivante est incorrecte:

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

car le commentaire a une indentation incorrecte selon:

Erreur de syntaxe [x]: (): n'a pas trouvé l'indicateur '-' attendu lors de l'analyse d'une collection de blocs à la ligne 3, colonne 3

Voici une syntaxe valide:

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

Le problème ci-dessus se produit en particulier lors de la modification de fichiers dans Vim, qui effectue l'indentation des commentaires en les faisant recommencer depuis le début.

5
kenorb