File: mikutter.rb

package info (click to toggle)
mikutter 5.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,780 kB
  • sloc: ruby: 22,912; sh: 186; makefile: 21
file content (132 lines) | stat: -rwxr-xr-x 3,855 bytes parent folder | download
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
#!/bin/sh
# -*- coding: utf-8; mode: ruby -*-
exec ruby -x "$0" "$@"
#!ruby
=begin rdoc
= mikutter - simple, powerful and moeful Mastodon client
Copyright (C) 2009-2024 Toshiaki Asai

This software is released under the MIT License.

http://opensource.org/licenses/mit-license.php

=end
module Mikutter; end

Regexp.timeout = 1.0

if !ENV.fetch('DISABLE_BUNDLER_SETUP', nil) || ['', '0'].include?(ENV.fetch('DISABLE_BUNDLER_SETUP', nil).to_s)
  begin
    ENV['BUNDLE_GEMFILE'] = File.expand_path(File.join(File.dirname($0), "Gemfile"))
    require 'bundler/setup'
  rescue LoadError, SystemExit
    # bundlerがないか、依存関係の解決に失敗した場合
    # System の gem を使ってみる
  end
end

require_relative 'core/miquire'
require 'boot/delayer'
require 'boot/option'
Mopt.parse exec_command: true

ENV['LIBOVERLAY_SCROLLBAR'] = '0'

require 'benchmark'
require 'thread'
require 'fileutils'

require 'lib/diva_hacks'
require 'lib/lazy'
require 'lib/reserver'
require 'lib/timelimitedqueue'
require 'lib/uithreadonly'
require 'lib/weakstorage'

require_relative 'core/utils'

require 'boot/check_config_permission'
require 'boot/mainloop'
require 'environment'

Dir.chdir(Environment::CONFROOT)

require 'system/system'

require 'boot/load_plugin'

Plugin.call(:boot, nil)

# イベントの待受を開始する。
# _profile_ がtrueなら、プロファイリングした結果を一時ディレクトリに保存する
def boot!(profile)
  begin
    RubyVM::YJIT.enable if RUBY_VERSION.split('.') >= %w[3 3]
    if profile
      require 'ruby-prof'
      begin
        notice 'start profiling'
        RubyProf.start
        Mainloop.mainloop
      ensure
        result = RubyProf.stop
        printer = RubyProf::CallTreePrinter.new(result)
        path = File.join(Environment::TMPDIR, 'profile', Time.new.strftime('%Y-%m-%d-%H%M%S'))
        FileUtils.mkdir_p(path)
        notice "profile: writing to #{path}"
        printer.print(path: path)
        notice "profile: done."
      end
    else
      Mainloop.mainloop end
  rescue => exception
    into_debug_mode(exception)
    notice "catch exception `#{exception.class}'"
    raise
  rescue Exception => exception
    notice "catch exception `#{exception.class}'"
    exception = Mainloop.exception_filter(exception)
    notice "=> `#{exception.class}'"
    raise end
  exception = Mainloop.exception_filter(nil)
  if exception
    notice "raise mainloop exception `#{exception.class}'"
    raise exception end
  notice "boot! exited normally." end

def error_handling!(exception)
  notice "catch #{exception.class}"
  if Mopt.debug && exception.respond_to?(:deferred) && exception.deferred
    if command_exist?('dot')
      notice "[[#{exception.deferred.graph_draw}]]"
    else
      notice exception.deferred.graph
    end
  end
  File.open(File.expand_path(File.join(Environment::TMPDIR, 'crashed_exception')), 'w'){ |io| Marshal.dump(exception, io) } rescue nil
  raise exception end

begin
  errfile = File.join(File.expand_path(Environment::TMPDIR), 'mikutter_dump')
  File.rename(errfile, File.expand_path(File.join(Environment::TMPDIR, 'mikutter_error'))) if File.exist?(errfile)
  if not Mopt.debug
    $stderr = File.open(errfile, 'w')
    def $stderr.write(string)
      super(string)
      self.fsync rescue nil
    end
    $logger = nil # 次の呼び出しから Kernel.logger の出力先が新しい stderr になるようにする
  end
  boot!(Mopt.profile)
  if(Delayer.exception)
    raise Delayer.exception end
rescue Interrupt, SystemExit, SignalException => exception
  notice "catch #{exception.class}"
  if Delayer.exception
    error_handling! Delayer.exception
  else
    File.delete(errfile) if File.exist?(errfile)
    raise exception end
rescue Exception => exception
  error_handling! exception end
notice "mainloop exited normally."