File: make.ps1

package info (click to toggle)
docker.io 20.10.24%2Bdfsg1-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-proposed-updates
  • size: 60,824 kB
  • sloc: sh: 5,621; makefile: 593; ansic: 179; python: 162; asm: 7
file content (229 lines) | stat: -rw-r--r-- 10,127 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<#
.NOTES
    Summary: Windows native build script.

             It does however provided the minimum necessary to support parts of local Windows
             development and Windows to Windows CI.

             Usage Examples (run from repo root):
                "scripts/make.ps1 -Client" to build docker.exe client 64-bit binary (remote repo)
                "scripts/make.ps1 -TestUnit" to run unit tests
                "scripts/make.ps1 -Daemon -TestUnit" to build the daemon and run unit tests
                "scripts/make.ps1 -All" to run everything this script knows about that can run in a container
                "scripts/make.ps1" to build the daemon binary (same as -Daemon)
                "scripts/make.ps1 -Binary" shortcut to -Client and -Daemon

.PARAMETER Binary
     Builds the client and daemon binaries. A convenient shortcut to `make.ps1 -Client -Daemon`.

.PARAMETER Race
     Use -race in go build and go test.

.PARAMETER Noisy
     Use -v in go build.

.PARAMETER ForceBuildAll
     Use -a in go build.

.PARAMETER NoOpt
     Use -gcflags -N -l in go build to disable optimisation (can aide debugging).

.PARAMETER CommitSuffix
     Adds a custom string to be appended to the commit ID (spaces are stripped).

.PARAMETER TestUnit
     Runs unit tests.

.PARAMETER All
     Runs everything this script knows about that can run in a container.


TODO
- Unify the head commit
- Add golint and other checks (swagger maybe?)

#>


param(
    [Parameter(Mandatory=$False)][switch]$Binary,
    [Parameter(Mandatory=$False)][switch]$Race,
    [Parameter(Mandatory=$False)][switch]$Noisy,
    [Parameter(Mandatory=$False)][switch]$ForceBuildAll,
    [Parameter(Mandatory=$False)][switch]$NoOpt,
    [Parameter(Mandatory=$False)][string]$CommitSuffix,
    [Parameter(Mandatory=$False)][switch]$TestUnit,
    [Parameter(Mandatory=$False)][switch]$All
)

$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
$pushed=$False  # To restore the directory if we have temporarily pushed to one.

# Utility function to get the commit ID of the repository
Function Get-GitCommit() {
    if (-not (Test-Path ".\.git")) {
        # If we don't have a .git directory, but we do have the environment
        # variable DOCKER_GITCOMMIT set, that can override it.
        if ($env:DOCKER_GITCOMMIT.Length -eq 0) {
            Throw ".git directory missing and DOCKER_GITCOMMIT environment variable not specified."
        }
        Write-Host "INFO: Git commit ($env:DOCKER_GITCOMMIT) assumed from DOCKER_GITCOMMIT environment variable"
        return $env:DOCKER_GITCOMMIT
    }
    $gitCommit=$(git rev-parse --short HEAD)
    if ($(git status --porcelain --untracked-files=no).Length -ne 0) {
        $gitCommit="$gitCommit-unsupported"
        Write-Host ""
        Write-Warning "This version is unsupported because there are uncommitted file(s)."
        Write-Warning "Either commit these changes, or add them to .gitignore."
        git status --porcelain --untracked-files=no | Write-Warning
        Write-Host ""
    }
    return $gitCommit
}

# Build a binary (client or daemon)
Function Execute-Build($additionalBuildTags, $directory) {
    # Generate the build flags
    $buildTags = "autogen"
    if ($Noisy)                     { $verboseParm=" -v" }
    if ($Race)                      { Write-Warning "Using race detector"; $raceParm=" -race"}
    if ($ForceBuildAll)             { $allParm=" -a" }
    if ($NoOpt)                     { $optParm=" -gcflags "+""""+"-N -l"+"""" }
    if ($additionalBuildTags -ne "") { $buildTags += $(" " + $additionalBuildTags) }


    # Get the git commit. This will also verify if we are in a repo or not. Then add a custom string if supplied.
    $gitCommit=Get-GitCommit
    if ($CommitSuffix -ne "") { $gitCommit += "-"+$CommitSuffix -Replace ' ', '' }
    if (Test-Path Env:\DOCKER_GITCOMMIT) {$gitCommit=$env:DOCKER_GITCOMMIT}

    # Get the version of docker (eg 17.04.0-dev)
    $dockerVersion="0.0.0-dev"
    if (Test-Path Env:\VERSION) {$dockerVersion=$env:VERSION}

    # Do the go build in the appropriate directory
    # Note -linkmode=internal is required to be able to debug on Windows.
    # https://github.com/golang/go/issues/14319#issuecomment-189576638
    Write-Host "INFO: Building..."

    $buildTime=$(Get-Date).ToUniversalTime()
    $env:GO_LDFLAGS="-linkmode=internal `
      -X \""github.com/docker/cli/cli/version.Version=$dockerVersion\"" `
      -X \""github.com/docker/cli/cli/version.GitCommit=$gitCommit\"" `
      -X \""github.com/docker/cli/cli/version.BuildTime=$buildTime\"""
    if ($env:PLATFORM) {
      $env:GO_LDFLAGS="$env:GO_LDFLAGS -X \""github.com/docker/cli/cli/version.PlatformName=$env:PLATFORM\"""
    }

    # Generate a version in the form major,minor,patch,build
    $versionQuad=$dockerVersion -replace "[^0-9.]*" -replace "\.", ","

    # 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.
    # Generate the .syso files containing all the resources and manifest needed to compile the final docker binaries. Both 32 and 64-bit clients.
    $env:_ag_dockerVersion=$dockerVersion
    $env:_ag_gitCommit=$gitCommit

    New-Item -ItemType Directory -Path .\tmp -Force | Out-Null
    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%\"
    if ($LASTEXITCODE -ne 0) { Throw "Failed to compile client 64-bit resources" }

    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%\"
    if ($LASTEXITCODE -ne 0) { Throw "Failed to compile client 32-bit resources" }
    Remove-Item .\tmp -Recurse -Force -ErrorAction SilentlyContinue | Out-Null

    Push-Location $root\cmd\$directory; $global:pushed=$True

    # By using --% we can use \"key=%foo%\" and have a environment variable foo that contains spaces
    go build $raceParm $verboseParm $allParm $optParm -tags "$buildTags" `
      -o "$root\build\$directory.exe" `
      -ldflags --% "%GO_LDFLAGS%"

    if ($LASTEXITCODE -ne 0) { Throw "Failed to compile" }
    Pop-Location; $global:pushed=$False
}

# Run the unit tests
Function Run-UnitTests() {
    Write-Host "INFO: Running unit tests..."
    $testPath="./..."
    $goListCommand = "go list -e -f '{{if ne .Name """ + '\"github.com/docker/cli\"' + """}}{{.ImportPath}}{{end}}' $testPath"
    $pkgList = $(Invoke-Expression $goListCommand)
    if ($LASTEXITCODE -ne 0) { Throw "go list for unit tests failed" }
    $pkgList = $pkgList | Select-String -Pattern "github.com/docker/cli"
    $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/cli/vendor"
    $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/cli/man"
    $pkgList = $pkgList | Select-String -NotMatch "github.com/docker/cli/e2e"
    $pkgList = $pkgList -replace "`r`n", " "
    $goTestCommand = "go test" + $raceParm + " -cover -ldflags -w -tags """ + "autogen" + """ -a """ + "-test.timeout=10m" + """ $pkgList"
    Invoke-Expression $goTestCommand
    if ($LASTEXITCODE -ne 0) { Throw "Unit tests failed" }
}

# Start of main code.
Try {
    Write-Host -ForegroundColor Cyan "INFO: make.ps1 starting at $(Get-Date)"

    # Get to the root of the repo
    $root = $(Split-Path $MyInvocation.MyCommand.Definition -Parent | Split-Path -Parent)
    Push-Location $root

    # Handle the "-All" shortcut to turn on all things we can handle.
    # Note we expressly only include the items which can run in a container - the validations tests cannot
    # as they require the .git directory which is excluded from the image by .dockerignore
    if ($All) { $Client=$True; $TestUnit=$True }

    # Handle the "-Binary" shortcut to build both client and daemon.
    if ($Binary) { $Client = $True; }

    # Verify git is installed
    if ($(Get-Command git -ErrorAction SilentlyContinue) -eq $nil) { Throw "Git does not appear to be installed" }

    # Verify go is installed
    if ($(Get-Command go -ErrorAction SilentlyContinue) -eq $nil) { Throw "GoLang does not appear to be installed" }

    # Build the binaries
    if ($Client) {
        # Create the build directory if it doesn't exist
        if (-not (Test-Path ".\build")) { New-Item ".\build" -ItemType Directory | Out-Null }

        # Perform the actual build
        Execute-Build "" "docker"
    }

    # Run unit tests
    if ($TestUnit) { Run-UnitTests }

    # Gratuitous ASCII art.
    if ($Client) {
        Write-Host
        Write-Host -ForegroundColor Green " ________   ____  __."
        Write-Host -ForegroundColor Green " \_____  \ `|    `|/ _`|"
        Write-Host -ForegroundColor Green " /   `|   \`|      `<"
        Write-Host -ForegroundColor Green " /    `|    \    `|  \"
        Write-Host -ForegroundColor Green " \_______  /____`|__ \"
        Write-Host -ForegroundColor Green "         \/        \/"
        Write-Host
    }
}
Catch [Exception] {
    Write-Host -ForegroundColor Red ("`nERROR: make.ps1 failed:`n$_")

    # More gratuitous ASCII art.
    Write-Host
    Write-Host -ForegroundColor Red  "___________      .__.__             .___"
    Write-Host -ForegroundColor Red  "\_   _____/____  `|__`|  `|   ____   __`| _/"
    Write-Host -ForegroundColor Red  " `|    __) \__  \ `|  `|  `| _/ __ \ / __ `| "
    Write-Host -ForegroundColor Red  " `|     \   / __ \`|  `|  `|_\  ___// /_/ `| "
    Write-Host -ForegroundColor Red  " \___  /  (____  /__`|____/\___  `>____ `| "
    Write-Host -ForegroundColor Red  "     \/        \/             \/     \/ "
    Write-Host

    Throw $_
}
Finally {
    Pop-Location # As we pushed to the root of the repo as the very first thing
    if ($global:pushed) { Pop-Location }
    Write-Host -ForegroundColor Cyan "INFO: make.ps1 ended at $(Get-Date)"
}