-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
golang-1.0.tcl
451 lines (410 loc) · 18.2 KB
/
golang-1.0.tcl
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
#
# This PortGroup accommodates golang projects.
#
# Usage:
#
# PortGroup golang 1.0
#
# go.setup example.com/author/project 1.0.0 v
#
# go.vendors example.com/dep1/foo \
# lock abcdef123456... \
# rmd160 fedcba654321... \
# sha256 bdface246135... \
# size 1234 \
# vanity_domain.com/dep2_bar \
# repo example.com/dep2/bar \
# lock fedcba654321... \
# rmd160 abcdef123456... \
# sha256 fedcba654321... \
# size 4321
#
# The github-1.0 or bitbucket-1.0 portgroups are automatically applied and set
# up for projects hosted on GitHub or Bitbucket; in these cases it is not
# necessary to specify the portgroups or call github.setup or bitbucket.setup,
# i.e. the following are sufficient:
#
# PortGroup golang 1.0
# go.setup github.com/author/project 1.0.0 v
#
# or
#
# PortGroup golang 1.0
# go.setup bitbucket.com/author/project 1.0.0 v
#
# The go.vendors option expects a list of package IDs, each followed by these
# labeled values:
#
# - repo: Packages are sometimes hosted on domains that merely redirect to
# well-known hosts such as GitHub. In that case, specify the resolved package
# name with the `repo` keyword. Example: coolbiz.io/coolpackage might resolve
# to github.com/coolbiz/package. This must come before the `lock` keyword.
#
# - lock: the version of the package in git reference format. This must come
# before any checksums.
#
# - rmd160, sha256, size, etc.: checksums of the package. All checksums
# supported by the checksums keyword are supported.
#
# The list of vendors can be found in the go.sum, Gopkg.lock, glide.lock,
# etc. file in the upstream source code. The go2port tool (install via MacPorts)
# can be used to generate a skeleton portfile with precomputed go.vendors.
PortGroup legacysupport 1.1
PortGroup compiler_wrapper 1.0
options go.package go.domain go.author go.project go.version go.tag_prefix go.tag_suffix go.offline_build
proc go.setup {go_package go_version {go_tag_prefix ""} {go_tag_suffix ""}} {
global go.domain go.author go.project go.version
go.package ${go_package}
go.version ${go_version}
# go.package is split up here into go.{domain,author,project}, but a port
# may override just go.package when, for instance, the upstream author has
# decided to customize the package ID but still host on e.g. GitHub. The
# shfmt port is an example of this.
#
# It is assumed in this portgroup that go.{domain,author,project} will
# remain consistent with the distfile; this is needed when moving the source
# into the GOPATH in the post-extract block later on.
lassign [go._translate_package_id ${go_package}] go.domain go.author go.project subproject
if {${subproject} ne ""} {
ui_error "go.setup cannot handle subprojects yet"
error "unhandled subproject"
}
switch ${go.domain} {
github.com {
uplevel "PortGroup github 1.0"
github.setup ${go.author} ${go.project} ${go_version} ${go_tag_prefix} ${go_tag_suffix}
}
gitlab.com {
uplevel "PortGroup gitlab 1.0"
gitlab.setup ${go.author} ${go.project} ${go_version} ${go_tag_prefix} ${go_tag_suffix}
}
bitbucket.org {
uplevel "PortGroup bitbucket 1.0"
bitbucket.setup ${go.author} ${go.project} ${go_version} ${go_tag_prefix}
}
git.sr.ht {
uplevel "PortGroup sourcehut 1.0"
sourcehut.setup ${go.author} ${go.project} ${go_version} ${go_tag_prefix} ${go_tag_suffix}
}
gitea.com {
uplevel "PortGroup gitea 1.0"
gitea.setup ${go.author} ${go.project} ${go_version} ${go_tag_prefix} ${go_tag_suffix}
}
default {
if {![info exists PortInfo(name)]} {
name ${go.project}
}
version ${go.version}
}
}
}
proc go._translate_package_id {package_id} {
set parts [split ${package_id} /]
set domain [lindex ${parts} 0]
set author [lindex ${parts} 1]
set project [lindex ${parts} 2]
# possibly empty
set subproject [lindex ${parts} 3]
switch ${domain} {
golang.org {
# Use GitHub mirror
set domain github.com
set author golang
}
gopkg.in {
# gopkg.in redirects to GitHub
set domain github.com
if {${project} eq ""} {
# Short format: gopkg.in/foo.v1 -> github.com/go-foo/foo
set project [go._strip_gopkg_version ${author}]
set author go-${project}
} else {
# Long format: gopkg.in/foo/bar.v1 -> github.com/foo/bar
set project [go._strip_gopkg_version ${project}]
}
}
git.sr.ht {
# Strip leading ~ from author name
set author [string trim ${author} ~]
}
}
return [list ${domain} ${author} ${project} ${subproject}]
}
proc go._strip_gopkg_version {str} {
return [regsub -- \\..*$ ${str} ""]
}
options go.bin go.vendors
default go.bin {${prefix}/bin/go}
default go.vendors {}
default go.offline_build \
true
platforms darwin freebsd linux
supported_archs arm64 i386 x86_64
set goos ${os.platform}
switch ${configure.build_arch} {
arm64 { set goarch arm64 }
i386 { set goarch 386 }
x86_64 { set goarch amd64 }
default { set goarch {} }
}
default universal_variant no
default use_configure no
default dist_subdir go
default depends_build port:go
set gopath ${workpath}/gopath
default worksrcdir {gopath/src/${go.package}}
set go_env {GOPATH=${gopath} GOARCH=${goarch} GOOS=${goos} GOPROXY=off GO111MODULE=off \
CC=${configure.cc} CXX=${configure.cxx} FC=${configure.fc} \
OBJC=${configure.objc} OBJCXX=${configure.objcxx} }
default build.cmd {${go.bin} build}
default build.args ""
default build.target ""
default build.env ${go_env}
default test.cmd {${go.bin} test}
default test.args ""
default test.target ""
default test.env ${go_env}
default configure.env ${go_env}
proc go.append_env {} {
global configure.ldflags os.major build.env go.offline_build
# Create a wrapper scripts around compiler commands to enforce use of MacPorts flags
# and to aid use of MacPorts legacysupport library as required.
if { ${os.major} <= [option legacysupport.newest_darwin_requires_legacy] } {
# Note, go annoyingly uses CC for both building and linking, and thus in order to get it to correctly
# link to the legacy support library, the ldflags need to be added to the cc and ccx wrappers.
# To then prevent 'clang linker input unused' errors we must append -Wno-error at the end.
# Also remove '-static' from compilation options as this is not supported on older systems.
compwrap.compiler_args_forward \$\{\@\//-static/\}
compwrap.compiler_pre_flags-append ${configure.ldflags}
compwrap.compiler_post_flags-append -Wno-error
}
post-extract {
build.env-append \
"CC=[compwrap::wrap_compiler cc]" \
"CXX=[compwrap::wrap_compiler cxx]" \
"OBJC=[compwrap::wrap_compiler objc]" \
"OBJCXX=[compwrap::wrap_compiler objcxx]" \
"FC=[compwrap::wrap_compiler fc]" \
"F90=[compwrap::wrap_compiler f90]" \
"F77=[compwrap::wrap_compiler f77]"
if { ${os.major} <= [option legacysupport.newest_darwin_requires_legacy] } {
build.env-append \
"GO_EXTLINK_ENABLED=1" \
"BOOT_GO_LDFLAGS=-extldflags='${configure.ldflags}'" \
"CGO_CFLAGS=${configure.cflags} [get_canonical_archflags cc]" \
"CGO_CXXFLAGS=${configure.cxxflags} [get_canonical_archflags cxx]" \
"CGO_LDFLAGS=${configure.cflags} ${configure.ldflags} [get_canonical_archflags ld]" \
"GO_LDFLAGS=-extldflags='${configure.ldflags} [get_canonical_archflags ld]'"
}
configure.env-append ${build.env}
test.env-append ${build.env}
}
if { ! ${go.offline_build} } {
ui_debug "Disabling offline building for Go"
configure.env-delete \
GO111MODULE=off GOPROXY=off
build.env-delete GO111MODULE=off GOPROXY=off
test.env-delete GO111MODULE=off GOPROXY=off
}
}
port::register_callback go.append_env
# go.vendors name1 ver1 name2 ver2...
# When a go.sum, Gopkg.lock, glide.lock, etc. is present use go2port to generate values
set go.vendors_internal {}
option_proc go.vendors handle_go_vendors
proc handle_go_vendors {option action {vendors_str ""}} {
if {${action} eq "set"} {
if {[catch {
handle_set_go_vendors ${vendors_str}
} error]} {
ui_debug ${::errorInfo}
ui_error "Couldn't parse go.vendors line (${vendors_str}) [${error}]"
}
}
}
proc handle_set_go_vendors {vendors_str} {
global go.vendors_internal portchecksum::checksum_types
set num_tokens [llength ${vendors_str}]
if {$num_tokens > 0} {
# portgroups like github may set this - can't be used with multiple distfiles
extract.rename no
}
for {set ix 0} {${ix} < ${num_tokens}} {incr ix} {
# Get the Go package ID
set vpackage [lindex ${vendors_str} ${ix}]
# Package resolves to itself by default; only overridden in case of
# redirects, etc.
set vresolved ${vpackage}
# Handle the remaining values for this package
incr ix
while {1} {
set token [lindex ${vendors_str} ${ix}]
if {${token} eq "repo"} {
# Handle the package's resolved name. See discussion of this in
# header comments.
incr ix
set vresolved [lindex ${vendors_str} ${ix}]
incr ix
} elseif {${token} eq "lock"} {
# Handle the package version ("lock" as in "lockfile")
incr ix
set vversion [lindex ${vendors_str} ${ix}]
incr ix
# Split up the package ID
lassign [go._translate_package_id ${vresolved}] vdomain vauthor vproject vsubproject
if {[string match v* ${vversion}]} {
set sha1_short {}
} else {
# The vauthor may be wrong (the project has been renamed/changed
# ownership) so we need to use the SHA-1 suffix later to identify
# the package when moving into the GOPATH. GitHub uses 7 digits;
# Bitbucket uses 12. We take 7 and use globbing.
set sha1_short [string range ${vversion} 0 6]
}
lappend go.vendors_internal [list ${sha1_short} ${vpackage} ${vresolved} ${vversion}]
switch ${vdomain} {
github.com {
if {${vsubproject} eq ""} {
set distfile ${vauthor}-${vproject}-${vversion}.tar.gz
set master_site https://codeload.github.com/${vauthor}/${vproject}/legacy.tar.gz/${vversion}?dummy=
} else {
set distfile ${vauthor}-${vproject}-${vsubproject}-${vversion}.tar.gz
set master_site https://codeload.github.com/${vauthor}/${vproject}/legacy.tar.gz/${vsubproject}/${vversion}?dummy=
}
}
bitbucket.org {
if {${vsubproject} ne ""} {
ui_error "go.vendors can't handle subprojects from ${vdomain} yet"
error "unsupported dependency domain"
}
set distfile ${vversion}.tar.gz
set master_site https://bitbucket.org/${vauthor}/${vproject}/get
}
gitlab.com -
salsa.debian.org {
if {${vsubproject} ne ""} {
ui_error "go.vendors can't handle subprojects from ${vdomain} yet"
error "unsupported dependency domain"
}
set distfile ${vproject}-${vversion}.tar.gz
set master_site https://${vdomain}/${vauthor}/${vproject}/-/archive/${vversion}
}
git.sr.ht {
if {${vsubproject} ne ""} {
ui_error "go.vendors can't handle subprojects from ${vdomain} yet"
error "unsupported dependency domain"
}
set distfile ${vversion}.tar.gz
set master_site https://${vdomain}/~${vauthor}/${vproject}/archive
}
go.googlesource.com {
if {${vsubproject} ne ""} {
ui_error "go.vendors can't handle subprojects from ${vdomain} yet"
error "unsupported dependency domain"
}
set distfile ${vversion}.tar.gz
set master_site https://${vdomain}/${vauthor}/+archive/refs/tags
}
default {
ui_error "go.vendors can't handle dependencies from ${vdomain}"
error "unsupported dependency domain"
}
}
set tag [regsub -all {[^[:alpha:][:digit:]]} ${vpackage}-${vversion} -]
master_sites-append ${master_site}:${tag}
distfiles-append ${distfile}:${tag}
checksums-append ${distfile}
} elseif {${token} in ${checksum_types}} {
# Handle checksum values
incr ix
set csumval [lindex ${vendors_str} ${ix}]
incr ix
checksums-append ${token} ${csumval}
} else {
# This wasn't a checksum token, but rather the next vendor package
incr ix -1
break
}
# Stop if we have consumed all the tokens
if {${ix} == ${num_tokens}} {
break
}
}
}
}
# Setup build sources in GOPATH style:
# workpath/
# gopath/src/example.com/
# author1/project1/
# author2/project2/
# :
#
# Danger! These manipulations depend heavily on the filenames resulting from
# expanding the distfiles. GitHub and Bitbucket are known to work:
#
# - GitHub: ${author}-${project}-${7-digit hash}
# - Bitbucket: ${author}-${project}-${12-digit hash}
# - GitLab: ${project}-${ref}
#
# Support for additional hosts not conforming to this pattern will take some
# work.
post-extract {
if {${fetch.type} eq "standard"} {
# Don't try to create the worksrcpath using go.{domain,author,project}
# as the result will not be accurate when go.package has been
# customized.
file mkdir [file dirname ${worksrcpath}]
if {[file exists [glob -nocomplain ${workpath}/${go.author}-${go.project}-*]]} {
# GitHub and Bitbucket follow this path
move [glob ${workpath}/${go.author}-${go.project}-*] ${worksrcpath}
} elseif {[file exists ${workpath}/${go.project}]} {
move ${workpath}/${go.project} ${worksrcpath}
} else {
# GitLab follows this path
move [glob ${workpath}/${go.project}-*] ${worksrcpath}
}
# If the above fails then something went wrong and we should error out.
}
foreach vlist ${go.vendors_internal} {
lassign ${vlist} sha1_short vpackage vresolved vversion
ui_debug "Processing vendored dependency (sha1_short: ${sha1_short}, vpackage: ${vpackage}, vresolved: ${vresolved}, vversion: ${vversion})"
file mkdir ${gopath}/src/[file dirname ${vpackage}]
# Next is a big bag of heuristics to try to move the extracted
# dependencies into the gopath. We have to try to accommodate all naming
# schemes used by the various "forges" (GitHub, Gitlab, etc.).
lassign [go._translate_package_id ${vresolved}] _ vauthor vproject
set gitlab_workdir ${vproject}-${vversion}
if {[file exists ${workpath}/${gitlab_workdir}]} {
move ${workpath}/${gitlab_workdir} ${gopath}/src/${vpackage}
} elseif {${sha1_short} ne ""} {
move [glob ${workpath}/*-${sha1_short}*] ${gopath}/src/${vpackage}
} else {
# In some cases, this can match multiple folders, e.g.,
# gopkg.in/src-d/go-git.v4 and gopkg.in/src-d/go-git-fixtures.v3.
# We want the one that does not have any dashes in the wildcard of
# our glob expression, so use regex to identify that.
set candidates [glob ${workpath}/${vauthor}-${vproject}-*]
foreach candidate $candidates {
if {[regexp -nocase "^[quotemeta $workpath]/[quotemeta $vauthor]-[quotemeta $vproject]-\[^-\]*$" $candidate]} {
ui_debug "Choosing $candidate for ${workpath}/${vauthor}-${vproject}-*"
move $candidate ${gopath}/src/${vpackage}
break
} else {
ui_debug "Rejecting $candidate for ${workpath}/${vauthor}-${vproject}-* because it contains dashes in the wildcard match"
}
}
}
}
}
destroot {
ui_error "No destroot phase in the Portfile!"
ui_msg "Here is an example destroot phase:"
ui_msg
ui_msg "destroot {"
ui_msg { xinstall -m 0755 ${worksrcpath}/${name} ${destroot}${prefix}/bin/}
ui_msg "}"
ui_msg
ui_msg "Please check if there are additional files (configuration, documentation, etc.) that need to be installed."
error "destroot phase not implemented"
}