forked from code-golf/code-golf
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild-langs
More file actions
executable file
·136 lines (111 loc) · 4.62 KB
/
Copy pathbuild-langs
File metadata and controls
executable file
·136 lines (111 loc) · 4.62 KB
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
#!/usr/bin/env raku
use TOML::Thumb;
unit sub MAIN(Bool :$no-cache, Bool :$no-push, *@langs);
chdir $*PROGRAM.dirname;
my %langs = from-toml 'config/data/langs.toml'.IO;
if my $unknown = @langs ∖ %langs {
note "Unknown langs: $unknown";
exit 1;
}
# Build (and maybe push) lang-base.
run <docker buildx build>,
'--file', 'docker/lang-base.Dockerfile',
'--pull',
( '--push' unless $no-push ),
'--tag', 'codegolf/lang-base',
'.';
# Build all languages if no arguments are specified.
@langs ||= %langs.keys.sort: *.fc;
for %langs{@langs}:p -> (:key($name), :value(%lang)) {
my $id = id($name);
my $img = "codegolf/lang-$id";
if !$no-cache {
# Tag the builder stage so "docker system prune" won't remove it.
run «docker buildx build -t "{$img}-builder" --pull --target builder "langs/$id"»;
}
run <docker buildx build>,
( '--no-cache' if $no-cache ),
'--tag', $img,
"langs/$id";
# Size.
my $proc = run :out,
«docker images --format '{{.Size}}' -f "reference={$img}:latest"»;
$proc.sink;
# Format the size consistently so everything lines up.
with %lang<size> = $proc.out.slurp(:close).chomp {
s/(.)B$/ {$0.uc}iB/; # "XB" → " XiB"
s/^ ( \d \d ) ' ' /{$0}.0 /; # 99 → 99.0
s/^ ( \d\.\d ) ' ' /{$0}0 /; # 9.9 → 9.90
s/^ ( \d ) ' ' /{$0}.00 /; # 9 → 9.00
}
# Version.
if $id ~~ any <
05ab1e apl arkscript assembly befunge berry brainfuck cjam
erlang fish golfscript hexagony k knight lily luau stax umka
> {
"langs/$id/Dockerfile".IO.slurp ~~ / ' VER=' (\S+) | ' VERSION=' (\S+) /;
%lang<version> = do given $id {
when 'apl' { "Dyalog APL $0" }
when 'assembly' { "DefAssembler $0" }
when 'erlang' { "OTP $0" }
default { $0 }
}
}
else {
# Some langs output their version number over stderr so merge out/err.
my $proc = run «docker run -i --rm --tmpfs '/tmp:exec' $img»,
:in, :out, :merge(so $id eq 'forth' | 'scheme');
$proc.in.say: 'puts [info patchlevel]' if $id eq 'tcl';
$proc.in.close;
my $ver = $proc.out.slurp(:close).chomp.trans: "\n" => ' ';
given $name {
# Dotted decimal or hyphenated date.
my $digits = $ver ~~ / \d+ ( <[.-]> \d+ )+ /;
when 'ALGOL 68' { $ver = "Algol 68 Genie $digits" }
when 'AWK'
| 'Forth'
| 'Fortran'
| 'sed' { $ver = "GNU $name $digits" }
when 'BASIC' { $ver = "FreeBASIC $digits" }
when 'BQN' { $ver = "CBQN $digits" }
when 'C' { $ver = "TCC $digits" }
when 'C#'
| 'F#'
| 'PowerShell' { }
when 'C++' { $ver = "Clang $digits" }
when 'Clojure' { $ver = "Babashka $digits" }
when 'COBOL' { $ver = "GnuCOBOL $digits" }
when 'Common Lisp' { $ver = "GNU CLISP $digits" }
when 'D' { $ver = "DMD $digits" }
when 'Haskell' { $ver = "GHC $digits" }
when 'Java' {
$ver = $ver.match(/ \d+ ( \. \d+ )* ( \+ \d+ )? /);
$ver = "OpenJDK $ver" ~ ( ".0" if $ver ne $digits );
}
when 'JavaScript' { $ver = "V8 $digits" }
when 'Pascal' { $ver = "FPC $digits" }
when 'Prolog' { $ver = "SWI-Prolog $digits" }
when 'Raku' {
$ver ~~ m:g/ v (\S+) '.' /;
$ver = "Raku $1[0] on Rakudo $0[0]";
}
when 'Rexx' { $ver = "Regina $digits" }
when 'Scheme' { $ver = "Chez Scheme $digits" }
when 'SQL' { $ver = "SQLite $digits" }
default { $ver = $digits }
}
die "Couldn't get version string for $id." unless $ver;
%lang<version> = $ver;
}
run «docker push $img» unless $no-push;
}
spurt 'config/data/langs.toml', to-toml %langs;
# Reorder Dockerfiles: largest first to speed-up partial deploys.
my $layers;
$layers ~= sprintf(
q:b[COPY --from=codegolf/lang-%-*s / /langs/%2$s/rootfs/\n],
$ //= %langs.keys».&id».chars.max, id(.key),
) for %langs.sort: { so .value<size> ~~ /K/, -.value<size>.split(" ")[0], id(.key) };
.spurt: .slurp.subst: / ( 'COPY --from=codegolf' \N+ \n )+ /, $layers
for <docker/dev.Dockerfile docker/live.Dockerfile>».IO;
sub id { $^name.lc.subst(' ', '-').trans: qw[# + ><>] => qw[-sharp p fish] }