Support RCs with chocolatey package

This
- makes the `tools/*.ps1` generation more sane
- supports generating a package for RCs

Closes #2005.

--
Reviewed-on: https://github.com/bazelbuild/bazel/pull/2005
MOS_MIGRATED_REVID=138052483
diff --git a/scripts/packages/chocolatey/.gitignore b/scripts/packages/chocolatey/.gitignore
index 12bcf82..d7b988a 100644
--- a/scripts/packages/chocolatey/.gitignore
+++ b/scripts/packages/chocolatey/.gitignore
@@ -1,7 +1,6 @@
 *.nupkg
 *.zip
 bazel.nuspec
-chocolateyinstall.ps1
-chocolateyuninstall.ps1
 tools/*.exe
 tools/LICENSE.txt
+tools/params.json
diff --git a/scripts/packages/chocolatey/build.ps1 b/scripts/packages/chocolatey/build.ps1
index 9500e88..570af1b 100644
--- a/scripts/packages/chocolatey/build.ps1
+++ b/scripts/packages/chocolatey/build.ps1
@@ -1,29 +1,50 @@
 param(
   [string] $version = "0.3.2",
-  [switch] $isRelease
+  [int] $rc = 0,
+  [string] $mode = "local",
+  [string] $checksum = ""
 )
 
-$tvVersion = $version
-$tvFilename = "bazel-$($version)-windows-x86_64.zip"
-if ($isRelease) {
-  $tvUri = "https://github.com/bazelbuild/bazel/releases/download/$($version)/$($tvFilename)"
-} else {
+write-host "mode: $mode"
+if ($mode -eq "release") {
+  $tvVersion = $version
+  $tvFilename = "bazel-$($tvVersion)-windows-x86_64.zip"
+  $tvUri = "https://github.com/bazelbuild/bazel/releases/download/$($tvVersion)/$($tvFilename)"
+} elseif ($mode -eq "rc") {
+  $tvVersion = "$($version)-rc$($rc)"
+  $tvFilename = "bazel-$($version)rc$($rc)-windows-x86_64.zip"
+  $tvUri = "https://storage.googleapis.com/bazel/$($version)/rc$($rc)/$($tvFilename)"
+} elseif ($mode -eq "local") {
+  $tvVersion = $version
+  $tvFilename = "bazel-$($tvVersion)-windows-x86_64.zip"
   $tvUri = "http://localhost:8000/$($tvFilename)"
+} else {
+  throw "mode parameter '$mode' unsupported. Please use local, rc, or release."
 }
-write-host "download uri: $($tvUri)"
-
 rm -force -ErrorAction SilentlyContinue ./*.nupkg
-rm -force -ErrorAction SilentlyContinue ./*.zip
 rm -force -ErrorAction SilentlyContinue ./bazel.nuspec
-rm -force -ErrorAction SilentlyContinue ./tools/chocolateyinstall.ps1
-rm -force -ErrorAction SilentlyContinue ./tools/chocolateyuninstall.ps1
 rm -force -ErrorAction SilentlyContinue ./tools/LICENSE.txt
+rm -force -ErrorAction SilentlyContinue ./tools/params.json
+if ($checksum -eq "") {
+  rm -force -ErrorAction SilentlyContinue ./*.zip
+}
 
-if ($isRelease) {
+if ($mode -eq "release") {
   Invoke-WebRequest "$($tvUri).sha256" -UseBasicParsing -passthru -outfile sha256.txt
   $tvChecksum = (gc sha256.txt).split(' ')[0]
   rm sha256.txt
-} else {
+} elseif ($mode -eq "rc") {
+  if (-not(test-path $tvFilename)) {
+    Invoke-WebRequest "$($tvUri)" -UseBasicParsing -passthru -outfile $tvFilename
+  }
+  if ($checksum -eq "") {
+    write-host "calculating checksum"
+    $tvChecksum = (get-filehash $tvFilename -algorithm sha256).Hash
+  } else {
+    write-host "using passed checksum"
+    $tvChecksum = $checksum
+  }
+} elseif ($mode -eq "local") {
   Add-Type -A System.IO.Compression.FileSystem
   $outputDir = "$pwd/../../../output"
   $zipFile = "$pwd/$($tvFilename)"
@@ -36,18 +57,6 @@
 $nuspecExpanded = $ExecutionContext.InvokeCommand.ExpandString($nuspecTemplate)
 add-content -value $nuspecExpanded -path bazel.nuspec
 
-$installerScriptTemplate = get-content "chocolateyinstall.ps1.template" | out-string
-$installerScriptExpanded = $ExecutionContext.InvokeCommand.ExpandString($installerScriptTemplate)
-$installerScriptExpanded = $installerScriptExpanded -replace "ps_var_","$"
-$installerScriptExpanded = $installerScriptExpanded -replace "escape_char","``"
-add-content -value $installerScriptExpanded -path ./tools/chocolateyinstall.ps1
-
-$uninstallerScriptTemplate = get-content "chocolateyuninstall.ps1.template" | out-string
-$uninstallerScriptExpanded = $ExecutionContext.InvokeCommand.ExpandString($uninstallerScriptTemplate)
-$uninstallerScriptExpanded = $uninstallerScriptExpanded -replace "ps_var_","$"
-$uninstallerScriptExpanded = $uninstallerScriptExpanded -replace "escape_char","``"
-add-content -value $uninstallerScriptExpanded -path ./tools/chocolateyuninstall.ps1
-
 write-host "Copying LICENSE.txt from repo-root to tools directory"
 $licenseHeader = @"
 From: https://github.com/bazelbuild/bazel/blob/master/LICENSE.txt
@@ -56,4 +65,13 @@
 add-content -value $licenseHeader -path "./tools/LICENSE.txt"
 add-content -value (get-content "../../../LICENSE.txt") -path "./tools/LICENSE.txt"
 
+$params = @{
+  package = @{
+    uri = $tvUri;
+    checksum = $tvChecksum;
+    checksumType = "sha256";
+  }
+}
+add-content -value (ConvertTo-Json $params) -path "./tools/params.json"
+
 choco pack ./bazel.nuspec
diff --git a/scripts/packages/chocolatey/chocolateyinstall.ps1.template b/scripts/packages/chocolatey/chocolateyinstall.ps1.template
deleted file mode 100644
index 71813cc..0000000
--- a/scripts/packages/chocolatey/chocolateyinstall.ps1.template
+++ /dev/null
@@ -1,72 +0,0 @@
-ps_var_ErrorActionPreference = 'Stop'; # stop on all errors
-ps_var_packageName = 'bazel'
-ps_var_url = "$tvUri"
-ps_var_checksum = "$tvChecksum"
-ps_var_checksumType = 'sha256'
-ps_var_url64bit = ps_var_url
-ps_var_checksum64 = "$tvChecksum"
-ps_var_checksumType64 = ps_var_checksumType
-ps_var_toolsDir = Split-Path -parent ps_var_MyInvocation.MyCommand.Definition
-ps_var_packageDir = Split-Path -parent ps_var_toolsDir
-ps_var_binRoot = (Get-ToolsLocation) -replace "\\", "/"
-
-Install-ChocolateyZipPackage -PackageName "ps_var_packageName" escape_char
-  -Url "ps_var_url" escape_char
-  -Checksum "ps_var_checksum" escape_char
-  -ChecksumType "ps_var_checksumType" escape_char
-  -Url64bit "ps_var_url64bit" escape_char
-  -Checksum64 "ps_var_checksum64" escape_char
-  -Checksum64Type "ps_var_checksumType64" escape_char
-  -UnzipLocation "ps_var_packageDir"
-
-write-host "Ensure that msys2 dll is present in PATH to allow bazel to be run from non-msys2 shells"
-
-# stolen from docs: https://github.com/chocolatey/choco/wiki/How-To-Parse-PackageParameters-Argument
-ps_var_msys2Path = "c:\tools\msys64"
-if (ps_var_packageParameters)
-{
-  ps_var_match_pattern = "\/(?<option>([a-zA-Z]+)):(?<value>([escape_char"'])?([a-zA-Z0-9- _\\:\.]+)([escape_char"'])?)|\/(?<option>([a-zA-Z]+))"
-  ps_var_option_name = 'option'
-  ps_var_value_name = 'value'
-
-  if (ps_var_packageParameters -match ps_var_match_pattern)
-  {
-    ps_var_results = ps_var_packageParameters | Select-String ps_var_match_pattern -AllMatches
-    ps_var_results.matches | % {
-      ps_var_arguments.Add(
-        ps_var__.Groups[ps_var_option_name].Value.Trim(),
-        ps_var__.Groups[ps_var_value_name].Value.Trim())
-    }
-  }
-  else
-  {
-    Throw "Package Parameters were found but were invalid (REGEX Failure)"
-  }
-
-  if (ps_var_arguments.ContainsKey("msys2Path")) {
-    ps_var_msys2Path = ps_var_arguments["msys2Path"]
-    Write-Host "msys2Path Argument Found: ps_var_msys2Path"
-  }
-}
-Install-ChocolateyPath -PathToInstall "ps_var_msys2Path\usr\bin" -PathType "Machine"
-
-ps_var_addToMsysPath = (ps_var_packageDir -replace 'c:\\','/c/') -replace '\\','/'
-write-host @"
-bazel installed to ps_var_packageDir
-
-To use it in powershell or cmd, you should ensure your PATH environment variable contains
-  ps_var_(ps_var_msys2Path)\usr\bin
-BEFORE both
-  c:\windows\system32 (because bash-on-windows' bash.exe will be found here, if it's installed)
-  any references to msysgit (like c:\program files (x86)\git\bin or c:\program files (x86)\git\cmd) (because git's vendored version of msys2 will interfere with the real msys2)
-
-To use it in msys2, you should add that to your msys2 PATH:
-  export PATH=ps_var_(ps_var_addToMsysPath):escape_charps_var_PATH
-
-You also need, in your msys2 environment:
-  export JAVA_HOME="escape_charps_var_(ls -d C:/Program\ Files/Java/jdk* | sort | tail -n 1)escape_char"
-  export BAZEL_SH=c:/tools/msys64/usr/bin/bash.exe
-  export BAZEL_PYTHON=c:/tools/python2/python.exe
-
-See also https://bazel.build/docs/windows.html
-"@
diff --git a/scripts/packages/chocolatey/test.ps1 b/scripts/packages/chocolatey/test.ps1
index 91db5b7..febbc2f 100644
--- a/scripts/packages/chocolatey/test.ps1
+++ b/scripts/packages/chocolatey/test.ps1
@@ -1,23 +1,56 @@
 param(
-  [string] $version = "0.3.2"
+  [switch] $prerelease
 )
 
 choco uninstall bazel --force -y
-
-choco install bazel --verbose --debug --force -y -s ".;https://chocolatey.org/api/v2/"
+if ($prerelease) {
+  choco install bazel --verbose --debug --prerelease --force -y -s ".;https://chocolatey.org/api/v2/"
+} else {
+  choco install bazel --verbose --debug --force -y -s ".;https://chocolatey.org/api/v2/"
+}
 
 if ($LASTEXITCODE -ne 0)
 {
-  write-error "`$LASTEXITCODE was not zero. Inspect the output from choco install above."
+  write-error @"
+`$LASTEXITCODE was not zero.
+Inspect the output from choco install above.
+It should not have had errors.
+"@
+  exit 1
+}
+
+& bazel version
+if ($LASTEXITCODE -ne 0)
+{
+  write-error @"
+`$LASTEXITCODE was not zero.
+Inspect the output from ``bazel version`` above.
+It should have shown you bazel's version number.
+"@
+  exit 1
+}
+
+& bazel info
+if ($LASTEXITCODE -ne 0)
+{
+  write-error @"
+`$LASTEXITCODE was not zero.
+Inspect the output from ``bazel info`` above.
+It should have shown you bazel's information about the current workspace.
+"@
   exit 1
 }
 
 write-host @"
-The package should have installed without errors.
+This test just:
+* uninstalled bazel (if it was installed)
+* installed bazel from the package you built
+* asserted that the installation did not return an error exit code
+* ran ``bazel version`` and asserted non-error exit code
+* ran ``bazel info`` and asserted non-error exit code
 
-Now:
-* open a new shell (this should work in msys2, cmd, powershell)
-* Make sure your environment is accurate (see ``./tools/chocolateyinstall.ps1`` output)
-* run ``bazel version`` in that shell
-* ... and you should get a version number back
+The bazel commands should now be repeated in the other shells. Should work in:
+* powershell (probably what you just ran this in)
+* cmd
+* msys2
 "@
diff --git a/scripts/packages/chocolatey/tools/chocolateyinstall.ps1 b/scripts/packages/chocolatey/tools/chocolateyinstall.ps1
new file mode 100644
index 0000000..9afd433
--- /dev/null
+++ b/scripts/packages/chocolatey/tools/chocolateyinstall.ps1
@@ -0,0 +1,73 @@
+$ErrorActionPreference = 'Stop'; # stop on all errors
+$packageName = 'bazel'
+
+$toolsDir = Split-Path -parent $MyInvocation.MyCommand.Definition
+$p = ((gc "$toolsDir\params.json") -join "`n") | convertfrom-json
+
+$packageDir = Split-Path -parent $toolsDir
+$binRoot = (Get-ToolsLocation) -replace "\\", "/"
+
+write-host "Read params from json"
+write-host $p
+
+Install-ChocolateyZipPackage -PackageName "$packageName" `
+  -Url "$($p.package.uri)" `
+  -Checksum "$($p.package.checksum)" `
+  -ChecksumType "$($p.package.checksumType)" `
+  -Url64bit "$($p.package.uri)" `
+  -Checksum64 "$($p.package.checksum)" `
+  -Checksum64Type "$($p.package.checksumType)" `
+  -UnzipLocation "$packageDir"
+
+write-host "Ensure that msys2 dll is present in PATH to allow bazel to be run from non-msys2 shells"
+
+# from docs: https://github.com/chocolatey/choco/wiki/How-To-Parse-PackageParameters-Argument
+$msys2Path = "c:\tools\msys64"
+if ($packageParameters)
+{
+  $match_pattern = "\/(?<option>([a-zA-Z]+)):(?<value>([`"'])?([a-zA-Z0-9- _\\:\.]+)([`"'])?)|\/(?<option>([a-zA-Z]+))"
+  $option_name = 'option'
+  $value_name = 'value'
+
+  if ($packageParameters -match $match_pattern)
+  {
+    $results = $packageParameters | Select-String $match_pattern -AllMatches
+    $results.matches | % {
+      $arguments.Add(
+        $_.Groups[$option_name].Value.Trim(),
+        $_.Groups[$value_name].Value.Trim())
+    }
+  }
+  else
+  {
+    Throw "Package Parameters were found but were invalid (REGEX Failure)"
+  }
+
+  if ($arguments.ContainsKey("msys2Path")) {
+    $msys2Path = $arguments["msys2Path"]
+    Write-Host "msys2Path Argument Found: $msys2Path"
+  }
+}
+Install-ChocolateyPath -PathToInstall "$msys2Path\usr\bin" -PathType "Machine"
+
+$addToMsysPath = ($packageDir -replace 'c:\\','/c/') -replace '\\','/'
+write-host @"
+bazel installed to $packageDir
+
+To use it in powershell or cmd, you should ensure your PATH environment variable contains
+  $($msys2Path)\usr\bin
+BEFORE both
+  c:\windows\system32 (because bash-on-windows' bash.exe will be found here, if it's installed)
+  any references to msysgit (like c:\program files (x86)\git\bin or c:\program files (x86)\git\cmd) (because git's vendored version of msys2 will interfere with the real msys2)
+
+To use it in msys2, you should add that to your msys2 PATH:
+  export PATH=$($addToMsysPath):`$PATH
+
+You also need, in your msys2 environment (adjust paths for your system):
+  export JAVA_HOME="`$(ls -d C:/Program\ Files/Java/jdk* | sort | tail -n 1)`"
+  export BAZEL_SH=c:/tools/msys64/usr/bin/bash.exe
+  export BAZEL_PYTHON=c:/tools/python2/python.exe
+
+See also https://bazel.build/docs/windows.html
+"@
+
diff --git a/scripts/packages/chocolatey/chocolateyuninstall.ps1.template b/scripts/packages/chocolatey/tools/chocolateyuninstall.ps1
similarity index 100%
rename from scripts/packages/chocolatey/chocolateyuninstall.ps1.template
rename to scripts/packages/chocolatey/tools/chocolateyuninstall.ps1
diff --git a/site/versions/master/docs/windows-chocolatey-maintenance.md b/site/versions/master/docs/windows-chocolatey-maintenance.md
index da3db69..90c9200 100644
--- a/site/versions/master/docs/windows-chocolatey-maintenance.md
+++ b/site/versions/master/docs/windows-chocolatey-maintenance.md
@@ -34,39 +34,39 @@
 
 ```powershell
 pushd scripts/packages/chocolatey
-  ./build.ps1 -version 0.3.1 -isRelease
+  ./build.ps1 -version 0.3.2 -mode local
 popd
 ```
 
 Should result in `scripts/packages/chocolatey/bazel.<version>.nupkg` being created.
 
+The `build.ps1` script supports `mode` values `local`, `rc` and `release`.
+
 #### Test
 
-0. Build the package (without `isRelease`)
+0. Build the package (with `-mode local`)
   * run a webserver (`python -m SimpleHTTPServer` in `scripts/packages/chocolatey` is convenient and starts one on `http://localhost:8000`)
-  * adjust `chocolateyinstall.ps1` so that the `$url` and `$url64` parameters point to `http://localhost:8000/bazel_0.3.1_windows_x86_64.zip`
 0. Test the install
 
     The `test.ps1` should install the package cleanly (and error if it did not install cleanly), then tell you what to do next.
 
-    In a new (msys2) shell
-    ```sh
-    bazel version
-    ```
-    should result in that version, with executable from PATH.
-
 0. Test the uninstall
 
     ```sh
     choco uninstall bazel
-    # should remove bazel from the system - c:/tools/bazel should be deleted
+    # should remove bazel from the system
     ```
 
-Chocolatey's moderation process automates checks here.
+Chocolatey's moderation process automates checks here as well.
 
-### Publish
+### Release
 
-```sh
+Modify `tools/parameters.json` for the new release's URI and checksum once the release has been published to github releases.
+
+```powershell
+./build.ps1 -version <version> -isRelease
+./test.ps1 -version <version>
+# if the test.ps1 passes
 choco push bazel.x.y.z.nupkg --source https://chocolatey.org/
 ```