Yaml 如何在appveyor.yml中将命令拆分为多行
我想在我的Yaml 如何在appveyor.yml中将命令拆分为多行,yaml,appveyor,Yaml,Appveyor,我想在我的appveyor.yml文件中跨多行拆分一个长的构建命令,但是我无法将其展开,因此当第一个FOR命令被切断并返回错误时,构建失败。我不知道如何正确分割.yml文件中的行,以便在Appveyor中重新组装。如何做到这一点 以下是一个简化版本: build_script: - cmd: >- @echo off FOR %%P IN (x86,x64) DO ( ^ FOR %%C IN (Debug,Release) DO ( ^ msb
appveyor.yml
文件中跨多行拆分一个长的构建命令,但是我无法将其展开,因此当第一个FOR
命令被切断并返回错误时,构建失败。我不知道如何正确分割.yml
文件中的行,以便在Appveyor中重新组装。如何做到这一点
以下是一个简化版本:
build_script:
- cmd: >-
@echo off
FOR %%P IN (x86,x64) DO ( ^
FOR %%C IN (Debug,Release) DO ( ^
msbuild ^
/p:Configuration=%%C ^
/p:Platform=%%P ... ^
|| EXIT 1 ^
) ^
)
我希望它在AppVeyor中显示为:
@echo off
FOR %%P IN (x86,x64) DO ( FOR %%C IN (Debug,Release) DO ( msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 ) )
额外的空格并不重要,重要的一点是以开头的一行直到最后一行出现在同一行
请注意,从理论上讲,验船师也可以看到:
@echo off
FOR %%P IN (x86,x64) DO ( ^
FOR %%C IN (Debug,Release) DO ( ^
msbuild ^
/p:Configuration=%%C ^
/p:Platform=%%P ... ^
|| EXIT 1 ^
) ^
)
由于Windowscmd.exe
解释器随后会在每行末尾看到延续标记(^
),并将它们视为一个大的长命令,除了Appveyor似乎无法识别^
标记,因此它会将每行发送到cmd.exe
,一次发送一个,而不是将整个多行块一起发送
这意味着第一个选项看起来像是唯一可行的解决方案,其中YAML的构造使得
行的及其后的所有内容组合成一行
我试过:
- 单行间距,每行末尾无额外字符。根据,单间距的YML线应该展开为一条线,但Appveyor不会这样做
- 双倍行距的行,每行末尾没有额外字符。这应该使每一行都成为一个单独的命令,事实上,它们是这样的,因为第一个
命令失败,出现FOR
,因为它不完整(只有错误255
行存在,而不是循环的其余部分。)FOR
- 以
结尾的双倍行距线。Appveyor一次只运行一行,因此我在第一个不完整的^
命令中得到了一个FOR
错误255
- 如上所示,以
结尾的单间隔行。与双倍行距的行相同,^
来自不完整的错误255
命令FOR
- 在运行单独的命令(例如,多个
语句)时,用msbuild
结束每一行实际上是可行的,但这不适用于&&^
循环,因为如果前面没有命令,则不能使用FOR
&
在
appveyor.yml
中,是否有将单个cmd
命令拆分为多行的技巧?如果您知道appveyor期望的是什么(我不知道),让我们假设:
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO ( msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 )
)
然后,通过转储YAML(例如从Python中转储),可以轻松生成适当的YAML:
import sys
import ruamel.yaml
appveyor_str = """\
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO ( msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 )
)
"""
data = dict(build_script=[dict(cmd=appveyor_str)])
ruamel.yaml.round_trip_dump(data, sys.stdout)
给你:
build_script:
- cmd: "@echo off\nFOR %%P IN (x86,x64) DO (\n FOR %%C IN (Debug,Release) DO (\
\ msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 )\n)\n"
(在上述示例中,任何换行符前都没有空格)
使用(带
)时,您几乎无法控制标量的折叠。也不可能在折叠(或文字)块样式标量中转义序列
如果您的多行字符串不需要转义,您可以尝试作为块样式标量转储:
import sys
import ruamel.yaml
appveyor_str = """\
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO ( msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 )
)
"""
data = dict(build_script=[dict(cmd=ruamel.yaml.scalarstring.PreservedScalarString(appveyor_str))])
ruamel.yaml.round_trip_dump(data, sys.stdout)
其中:
build_script:
- cmd: |
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO ( msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 )
)
(即,确切地说,你放进了什么)
如果您将所有内容右对齐(其可读性不如您所希望的那样),并在第一次输出后使用双换行符,则您将获得所需的输出:
import sys
import ruamel.yaml
yaml_str = """\
build_script:
- cmd: >-
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO (
msbuild
/p:Configuration=%%C
/p:Platform=%%P ...
|| EXIT 1
)
)
"""
data = ruamel.yaml.load(yaml_str)
print(data['build_script'][0]['cmd'])
给出:
@echo off
FOR %%P IN (x86,x64) DO ( FOR %%C IN (Debug,Release) DO ( msbuild /p:Configuration=%%C /p:Platform=%%P ... || EXIT 1 ) )
但不能缩进(从折叠块样式标量的细节):
以空白字符开头的行(更多缩进行)不会折叠
CMD
命令总是分成单独的行,并通过包装到.CMD
文件中逐个运行。将您的代码放入build.cmd
,提交到repo,然后调用为:
build_script:
- build.cmd
如何在appveyor.yml中将命令拆分为多行
下面是batch、cmd、ps的一些语法示例
我希望这些例子能为您节省一些时间
语法示例
批量
# please note the & at EOL in the next example
install:
# Install VULKAN_SDK
- if not exist %VULKAN_SDK% (
curl -L --silent --show-error --output Vulkan_SDK_Installer.exe https://sdk.lunarg.com/sdk/download/%VULKAN_VERSION%/windows/VulkanSDK-%VULKAN_VERSION%-Installer.exe?Human=true &
Vulkan_SDK_Installer.exe /S
)
- dir %VULKAN_SDK%
before_build:
- |-
set MINGW32_ARCH=i686-w64-mingw32
- if exist %PREFIX% set NEEDDEPENDS=rem
# Depends
- |-
%NEEDDEPENDS% mkdir %PREFIX%\include\SDL2
%NEEDDEPENDS% mkdir %PREFIX%\lib
%NEEDDEPENDS% cd %TEMP%
%NEEDDEPENDS% appveyor DownloadFile https://sourceforge.net/projects/gnuwin32/files/gettext/0.14.4/gettext-0.14.4-lib.zip
%NEEDDEPENDS% mkdir gettext-0.14.4-lib
%NEEDDEPENDS% move gettext-0.14.4-lib.zip gettext-0.14.4-lib
%NEEDDEPENDS% cd gettext-0.14.4-lib
%NEEDDEPENDS% 7z x gettext-0.14.4-lib.zip > nul
%NEEDDEPENDS% copy include\* %PREFIX%\include > nul
%NEEDDEPENDS% copy lib\* %PREFIX%\lib > nul
%NEEDDEPENDS% cd ..
CMD
before_build:
- cmd: >-
mkdir build
cd .\build
set OpenBLAS_HOME=%APPVEYOR_BUILD_FOLDER%/%MXNET_OPENBLAS_DIR%
set OpenCV_DIR=%APPVEYOR_BUILD_FOLDER%/%MXNET_OPENCV_DIR%/build
cmake .. -DOPENCV_DIR=%OpenCV_DIR% -DUSE_CUDA=0 -DUSE_CUDNN=0 -DUSE_NVRTC=0 -DUSE_OPENCV=1 -DUSE_OPENMP=1 -DUSE_BLAS=open -DUSE_DIST_KVSTORE=0 -G "Visual Studio 12 2013 Win64"
PS
install:
- ps: >-
git submodule init
git submodule update
if (!(Test-Path ${env:MXNET_OPENBLAS_FILE})) {
echo "Downloading openblas from ${env:MXNET_OPENBLAS_PKG} ..."
appveyor DownloadFile "${env:MXNET_OPENBLAS_PKG}" -FileName ${env:MXNET_OPENBLAS_FILE} -Timeout 1200000
}
使用双引号:
build_script:
- cmd: "
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO (
msbuild
/p:Configuration=%%C
/p:Platform=%%P ...
|| EXIT 1
)
)"
您可以更精确地检查yaml ref
我使用appveyor遇到了同样的问题(多么奇怪的限制!)。使用双引号使我能够利用YAML微妙之处:
- 在我这边保持一个易于阅读/书写的多行表达式
- 按应用程序有效存储单行值
对于其他读者,请注意,行将被折叠,因此,需要使用特殊语法来编写,以支持。。。在OP所给出的表达式中,您不能省略<代码> >代码> .< /P> < P>,有另一个提示要考虑其他批处理和PS。MysS2/MINW32/MINW64安装在AppVEYOR VMs>代码>:\Mys64 \ Ur\bin \Bash < /C>,除了“WINDOWS”版本的MINW64。< /P> 不幸的是,让bash中的多行命令在appveyor中工作并不是那么简单: 例如: 下面是一段代码:
cd/tmp
对于$中的服务器(grep'^server'/etc/pacman.d/mirrorlist.msys | awk'{print$3}'| shuf | arch=x86_64 envsubst);做
回显尝试${server}
curl--连接超时10-LO${server}msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz&&break
完成”
变成
->-
C:\msys64\usr\bin\bash-lc”
cd/tmp;
对于$中的服务器(grep$'\x5eServer'/etc/pacman.d/mirrorlist.msys | awk'{print$3}'| shuf | arch=x86_64/usr/bin/envsubst);做
:; 回显尝试${server};
:; curl——连接超时10-LO${server}msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz&&break;
完成”
为什么会如此不同?
appveyor中批处理多行bash字符串时会出现许多问题:
^
.Ho结尾
install:
- ps: |
Add-Type -AssemblyName System.IO.Compression.FileSystem
if (!(Test-Path -Path "C:\maven" )) {
(new-object System.Net.WebClient).DownloadFile('https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip', 'C:\maven-bin.zip')
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:\maven-bin.zip", "C:\maven")
}
on_success:
- ps: |
if ($true)
{
Write-Host "Success"
}
build_script:
- cmd: "
@echo off
FOR %%P IN (x86,x64) DO (
FOR %%C IN (Debug,Release) DO (
msbuild
/p:Configuration=%%C
/p:Platform=%%P ...
|| EXIT 1
)
)"
# This is really using /mingw64/bin/envsubst in MINGW64 mode
bash -c "for x in $(echo $'${PWD}\n${OLDPWD}' | envsubst); do
:; echo ""${x}"" | xxd;
done"
# Either need to have MSYSTEM set to MSYS, or
bash -c "for x in $(echo $'${PWD}\n${OLDPWD}' | /usr/bin/envsubst); do
:; echo ""${x}"" | xxd;
done"
# or, as a last resort, use dos2unix
bash -c "for x in $(echo $'${PWD}\n${OLDPWD}' | envsubst | dos2unix); do
:; echo ""${x}"" | xxd;
done"