github.com/xeptore/docker-cli@v20.10.14+incompatible/scripts/make.ps1 (about)

     1  <#
     2  .NOTES
     3      Summary: Windows native build script.
     4  
     5               It does however provided the minimum necessary to support parts of local Windows
     6               development and Windows to Windows CI.
     7  
     8               Usage Examples (run from repo root):
     9                  "scripts/make.ps1 -Client" to build docker.exe client 64-bit binary (remote repo)
    10                  "scripts/make.ps1 -TestUnit" to run unit tests
    11                  "scripts/make.ps1 -Daemon -TestUnit" to build the daemon and run unit tests
    12                  "scripts/make.ps1 -All" to run everything this script knows about that can run in a container
    13                  "scripts/make.ps1" to build the daemon binary (same as -Daemon)
    14                  "scripts/make.ps1 -Binary" shortcut to -Client and -Daemon
    15  
    16  .PARAMETER Binary
    17       Builds the client and daemon binaries. A convenient shortcut to `make.ps1 -Client -Daemon`.
    18  
    19  .PARAMETER Race
    20       Use -race in go build and go test.
    21  
    22  .PARAMETER Noisy
    23       Use -v in go build.
    24  
    25  .PARAMETER ForceBuildAll
    26       Use -a in go build.
    27  
    28  .PARAMETER NoOpt
    29       Use -gcflags -N -l in go build to disable optimisation (can aide debugging).
    30  
    31  .PARAMETER CommitSuffix
    32       Adds a custom string to be appended to the commit ID (spaces are stripped).
    33  
    34  .PARAMETER TestUnit
    35       Runs unit tests.
    36  
    37  .PARAMETER All
    38       Runs everything this script knows about that can run in a container.
    39  
    40  
    41  TODO
    42  - Unify the head commit
    43  - Add golint and other checks (swagger maybe?)
    44  
    45  #>
    46  
    47  
    48  param(
    49      [Parameter(Mandatory=$False)][switch]$Binary,
    50      [Parameter(Mandatory=$False)][switch]$Race,
    51      [Parameter(Mandatory=$False)][switch]$Noisy,
    52      [Parameter(Mandatory=$False)][switch]$ForceBuildAll,
    53      [Parameter(Mandatory=$False)][switch]$NoOpt,
    54      [Parameter(Mandatory=$False)][string]$CommitSuffix,
    55      [Parameter(Mandatory=$False)][switch]$TestUnit,
    56      [Parameter(Mandatory=$False)][switch]$All
    57  )
    58  
    59  $ErrorActionPreference = "Stop"
    60  $ProgressPreference = "SilentlyContinue"
    61  $pushed=$False  # To restore the directory if we have temporarily pushed to one.
    62  
    63  # Utility function to get the commit ID of the repository
    64  Function Get-GitCommit() {
    65      if (-not (Test-Path ".\.git")) {
    66          # If we don't have a .git directory, but we do have the environment
    67          # variable DOCKER_GITCOMMIT set, that can override it.
    68          if ($env:DOCKER_GITCOMMIT.Length -eq 0) {
    69              Throw ".git directory missing and DOCKER_GITCOMMIT environment variable not specified."
    70          }
    71          Write-Host "INFO: Git commit ($env:DOCKER_GITCOMMIT) assumed from DOCKER_GITCOMMIT environment variable"
    72          return $env:DOCKER_GITCOMMIT
    73      }
    74      $gitCommit=$(git rev-parse --short HEAD)
    75      if ($(git status --porcelain --untracked-files=no).Length -ne 0) {
    76          $gitCommit="$gitCommit-unsupported"
    77          Write-Host ""
    78          Write-Warning "This version is unsupported because there are uncommitted file(s)."
    79          Write-Warning "Either commit these changes, or add them to .gitignore."
    80          git status --porcelain --untracked-files=no | Write-Warning
    81          Write-Host ""
    82      }
    83      return $gitCommit
    84  }
    85  
    86  # Build a binary (client or daemon)
    87  Function Execute-Build($additionalBuildTags, $directory) {
    88      # Generate the build flags
    89      $buildTags = "autogen"
    90      if ($Noisy)                     { $verboseParm=" -v" }
    91      if ($Race)                      { Write-Warning "Using race detector"; $raceParm=" -race"}
    92      if ($ForceBuildAll)             { $allParm=" -a" }
    93      if ($NoOpt)                     { $optParm=" -gcflags "+""""+"-N -l"+"""" }
    94      if ($additionalBuildTags -ne "") { $buildTags += $(" " + $additionalBuildTags) }
    95  
    96  
    97      # Get the git commit. This will also verify if we are in a repo or not. Then add a custom string if supplied.
    98      $gitCommit=Get-GitCommit
    99      if ($CommitSuffix -ne "") { $gitCommit += "-"+$CommitSuffix -Replace ' ', '' }
   100      if (Test-Path Env:\DOCKER_GITCOMMIT) {$gitCommit=$env:DOCKER_GITCOMMIT}
   101  
   102      # Get the version of docker (eg 17.04.0-dev)
   103      $dockerVersion="0.0.0-dev"
   104      if (Test-Path Env:\VERSION) {$dockerVersion=$env:VERSION}
   105  
   106      # Do the go build in the appropriate directory
   107      # Note -linkmode=internal is required to be able to debug on Windows.
   108      # https://github.com/golang/go/issues/14319#issuecomment-189576638
   109      Write-Host "INFO: Building..."
   110  
   111      $buildTime=$(Get-Date).ToUniversalTime()
   112      $env:LDFLAGS="-linkmode=internal `
   113        -X \""github.com/docker/cli/cli/version.Version=$dockerVersion\"" `
   114        -X \""github.com/docker/cli/cli/version.GitCommit=$gitCommit\"" `
   115        -X \""github.com/docker/cli/cli/version.BuildTime=$buildTime\"""
   116      if ($env:PLATFORM) {
   117        $env:LDFLAGS="$env:LDFLAGS -X \""github.com/docker/cli/cli/version.PlatformName=$env:PLATFORM\"""
   118      }
   119  
   120      # Generate a version in the form major,minor,patch,build
   121      $versionQuad=$dockerVersion -replace "[^0-9.]*" -replace "\.", ","
   122  
   123      # If you really want to understand this madness below, search the Internet for powershell variables after verbatim arguments... Needed to get double-quotes passed through to the compiler options.
   124      # Generate the .syso files containing all the resources and manifest needed to compile the final docker binaries. Both 32 and 64-bit clients.
   125      $env:_ag_dockerVersion=$dockerVersion
   126      $env:_ag_gitCommit=$gitCommit
   127  
   128      New-Item -ItemType Directory -Path .\tmp -Force | Out-Null
   129      windres -i scripts/winresources/docker.rc -o cli/winresources/rsrc_amd64.syso  -F pe-x86-64 --use-temp-file -I ./tmp -D DOCKER_VERSION_QUAD=$versionQuad --% -D DOCKER_VERSION=\"%_ag_dockerVersion%\" -D DOCKER_COMMIT=\"%_ag_gitCommit%\"
   130      if ($LASTEXITCODE -ne 0) { Throw "Failed to compile client 64-bit resources" }
   131  
   132      windres -i scripts/winresources/docker.rc -o cli/winresources/rsrc_386.syso    -F pe-i386   --use-temp-file -I ./tmp -D DOCKER_VERSION_QUAD=$versionQuad --% -D DOCKER_VERSION=\"%_ag_dockerVersion%\" -D DOCKER_COMMIT=\"%_ag_gitCommit%\"
   133      if ($LASTEXITCODE -ne 0) { Throw "Failed to compile client 32-bit resources" }
   134      Remove-Item .\tmp -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
   135  
   136      Push-Location $root\cmd\$directory; $global:pushed=$True
   137  
   138      # By using --% we can use \"key=%foo%\" and have a environment variable foo that contains spaces
   139      go build $raceParm $verboseParm $allParm $optParm -tags "$buildTags" `
   140        -o "$root\build\$directory.exe" `
   141        -ldflags --% "%LDFLAGS%"
   142  
   143      if ($LASTEXITCODE -ne 0) { Throw "Failed to compile" }
   144      Pop-Location; $global:pushed=$False
   145  }
   146  
   147  # Run the unit tests
   148  Function Run-UnitTests() {
   149      Write-Host "INFO: Running unit tests..."
   150      $testPath="./..."
   151      $goListCommand = "go list -e -f '{{if ne .Name """ + '\"github.com/docker/cli\"' + """}}{{.ImportPath}}{{end}}' $testPath"
   152      $pkgList = $(Invoke-Expression $goListCommand)
   153      if ($LASTEXITCODE -ne 0) { Throw "go list for unit tests failed" }
   154      $pkgList = $pkgList | Select-String -Pattern "github.com/docker/cli"
   155      $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/cli/vendor"
   156      $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/cli/man"
   157      $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/cli/e2e"
   158      $pkgList = $pkgList -replace "`r`n", " "
   159      $goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen" + """ -a """ + "-test.timeout=10m" + """ $pkgList"
   160      Invoke-Expression $goTestCommand
   161      if ($LASTEXITCODE -ne 0) { Throw "Unit tests failed" }
   162  }
   163  
   164  # Start of main code.
   165  Try {
   166      Write-Host -ForegroundColor Cyan "INFO: make.ps1 starting at $(Get-Date)"
   167  
   168      # Get to the root of the repo
   169      $root = $(Split-Path $MyInvocation.MyCommand.Definition -Parent | Split-Path -Parent)
   170      Push-Location $root
   171  
   172      # Handle the "-All" shortcut to turn on all things we can handle.
   173      # Note we expressly only include the items which can run in a container - the validations tests cannot
   174      # as they require the .git directory which is excluded from the image by .dockerignore
   175      if ($All) { $Client=$True; $TestUnit=$True }
   176  
   177      # Handle the "-Binary" shortcut to build both client and daemon.
   178      if ($Binary) { $Client = $True; }
   179  
   180      # Verify git is installed
   181      if ($(Get-Command git -ErrorAction SilentlyContinue) -eq $nil) { Throw "Git does not appear to be installed" }
   182  
   183      # Verify go is installed
   184      if ($(Get-Command go -ErrorAction SilentlyContinue) -eq $nil) { Throw "GoLang does not appear to be installed" }
   185  
   186      # Build the binaries
   187      if ($Client) {
   188          # Create the build directory if it doesn't exist
   189          if (-not (Test-Path ".\build")) { New-Item ".\build" -ItemType Directory | Out-Null }
   190  
   191          # Perform the actual build
   192          Execute-Build "" "docker"
   193      }
   194  
   195      # Run unit tests
   196      if ($TestUnit) { Run-UnitTests }
   197  
   198      # Gratuitous ASCII art.
   199      if ($Client) {
   200          Write-Host
   201          Write-Host -ForegroundColor Green " ________   ____  __."
   202          Write-Host -ForegroundColor Green " \_____  \ `|    `|/ _`|"
   203          Write-Host -ForegroundColor Green " /   `|   \`|      `<"
   204          Write-Host -ForegroundColor Green " /    `|    \    `|  \"
   205          Write-Host -ForegroundColor Green " \_______  /____`|__ \"
   206          Write-Host -ForegroundColor Green "         \/        \/"
   207          Write-Host
   208      }
   209  }
   210  Catch [Exception] {
   211      Write-Host -ForegroundColor Red ("`nERROR: make.ps1 failed:`n$_")
   212  
   213      # More gratuitous ASCII art.
   214      Write-Host
   215      Write-Host -ForegroundColor Red  "___________      .__.__             .___"
   216      Write-Host -ForegroundColor Red  "\_   _____/____  `|__`|  `|   ____   __`| _/"
   217      Write-Host -ForegroundColor Red  " `|    __) \__  \ `|  `|  `| _/ __ \ / __ `| "
   218      Write-Host -ForegroundColor Red  " `|     \   / __ \`|  `|  `|_\  ___// /_/ `| "
   219      Write-Host -ForegroundColor Red  " \___  /  (____  /__`|____/\___  `>____ `| "
   220      Write-Host -ForegroundColor Red  "     \/        \/             \/     \/ "
   221      Write-Host
   222  
   223      Throw $_
   224  }
   225  Finally {
   226      Pop-Location # As we pushed to the root of the repo as the very first thing
   227      if ($global:pushed) { Pop-Location }
   228      Write-Host -ForegroundColor Cyan "INFO: make.ps1 ended at $(Get-Date)"
   229  }