$Date: 2018-07-07 06:49:13 +0900 (2018/07/07 (土)) $
$Revision: 1347 $
nuget.exe の最大パス長の制限を回避するためのワークアラウンド
前提
Pipeline Multibranch Plugin
は、ワークスペースのパスとして非常に長いパスを使用します。
しかし nuget.exe は扱うことができるパス名に制限があります。
NuGet and long file name support #3324
このページではこの制限を回避する方法を説明します。
ワークアラウンドの概念
-
一時的なジャンクションで使用するユニークなパス名を作ります。
- 一時的なジャンクションのパス長は十分短くします。
- 少なくとも一時的なジャンクションのパスはジャンクションの作成から削除までの間ユニークである必要があります。
- ただ、ジャンクションの削除後も一意なパスを選ぶほうがいいです。
-
非常に長いディレクトリに対して一時的で一意なジャンクションを作ります。
-
ジャンクションのディレクトリに移動します。
-
'nuget.exe restore' をサブディレクトリに対して再帰的に実行します。
-
もともとのディレクトリに移動します。
-
一時的なジャンクションを削除します。
ジャンクションの作り方
'mklink /j' コマンドでジャンクションを作成します。
構文
mklink /j <新しいジャンクションのパス> <作成元のディレクトリのパス>
例
mklink /j C:\Windows\Temp\new-junction C:\Jenkins\workspace\sample-cmake-profile_master-IUZBDGO3W5L2BPWGQVT2S7PEJHL5ZITG5TGSZPXMOTZ4IVLY35GQ
ジャンクションの削除方法
rmdir コマンドでジャンクションを削除します。
例
rmdir C:\Windows\Temp\new-junction
制限を回避するためのバッチファイル
ダウンロード
ダウンロードしたあと、拡張子を txt から bat に変えてください。
サンプルバッチフアイル (restore-all.txt)
バッチフアイル
@rem This is a batch file to maneuver the limitaion of the max path length which nuget.exe can handle.
@rem
@rem It is designed to use in a Jenkins Job because it relies on BUILD_TAG variable.
@rem If you want to use this outside of Jenkins, you need to choose an alternative unique id.
@rem
@rem 1. Create an unique path name for the next step.
@rem 2. Create a unique and temporary junction for very long path directory.
@rem (The path length of the temporary junction must be short enough.)
@rem 3. move to the directory of the junction.
@rem 4. remove all packages directories recursively. (not mandatory)
@rem 5. run 'nuget.exe restore' for all solution files recursively.
@rem 6. move to the original directory.
@rem 7. remove the temporary junction.
@echo off
set RET=1
@rem You may want to change the path of nuget.exe
set NUGET_PATH=C:\Program Files (x86)\NuGet\nuget.exe
@rem check environment variable of Jenkins
if "%BUILD_TAG%" == "" (
echo BUILD_TAG is empty
exit /b 1
)
@rem the parent directory of a temporary junction
@rem you may want to tweak this.
set WA_ROOT=C:\Windows\Temp
@rem path to temporary junction
@rem change this path if you need to.
@rem
@rem BUILD_TAG and EXECUTOR_NUMBER are defined by Jenkins.
@rem see https://wiki.jenkins.io/display/JENKINS/Building+a+software+project
@rem
set WA_TARGET=%WA_ROOT%\%BUILD_TAG%-%EXECUTOR_NUMBER%
@rem save current directory
set CURRENT=%CD%
@rem workspace directory which is the target directory of the junction
set WA_SOURCE=%CURRENT%
@rem create a temporary junction
@rem This is the first core of this workaround.
echo mklink /j "%WA_TARGET%" "%WA_SOURCE%"
mklink /j "%WA_TARGET%" "%WA_SOURCE%" || goto END
@rem move to the junction directory to avoid the limitation of nuget.exe.
@rem This is the second core of this workaround.
cd /d %WA_TARGET% || goto END
@rem this is optional.
@rem If you don't need to remove packages directory in advance, disable or remove this.
for /r %%i in (packages) do (
if exist %%i (
echo rmdir /s /q %%i
rmdir /s /q %%i
)
)
@rem run 'nuget.exe restore' recursively.
for /r %%i in (*.sln) do (
if exist %%i (
echo "%NUGET_PATH%" restore %%i
"%NUGET_PATH%" restore %%i || goto END
)
)
@rem set return code
set RET=0
:END
@rem get back to the original directory.
cd /d %CURRENT%
@rem remove the temporary junction
echo rmdir %WA_TARGET%
rmdir %WA_TARGET%
@rem return result
exit /b %RET%