Module: Lyp::Lilypond
- Defined in:
- lib/lyp/lilypond.rb
Constant Summary collapse
- CMP_VERSION =
proc do |x, y| Gem::Version.new(x[:version]) <=> Gem::Version.new(y[:version]) end
- BASE_URL =
"http://download.linuxaudio.org/lilypond/binaries"
Class Attribute Summary collapse
-
.forced_version ⇒ Object
readonly
Returns the value of attribute forced_version.
Class Method Summary collapse
- .check_lilypond! ⇒ Object
- .compile(argv, opts = {}) ⇒ Object
- .copy_fonts_from_all_packages(version, opts) ⇒ Object
- .copy_lilypond_files(base_path, version, opts) ⇒ Object
-
.current_lilypond ⇒ Object
The current lilypond path is stored in a temporary file named by the session id.
- .default_lilypond ⇒ Object
- .detect_lilypond_platform ⇒ Object
- .detect_use_version_argument(argv) ⇒ Object
- .detect_version_from_specifier(version_specifier) ⇒ Object
- .download_lilypond(url, fn, opts) ⇒ Object
- .exec(cmd, raise_on_failure = true) ⇒ Object
- .force_env_version! ⇒ Object
- .forced_lilypond ⇒ Object
- .get_session_settings ⇒ Object
- .get_system_lilyponds_paths ⇒ Object
- .install(version_specifier, opts = {}) ⇒ Object
- .install_lilypond_files(fn, platform, version, opts) ⇒ Object
-
.install_lilypond_files_linux(fn, target, platform, version, opts) ⇒ Object
Since linux versions are distributed as sh archives, we need first to extract the sh archive, then extract the resulting tar file.
- .install_lilypond_files_osx(fn, target, platform, version, opts) ⇒ Object
- .install_version(version, opts) ⇒ Object
- .invoke(argv, opts = {}) ⇒ Object
- .latest_stable_version ⇒ Object
- .latest_unstable_version ⇒ Object
- .latest_version ⇒ Object
- .lilypond_install_url(platform, version, opts) ⇒ Object
- .list ⇒ Object
- .lyp_lilyponds ⇒ Object
- .patch_font_scm(version) ⇒ Object
-
.search(version_specifier = nil) ⇒ Object
Returns a list of versions of lilyponds available for download.
- .select_default_lilypond! ⇒ Object
- .session_settings_filename ⇒ Object
- .set_current_lilypond(path) ⇒ Object
- .set_default_lilypond(path) ⇒ Object
- .set_session_settings(settings) ⇒ Object
- .system_lilyponds ⇒ Object
- .temp_install_filename(url) ⇒ Object
- .uninstall(version) ⇒ Object
- .use(version, opts) ⇒ Object
- .valid_lilypond?(path) ⇒ Boolean
- .version_match(version, specifier, all_versions) ⇒ Object
Class Attribute Details
.forced_version ⇒ Object (readonly)
Returns the value of attribute forced_version.
74 75 76 |
# File 'lib/lyp/lilypond.rb', line 74 def forced_version @forced_version end |
Class Method Details
.check_lilypond! ⇒ Object
76 77 78 79 80 81 |
# File 'lib/lyp/lilypond.rb', line 76 def check_lilypond! # check default select_default_lilypond! unless valid_lilypond?(default_lilypond) set_current_lilypond(default_lilypond) unless valid_lilypond?(current_lilypond) end |
.compile(argv, opts = {}) ⇒ Object
8 9 10 11 12 13 |
# File 'lib/lyp/lilypond.rb', line 8 def compile(argv, opts = {}) fn = Lyp.wrap(argv.pop, opts) argv << fn invoke(argv, opts) end |
.copy_fonts_from_all_packages(version, opts) ⇒ Object
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/lyp/lilypond.rb', line 409 def copy_fonts_from_all_packages(version, opts) return unless Lyp::FONT_COPY_REQ =~ Gem::Version.new(version) ly_fonts_dir = File.join(Lyp.lilyponds_dir, version, 'share/lilypond/current/fonts') Dir["#{Lyp.packages_dir}/**/fonts"].each do |package_fonts_dir| Dir["#{package_fonts_dir}/*.otf"].each do |fn| target_fn = File.join(ly_fonts_dir, 'otf', File.basename(fn)) FileUtils.cp(fn, target_fn) end Dir["#{package_fonts_dir}/*.svg"].each do |fn| target_fn = File.join(ly_fonts_dir, 'svg', File.basename(fn)) FileUtils.cp(fn, target_fn) end Dir["#{package_fonts_dir}/*.woff"].each do |fn| target_fn = File.join(ly_fonts_dir, 'svg', File.basename(fn)) FileUtils.cp(fn, target_fn) end end end |
.copy_lilypond_files(base_path, version, opts) ⇒ Object
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/lyp/lilypond.rb', line 382 def copy_lilypond_files(base_path, version, opts) target_dir = File.join(Lyp.lilyponds_dir, version) FileUtils.rm_rf(target_dir) if File.exists?(target_dir) # create directory for lilypond files FileUtils.mkdir_p(target_dir) # copy files STDERR.puts "Copying..." unless opts[:silent] %w{bin etc lib lib64 share var}.each do |entry| dir = File.join(base_path, entry) FileUtils.cp_r(dir, target_dir, remove_destination: true) if File.directory?(dir) end STDERR.puts exec "#{target_dir}/bin/lilypond -v" unless opts[:silent] rescue => e puts e. end |
.current_lilypond ⇒ Object
The current lilypond path is stored in a temporary file named by the session id. Thus we can persist the version selected by the user
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/lyp/lilypond.rb', line 40 def current_lilypond return forced_lilypond if @forced_version settings = get_session_settings if !settings[:current] settings[:current] = default_lilypond set_session_settings(settings) end settings[:current] end |
.default_lilypond ⇒ Object
30 31 32 |
# File 'lib/lyp/lilypond.rb', line 30 def default_lilypond Lyp::Settings['lilypond/default'] end |
.detect_lilypond_platform ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/lyp/lilypond.rb', line 274 def detect_lilypond_platform case RUBY_PLATFORM when /x86_64-darwin/ "darwin-x86" when /ppc-darwin/ "darwin-ppc" when "i686-linux" "linux-x86" when "x86_64-linux" "linux-64" when "ppc-linux" "linux-ppc" end end |
.detect_use_version_argument(argv) ⇒ Object
26 27 28 |
# File 'lib/lyp/lilypond.rb', line 26 def detect_use_version_argument(argv) nil end |
.detect_version_from_specifier(version_specifier) ⇒ Object
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/lyp/lilypond.rb', line 253 def detect_version_from_specifier(version_specifier) case version_specifier when /^\d/ version_specifier when nil, 'stable' latest_stable_version when 'unstable' latest_unstable_version when 'latest' latest_version else req = Gem::Requirement.new(version_specifier) lilypond = search.reverse.find {|l| req =~ Gem::Version.new(l[:version])} if lilypond lilypond[:version] else raise "Could not find version matching #{version_specifier}" end end end |
.download_lilypond(url, fn, opts) ⇒ Object
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/lyp/lilypond.rb', line 313 def download_lilypond(url, fn, opts) STDERR.puts "Downloading #{url}" unless opts[:silent] download_count = 0 client = HTTPClient.new conn = client.get_async(url) msg = conn.pop total_size = msg.header['Content-Length'].first.to_i io = msg.content unless opts[:silent] = ProgressBar.create(title: 'Download', total: total_size) end File.open(fn, 'w+') do |f| while data = io.read(10000) download_count += data.bytesize f << data unless opts[:silent] .progress = download_count if download_count <= total_size end end end .finish unless opts[:silent] end |
.exec(cmd, raise_on_failure = true) ⇒ Object
488 489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'lib/lyp/lilypond.rb', line 488 def exec(cmd, raise_on_failure = true) success = nil Open3.popen3(cmd) do |_in, _out, _err, wait_thr| exit_value = wait_thr.value $_out = _out.read $_err = _err.read success = exit_value == 0 end if !success && raise_on_failure raise "Error executing cmd #{cmd}: #{$_err}" end success end |
.force_env_version! ⇒ Object
67 68 69 70 71 72 |
# File 'lib/lyp/lilypond.rb', line 67 def force_env_version! @forced_version = ENV['LILYPOND_VERSION'] unless @forced_version raise "LILYPOND_VERSION not set" end end |
.forced_lilypond ⇒ Object
59 60 61 62 63 64 65 |
# File 'lib/lyp/lilypond.rb', line 59 def forced_lilypond lilypond = lyp_lilyponds.find do |l| l[:version] == @forced_version end lilypond && lilypond[:path] end |
.get_session_settings ⇒ Object
95 96 97 |
# File 'lib/lyp/lilypond.rb', line 95 def get_session_settings YAML.load(IO.read(session_settings_filename)) rescue {} end |
.get_system_lilyponds_paths ⇒ Object
179 180 181 182 183 184 185 186 187 |
# File 'lib/lyp/lilypond.rb', line 179 def get_system_lilyponds_paths self_bin_dir = File.dirname(File.($0)) list = `which -a lilypond` list = list.lines.map {|f| f.chomp}.reject do |l| dir = File.dirname(l) (dir == Gem.bindir) || (dir == Lyp::LYP_BIN_DIRECTORY) || (dir == self_bin_dir) end end |
.install(version_specifier, opts = {}) ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/lyp/lilypond.rb', line 241 def install(version_specifier, opts = {}) version = detect_version_from_specifier(version_specifier) raise "No version found matching specifier #{version_specifier}" unless version STDERR.puts "Installing version #{version}" unless opts[:silent] install_version(version, opts) lilypond_path = "#{Lyp.lilyponds_dir}/#{version}/bin/lilypond" set_current_lilypond(lilypond_path) set_default_lilypond(lilypond_path) if opts[:default] end |
.install_lilypond_files(fn, platform, version, opts) ⇒ Object
338 339 340 341 342 343 344 345 346 347 348 349 350 351 |
# File 'lib/lyp/lilypond.rb', line 338 def install_lilypond_files(fn, platform, version, opts) tmp_target = "/tmp/lyp-lilypond-#{version}" FileUtils.mkdir_p(tmp_target) case platform when /darwin/ install_lilypond_files_osx(fn, tmp_target, platform, version, opts) when /linux/ install_lilypond_files_linux(fn, tmp_target, platform, version, opts) end ensure FileUtils.rm_rf(tmp_target) end |
.install_lilypond_files_linux(fn, target, platform, version, opts) ⇒ Object
Since linux versions are distributed as sh archives, we need first to extract the sh archive, then extract the resulting tar file
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/lyp/lilypond.rb', line 362 def install_lilypond_files_linux(fn, target, platform, version, opts) STDERR.puts "Extracting..." unless opts[:silent] # create temp directory in which to extract .sh file tmp_dir = "/tmp/lyp-#{Time.now.to_f}" FileUtils.mkdir_p(tmp_dir) FileUtils.cd(tmp_dir) do exec "sh #{fn} --tarball >/dev/null" end tmp_fn = "#{tmp_dir}/lilypond-#{version}-1.#{platform}.tar.bz2" exec "tar -xjf #{tmp_fn} -C #{target}" copy_lilypond_files("#{target}/usr", version, opts) ensure FileUtils.rm_rf(tmp_dir) end |
.install_lilypond_files_osx(fn, target, platform, version, opts) ⇒ Object
353 354 355 356 357 358 |
# File 'lib/lyp/lilypond.rb', line 353 def install_lilypond_files_osx(fn, target, platform, version, opts) STDERR.puts "Extracting..." unless opts[:silent] exec "tar -xjf #{fn} -C #{target}" copy_lilypond_files("#{target}/LilyPond.app/Contents/Resources", version, opts) end |
.install_version(version, opts) ⇒ Object
289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/lyp/lilypond.rb', line 289 def install_version(version, opts) platform = detect_lilypond_platform url = lilypond_install_url(platform, version, opts) fn = temp_install_filename(url) download_lilypond(url, fn, opts) unless File.file?(fn) install_lilypond_files(fn, platform, version, opts) patch_font_scm(version) copy_fonts_from_all_packages(version, opts) end |
.invoke(argv, opts = {}) ⇒ Object
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/lyp/lilypond.rb', line 15 def invoke(argv, opts = {}) lilypond = detect_use_version_argument(argv) || current_lilypond case opts[:mode] when :system system("#{lilypond} #{argv.join(" ")}") else Kernel.exec(lilypond, *argv) end end |
.latest_stable_version ⇒ Object
229 230 231 |
# File 'lib/lyp/lilypond.rb', line 229 def latest_stable_version search.reverse.find {|l| Gem::Version.new(l[:version]).segments[1].even?}[:version] end |
.latest_unstable_version ⇒ Object
233 234 235 |
# File 'lib/lyp/lilypond.rb', line 233 def latest_unstable_version search.reverse.find {|l| Gem::Version.new(l[:version]).segments[1].odd?}[:version] end |
.latest_version ⇒ Object
237 238 239 |
# File 'lib/lyp/lilypond.rb', line 237 def latest_version search.last[:version] end |
.lilypond_install_url(platform, version, opts) ⇒ Object
301 302 303 304 305 306 |
# File 'lib/lyp/lilypond.rb', line 301 def lilypond_install_url(platform, version, opts) ext = platform =~ /darwin/ ? ".tar.bz2" : ".sh" filename = "lilypond-#{version}-1.#{platform}" "#{BASE_URL}/#{platform}/#{filename}#{ext}" end |
.list ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/lyp/lilypond.rb', line 113 def list system_list = system_lilyponds lyp_list = lyp_lilyponds default = default_lilypond unless default latest = system_list.sort(&CMP_VERSION).last || lyp_list.sort(&CMP_VERSION).last if latest default = latest[:path] set_default_lilypond(default) end end current = current_lilypond lilyponds = system_list + lyp_list lilyponds.each do |l| l[:default] = l[:path] == default l[:current] = l[:path] == current end # sort by version lilyponds.sort!(&CMP_VERSION) end |
.lyp_lilyponds ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/lyp/lilypond.rb', line 138 def lyp_lilyponds list = [] Dir["#{Lyp.lilyponds_dir}/*"].each do |path| next unless File.directory?(path) && File.basename(path) =~ /^[\d\.]+$/ root_path = path version = File.basename(path) path = File.join(path, "bin/lilypond") list << { root_path: root_path, path: path, version: version } end list end |
.patch_font_scm(version) ⇒ Object
402 403 404 405 406 407 |
# File 'lib/lyp/lilypond.rb', line 402 def patch_font_scm(version) return unless Lyp::FONT_PATCH_REQ =~ Gem::Version.new(version) target_fn = File.join(Lyp.lilyponds_dir, version, 'share/lilypond/current/scm/font.scm') FileUtils.cp(Lyp::FONT_PATCH_FILENAME, target_fn) end |
.search(version_specifier = nil) ⇒ Object
Returns a list of versions of lilyponds available for download
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/lyp/lilypond.rb', line 192 def search(version_specifier = nil) require 'open-uri' require 'nokogiri' platform = detect_lilypond_platform url = "#{BASE_URL}/#{platform}/" doc = Nokogiri::HTML(open(url)) versions = [] doc.xpath("//td//a").each do |a| if a[:href] =~ /^lilypond-([0-9\.]+)/ versions << $1 end end installed_versions = list.map {|l| l[:version]} versions.select {|v| version_match(v, version_specifier, versions)}.map do |v| { version: v, installed: installed_versions.include?(v) } end end |
.select_default_lilypond! ⇒ Object
87 88 89 90 91 92 93 |
# File 'lib/lyp/lilypond.rb', line 87 def select_default_lilypond! latest = system_lilyponds.sort(&CMP_VERSION).last || lyp_lilyponds.sort(&CMP_VERSION).last if latest default = latest[:path] set_default_lilypond(default) end end |
.session_settings_filename ⇒ Object
105 106 107 |
# File 'lib/lyp/lilypond.rb', line 105 def session_settings_filename "/tmp/lyp.session.#{Process.getsid}.yml" end |
.set_current_lilypond(path) ⇒ Object
53 54 55 56 57 |
# File 'lib/lyp/lilypond.rb', line 53 def set_current_lilypond(path) settings = get_session_settings settings[:current] = path set_session_settings(settings) end |
.set_default_lilypond(path) ⇒ Object
34 35 36 |
# File 'lib/lyp/lilypond.rb', line 34 def set_default_lilypond(path) Lyp::Settings['lilypond/default'] = path end |
.set_session_settings(settings) ⇒ Object
99 100 101 102 103 |
# File 'lib/lyp/lilypond.rb', line 99 def set_session_settings(settings) File.open(session_settings_filename, 'w+') do |f| f << YAML.dump(settings) end end |
.system_lilyponds ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/lyp/lilypond.rb', line 157 def system_lilyponds list = get_system_lilyponds_paths return list if list.empty? list.inject([]) do |m, path| begin resp = `#{path} -v` if resp.lines.first =~ /LilyPond ([0-9\.]+)/i m << { root_path: File.(File.join(File.dirname(path), '..')), path: path, version: $1, system: true } end rescue # ignore error end m end end |
.temp_install_filename(url) ⇒ Object
308 309 310 311 |
# File 'lib/lyp/lilypond.rb', line 308 def temp_install_filename(url) u = URI(url) "/tmp/lyp-installer-#{File.basename(u.path)}" end |
.uninstall(version) ⇒ Object
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'lib/lyp/lilypond.rb', line 468 def uninstall(version) lilyponds = list.reverse lilypond = lilyponds.find {|l| l[:version] == version && !l[:system]} unless lilypond raise "Invalid version specified: #{version}" end lilyponds.delete(lilypond) latest = lilyponds.first if lilypond[:default] set_default_lilypond(latest && latest[:path]) end if lilypond[:current] set_current_lilypond(latest && latest[:path]) end lilypond_dir = File.('../..', lilypond[:path]) FileUtils.rm_rf(lilypond_dir) end |
.use(version, opts) ⇒ Object
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/lyp/lilypond.rb', line 433 def use(version, opts) lilypond_list = list.reverse case version when 'system' lilypond = lilypond_list.find {|v| v[:system] } unless lilypond raise "Could not find a system installed version of lilypond" end when 'latest' lilypond = lilypond_list.first when 'stable' lilypond = lilypond_list.find do |v| Gem::Version.new(v[:version]).segments[1].even? end when 'unstable' lilypond = lilypond_list.find do |v| Gem::Version.new(v[:version]).segments[1].odd? end else version = "~>#{version}.0" if version =~ /^\d+\.\d+$/ req = Gem::Requirement.new(version) lilypond = lilypond_list.find {|v| req =~ Gem::Version.new(v[:version])} end unless lilypond raise "Could not find a lilypond matching \"#{version}\"" end set_current_lilypond(lilypond[:path]) set_default_lilypond(lilypond[:path]) if opts[:default] lilypond end |
.valid_lilypond?(path) ⇒ Boolean
83 84 85 |
# File 'lib/lyp/lilypond.rb', line 83 def valid_lilypond?(path) File.file?(path) && (`#{path} -v` =~ /^GNU LilyPond/) end |
.version_match(version, specifier, all_versions) ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/lyp/lilypond.rb', line 216 def version_match(version, specifier, all_versions) case specifier when 'latest' version == all_versions.last when 'stable' Gem::Version.new(version).segments[1].even? when 'unstable' Gem::Version.new(version).segments[1].odd? else Gem::Requirement.new(specifier) =~ Gem::Version.new(version) end end |