kompo 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +2 -4
- data/.devcontainer/devcontainer.json +2 -2
- data/.standard.yml +2 -0
- data/CHANGELOG.md +27 -0
- data/Gemfile +10 -2
- data/Gemfile.lock +115 -3
- data/README.md +117 -10
- data/Rakefile +12 -2
- data/docs/document.md.ja +31 -0
- data/exe/kompo +45 -14
- data/lib/fs.c.erb +6 -0
- data/lib/kompo/cache.rb +65 -0
- data/lib/kompo/kompo_ignore.rb +40 -0
- data/lib/kompo/tasks/build_native_gem.rb +191 -0
- data/lib/kompo/tasks/bundle_install.rb +224 -0
- data/lib/kompo/tasks/cargo_path.rb +59 -0
- data/lib/kompo/tasks/check_stdlibs.rb +58 -0
- data/lib/kompo/tasks/collect_dependencies.rb +101 -0
- data/lib/kompo/tasks/copy_gemfile.rb +78 -0
- data/lib/kompo/tasks/copy_project_files.rb +112 -0
- data/lib/kompo/tasks/find_native_extensions.rb +89 -0
- data/lib/kompo/tasks/homebrew.rb +83 -0
- data/lib/kompo/tasks/install_deps.rb +365 -0
- data/lib/kompo/tasks/install_ruby.rb +427 -0
- data/lib/kompo/tasks/kompo_vfs_path.rb +144 -0
- data/lib/kompo/tasks/kompo_vfs_version_check.rb +56 -0
- data/lib/kompo/tasks/make_fs_c.rb +202 -0
- data/lib/kompo/tasks/make_main_c.rb +65 -0
- data/lib/kompo/tasks/packing.rb +235 -0
- data/lib/kompo/tasks/ruby_build_path.rb +54 -0
- data/lib/kompo/tasks/work_dir.rb +84 -0
- data/lib/kompo/version.rb +2 -1
- data/lib/kompo.rb +47 -420
- data/lib/main.c.erb +28 -15
- data/rbs_collection.lock.yaml +116 -0
- data/rbs_collection.yaml +19 -0
- metadata +72 -8
- data/lib/kompo/kompo_fs.rb +0 -15
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'English'
|
|
4
|
+
module Kompo
|
|
5
|
+
# Section to handle platform-specific dependencies.
|
|
6
|
+
# Switches implementation based on the current platform.
|
|
7
|
+
# Exports lib_paths for linker flags (e.g., "-L/usr/local/lib")
|
|
8
|
+
class InstallDeps < Taski::Section
|
|
9
|
+
interfaces :lib_paths
|
|
10
|
+
|
|
11
|
+
def impl
|
|
12
|
+
macos? ? ForMacOS : ForLinux
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# macOS implementation - installs dependencies via Homebrew
|
|
16
|
+
class ForMacOS < Taski::Task
|
|
17
|
+
def run
|
|
18
|
+
# HomebrewPath.path triggers Homebrew installation if not present
|
|
19
|
+
@lib_paths = [
|
|
20
|
+
InstallGmp.lib_path,
|
|
21
|
+
InstallOpenssl.lib_path,
|
|
22
|
+
InstallReadline.lib_path,
|
|
23
|
+
InstallLibyaml.lib_path,
|
|
24
|
+
InstallZlib.lib_path,
|
|
25
|
+
InstallLibffi.lib_path
|
|
26
|
+
].compact.join(' ')
|
|
27
|
+
|
|
28
|
+
puts 'All Homebrew dependencies installed'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# GMP library installation Section
|
|
32
|
+
class InstallGmp < Taski::Section
|
|
33
|
+
interfaces :lib_path
|
|
34
|
+
|
|
35
|
+
def impl
|
|
36
|
+
brew = HomebrewPath.path
|
|
37
|
+
system("#{brew} list #{BREW_NAME} > /dev/null 2>&1") ? Installed : Install
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
BREW_NAME = 'gmp'
|
|
41
|
+
MARKER_FILE = File.expand_path('~/.kompo_installed_gmp')
|
|
42
|
+
|
|
43
|
+
class Installed < Taski::Task
|
|
44
|
+
def run
|
|
45
|
+
brew = HomebrewPath.path
|
|
46
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
47
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
48
|
+
puts "#{BREW_NAME} is already installed"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class Install < Taski::Task
|
|
53
|
+
def run
|
|
54
|
+
brew = HomebrewPath.path
|
|
55
|
+
puts "Installing #{BREW_NAME}..."
|
|
56
|
+
system("#{brew} install #{BREW_NAME}") or raise "Failed to install #{BREW_NAME}"
|
|
57
|
+
File.write(MARKER_FILE, 'installed')
|
|
58
|
+
|
|
59
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
60
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def clean
|
|
64
|
+
return unless File.exist?(MARKER_FILE)
|
|
65
|
+
|
|
66
|
+
brew = HomebrewPath.path
|
|
67
|
+
puts "Uninstalling #{BREW_NAME} (installed by kompo)..."
|
|
68
|
+
system("#{brew} uninstall #{BREW_NAME}")
|
|
69
|
+
File.delete(MARKER_FILE) if File.exist?(MARKER_FILE)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# OpenSSL library installation Section
|
|
75
|
+
class InstallOpenssl < Taski::Section
|
|
76
|
+
interfaces :lib_path
|
|
77
|
+
|
|
78
|
+
def impl
|
|
79
|
+
brew = HomebrewPath.path
|
|
80
|
+
system("#{brew} list #{BREW_NAME} > /dev/null 2>&1") ? Installed : Install
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
BREW_NAME = 'openssl@3'
|
|
84
|
+
MARKER_FILE = File.expand_path('~/.kompo_installed_openssl')
|
|
85
|
+
|
|
86
|
+
class Installed < Taski::Task
|
|
87
|
+
def run
|
|
88
|
+
brew = HomebrewPath.path
|
|
89
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
90
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
91
|
+
puts "#{BREW_NAME} is already installed"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class Install < Taski::Task
|
|
96
|
+
def run
|
|
97
|
+
brew = HomebrewPath.path
|
|
98
|
+
puts "Installing #{BREW_NAME}..."
|
|
99
|
+
system("#{brew} install #{BREW_NAME}") or raise "Failed to install #{BREW_NAME}"
|
|
100
|
+
File.write(MARKER_FILE, 'installed')
|
|
101
|
+
|
|
102
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
103
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def clean
|
|
107
|
+
return unless File.exist?(MARKER_FILE)
|
|
108
|
+
|
|
109
|
+
brew = HomebrewPath.path
|
|
110
|
+
puts "Uninstalling #{BREW_NAME} (installed by kompo)..."
|
|
111
|
+
system("#{brew} uninstall #{BREW_NAME}")
|
|
112
|
+
File.delete(MARKER_FILE) if File.exist?(MARKER_FILE)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Readline library installation Section
|
|
118
|
+
class InstallReadline < Taski::Section
|
|
119
|
+
interfaces :lib_path
|
|
120
|
+
|
|
121
|
+
def impl
|
|
122
|
+
brew = HomebrewPath.path
|
|
123
|
+
system("#{brew} list #{BREW_NAME} > /dev/null 2>&1") ? Installed : Install
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
BREW_NAME = 'readline'
|
|
127
|
+
MARKER_FILE = File.expand_path('~/.kompo_installed_readline')
|
|
128
|
+
|
|
129
|
+
class Installed < Taski::Task
|
|
130
|
+
def run
|
|
131
|
+
brew = HomebrewPath.path
|
|
132
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
133
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
134
|
+
puts "#{BREW_NAME} is already installed"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class Install < Taski::Task
|
|
139
|
+
def run
|
|
140
|
+
brew = HomebrewPath.path
|
|
141
|
+
puts "Installing #{BREW_NAME}..."
|
|
142
|
+
system("#{brew} install #{BREW_NAME}") or raise "Failed to install #{BREW_NAME}"
|
|
143
|
+
File.write(MARKER_FILE, 'installed')
|
|
144
|
+
|
|
145
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
146
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def clean
|
|
150
|
+
return unless File.exist?(MARKER_FILE)
|
|
151
|
+
|
|
152
|
+
brew = HomebrewPath.path
|
|
153
|
+
puts "Uninstalling #{BREW_NAME} (installed by kompo)..."
|
|
154
|
+
system("#{brew} uninstall #{BREW_NAME}")
|
|
155
|
+
File.delete(MARKER_FILE) if File.exist?(MARKER_FILE)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# libyaml library installation Section
|
|
161
|
+
class InstallLibyaml < Taski::Section
|
|
162
|
+
interfaces :lib_path
|
|
163
|
+
|
|
164
|
+
def impl
|
|
165
|
+
brew = HomebrewPath.path
|
|
166
|
+
system("#{brew} list #{BREW_NAME} > /dev/null 2>&1") ? Installed : Install
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
BREW_NAME = 'libyaml'
|
|
170
|
+
MARKER_FILE = File.expand_path('~/.kompo_installed_libyaml')
|
|
171
|
+
|
|
172
|
+
class Installed < Taski::Task
|
|
173
|
+
def run
|
|
174
|
+
brew = HomebrewPath.path
|
|
175
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
176
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
177
|
+
puts "#{BREW_NAME} is already installed"
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class Install < Taski::Task
|
|
182
|
+
def run
|
|
183
|
+
brew = HomebrewPath.path
|
|
184
|
+
puts "Installing #{BREW_NAME}..."
|
|
185
|
+
system("#{brew} install #{BREW_NAME}") or raise "Failed to install #{BREW_NAME}"
|
|
186
|
+
File.write(MARKER_FILE, 'installed')
|
|
187
|
+
|
|
188
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
189
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def clean
|
|
193
|
+
return unless File.exist?(MARKER_FILE)
|
|
194
|
+
|
|
195
|
+
brew = HomebrewPath.path
|
|
196
|
+
puts "Uninstalling #{BREW_NAME} (installed by kompo)..."
|
|
197
|
+
system("#{brew} uninstall #{BREW_NAME}")
|
|
198
|
+
File.delete(MARKER_FILE) if File.exist?(MARKER_FILE)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# zlib library installation Section
|
|
204
|
+
class InstallZlib < Taski::Section
|
|
205
|
+
interfaces :lib_path
|
|
206
|
+
|
|
207
|
+
def impl
|
|
208
|
+
brew = HomebrewPath.path
|
|
209
|
+
system("#{brew} list #{BREW_NAME} > /dev/null 2>&1") ? Installed : Install
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
BREW_NAME = 'zlib'
|
|
213
|
+
MARKER_FILE = File.expand_path('~/.kompo_installed_zlib')
|
|
214
|
+
|
|
215
|
+
class Installed < Taski::Task
|
|
216
|
+
def run
|
|
217
|
+
brew = HomebrewPath.path
|
|
218
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
219
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
220
|
+
puts "#{BREW_NAME} is already installed"
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
class Install < Taski::Task
|
|
225
|
+
def run
|
|
226
|
+
brew = HomebrewPath.path
|
|
227
|
+
puts "Installing #{BREW_NAME}..."
|
|
228
|
+
system("#{brew} install #{BREW_NAME}") or raise "Failed to install #{BREW_NAME}"
|
|
229
|
+
File.write(MARKER_FILE, 'installed')
|
|
230
|
+
|
|
231
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
232
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def clean
|
|
236
|
+
return unless File.exist?(MARKER_FILE)
|
|
237
|
+
|
|
238
|
+
brew = HomebrewPath.path
|
|
239
|
+
puts "Uninstalling #{BREW_NAME} (installed by kompo)..."
|
|
240
|
+
system("#{brew} uninstall #{BREW_NAME}")
|
|
241
|
+
File.delete(MARKER_FILE) if File.exist?(MARKER_FILE)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# libffi library installation Section
|
|
247
|
+
class InstallLibffi < Taski::Section
|
|
248
|
+
interfaces :lib_path
|
|
249
|
+
|
|
250
|
+
def impl
|
|
251
|
+
brew = HomebrewPath.path
|
|
252
|
+
system("#{brew} list #{BREW_NAME} > /dev/null 2>&1") ? Installed : Install
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
BREW_NAME = 'libffi'
|
|
256
|
+
MARKER_FILE = File.expand_path('~/.kompo_installed_libffi')
|
|
257
|
+
|
|
258
|
+
class Installed < Taski::Task
|
|
259
|
+
def run
|
|
260
|
+
brew = HomebrewPath.path
|
|
261
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
262
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
263
|
+
puts "#{BREW_NAME} is already installed"
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
class Install < Taski::Task
|
|
268
|
+
def run
|
|
269
|
+
brew = HomebrewPath.path
|
|
270
|
+
puts "Installing #{BREW_NAME}..."
|
|
271
|
+
system("#{brew} install #{BREW_NAME}") or raise "Failed to install #{BREW_NAME}"
|
|
272
|
+
File.write(MARKER_FILE, 'installed')
|
|
273
|
+
|
|
274
|
+
prefix = `#{brew} --prefix #{BREW_NAME} 2>/dev/null`.chomp
|
|
275
|
+
@lib_path = "-L#{prefix}/lib" if $CHILD_STATUS.success? && !prefix.empty?
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def clean
|
|
279
|
+
return unless File.exist?(MARKER_FILE)
|
|
280
|
+
|
|
281
|
+
brew = HomebrewPath.path
|
|
282
|
+
puts "Uninstalling #{BREW_NAME} (installed by kompo)..."
|
|
283
|
+
system("#{brew} uninstall #{BREW_NAME}")
|
|
284
|
+
File.delete(MARKER_FILE) if File.exist?(MARKER_FILE)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Linux implementation - checks dependencies using pkg-config
|
|
291
|
+
class ForLinux < Taski::Task
|
|
292
|
+
def run
|
|
293
|
+
unless pkg_config_available?
|
|
294
|
+
puts '[WARNING] pkg-config not found. Skipping dependency check.'
|
|
295
|
+
puts 'Install pkg-config to enable automatic dependency verification.'
|
|
296
|
+
@lib_paths = ''
|
|
297
|
+
return
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
check_dependencies
|
|
301
|
+
@lib_paths = collect_lib_paths
|
|
302
|
+
|
|
303
|
+
puts 'All required development libraries are installed.'
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
REQUIRED_LIBS = {
|
|
307
|
+
'openssl' => { pkg_config: 'openssl', apt: 'libssl-dev', yum: 'openssl-devel' },
|
|
308
|
+
'readline' => { pkg_config: 'readline', apt: 'libreadline-dev', yum: 'readline-devel' },
|
|
309
|
+
'zlib' => { pkg_config: 'zlib', apt: 'zlib1g-dev', yum: 'zlib-devel' },
|
|
310
|
+
'libyaml' => { pkg_config: 'yaml-0.1', apt: 'libyaml-dev', yum: 'libyaml-devel' },
|
|
311
|
+
'libffi' => { pkg_config: 'libffi', apt: 'libffi-dev', yum: 'libffi-devel' }
|
|
312
|
+
}.freeze
|
|
313
|
+
|
|
314
|
+
private
|
|
315
|
+
|
|
316
|
+
def pkg_config_available?
|
|
317
|
+
system('which pkg-config > /dev/null 2>&1')
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def check_dependencies
|
|
321
|
+
missing = REQUIRED_LIBS.reject do |_, info|
|
|
322
|
+
system("pkg-config --exists #{info[:pkg_config]} 2>/dev/null")
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
raise build_error_message(missing) unless missing.empty?
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def collect_lib_paths
|
|
329
|
+
pkg_names = REQUIRED_LIBS.values.map { |info| info[:pkg_config] }
|
|
330
|
+
paths = pkg_names.flat_map do |pkg|
|
|
331
|
+
`pkg-config --libs-only-L #{pkg} 2>/dev/null`.chomp.split
|
|
332
|
+
end
|
|
333
|
+
paths.uniq.join(' ')
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def build_error_message(missing)
|
|
337
|
+
lib_names = missing.keys.join(', ')
|
|
338
|
+
apt_packages = missing.values.map { |info| info[:apt] }.join(' ')
|
|
339
|
+
yum_packages = missing.values.map { |info| info[:yum] }.join(' ')
|
|
340
|
+
|
|
341
|
+
<<~MSG
|
|
342
|
+
Missing required development libraries: #{lib_names}
|
|
343
|
+
|
|
344
|
+
Please install them using your package manager:
|
|
345
|
+
|
|
346
|
+
Ubuntu/Debian:
|
|
347
|
+
sudo apt-get update
|
|
348
|
+
sudo apt-get install -y #{apt_packages}
|
|
349
|
+
|
|
350
|
+
RHEL/CentOS/Fedora:
|
|
351
|
+
sudo yum install -y #{yum_packages}
|
|
352
|
+
# or: sudo dnf install -y #{yum_packages}
|
|
353
|
+
|
|
354
|
+
After installing, run kompo again.
|
|
355
|
+
MSG
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
private
|
|
360
|
+
|
|
361
|
+
def macos?
|
|
362
|
+
RUBY_PLATFORM.include?('darwin')
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|