-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathRakefile
139 lines (110 loc) · 3.83 KB
/
Rakefile
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
# frozen_string_literal: true
require "pathname"
require "securerandom"
require "shellwords"
require "minitest/test_task"
require "rake/clean"
require "rubocop/rake_task"
tapioca = "sorbet/tapioca"
ignore_file = ".ignore"
CLEAN.push(*%w[.idea/ .ruby-lsp/ .yardoc/ doc/], *FileList["*.gem"], ignore_file)
CLOBBER.push(*%w[sorbet/rbi/annotations/ sorbet/rbi/gems/], tapioca)
multitask(:default) do
sh(*%w[rake --tasks])
end
desc("Preview docs; use `PORT=<PORT>` to change the port")
multitask(:"docs:preview") do
sh(*%w[yard server --reload --quiet --bind [::] --port], ENV.fetch("PORT", "8808"))
end
desc("Run test suites; use `TEST=path/to/test.rb` to run a specific test file")
multitask(:test) do
rb =
FileList[ENV.fetch("TEST", "./test/**/*_test.rb")]
.map { "require_relative(#{_1.dump});" }
.join
ruby(*%w[-w -e], rb, verbose: false) { fail unless _1 }
end
rubo_find = %w[find ./lib ./test ./rbi -type f -and ( -name *.rb -or -name *.rbi ) -print0]
xargs = %w[xargs --no-run-if-empty --null --max-procs=0 --max-args=300 --]
desc("Lint `*.rb(i)`")
multitask(:"lint:rubocop") do
lint = xargs + %w[rubocop --fail-level E] + (ENV.key?("CI") ? %w[--format github] : [])
sh("#{rubo_find.shelljoin} | #{lint.shelljoin}")
end
desc("Format `*.rb(i)`")
multitask(:"format:rubocop") do
fmt = xargs + %w[rubocop --fail-level F --autocorrect --format simple --]
sh("#{rubo_find.shelljoin} | #{fmt.shelljoin}")
end
desc("Format `*.rbs`")
multitask(:"format:syntax_tree") do
find = %w[find ./sig -type f -name *.rbs -print0]
inplace = /darwin|bsd/ =~ RUBY_PLATFORM ? %w[-i''] : %w[-i]
uuid = SecureRandom.uuid
# `syntax_tree` has trouble with `rbs`'s class & module aliases
sed = xargs + %w[sed -E] + inplace + %w[-e]
# annotate unprocessable aliases with a unique comment
pre = sed + ["s/(class|module) ([^ ]+) = (.+$)/# \\1 #{uuid}\\n\\2: \\3/", "--"]
fmt = xargs + %w[stree write --plugin=rbs --]
# remove the unique comment and unprocessable aliases to type aliases
subst = <<~SED
s/# (class|module) #{uuid}/\\1/
t l1
b
: l1
N
s/\\n *([^:]+): (.+)$/ \\1 = \\2/
SED
# for each line:
# 1. try transform the unique comment into `class | module`, if successful, branch to label `l1`.
# 2. at label `l1`, join previously annotated line with `class | module` information.
pst = sed + [subst, "--"]
success = false
# transform class aliases to type aliases, which syntax tree has no trouble with
sh("#{find.shelljoin} | #{pre.shelljoin}")
# run syntax tree to format `*.rbs` files
sh("#{find.shelljoin} | #{fmt.shelljoin}") do
success = _1
end
# transform type aliases back to class aliases
sh("#{find.shelljoin} | #{pst.shelljoin}")
# always run post-processing to remove comment marker
fail unless success
end
desc("Format everything")
multitask(format: [:"format:rubocop", :"format:syntax_tree"])
desc("Typecheck `*.rbs`")
multitask(:"typecheck:steep") do
sh(*%w[steep check])
end
desc("Typecheck `*.rbi`")
multitask(:"typecheck:sorbet") do
sh(*%w[srb typecheck])
end
file(tapioca) do
sh(*%w[tapioca init])
end
desc("Typecheck everything")
multitask(typecheck: [:"typecheck:steep", :"typecheck:sorbet"])
desc("Lint and typecheck")
multitask(lint: [:"lint:rubocop", :typecheck])
desc("Build yard docs")
multitask(:"build:docs") do
sh(*%w[yard])
end
desc("Build ruby gem")
multitask(:"build:gem") do
# optimizing for grepping through the gem bundle: many tools honour `.ignore` files, including VSCode
#
# both `rbi` and `sig` directories are navigable by their respective tool chains and therefore can be ignored by tools such as `rg`
Pathname(ignore_file).write(<<~GLOB)
rbi/*
sig/*
GLOB
sh(*%w[gem build -- openai.gemspec])
rm_rf(ignore_file)
end
desc("Release ruby gem")
multitask(release: [:"build:gem"]) do
sh(*%w[gem push], *FileList["openai-*.gem"])
end