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 140 141 142 143 144 145 146 147 148
|
# -*- coding: utf-8 -*-
# specファイル自動生成
require "boot/delayer"
require "userconfig"
require "fileutils"
require 'ripper'
# イカサマ依存関係自動解決クラス。
# あまり頼りにしないでくれ、Rubyのパース面倒なんだよ
class Depend < Ripper::Filter
attr_reader :spec
def initialize(*args)
@last_const = ""
super end
def set_spec(spec)
@spec = spec
self end
# シンボル開始の:。次のidentをシンボルと見る
def on_symbeg(tok, f)
:symbol end
def on_ident(tok, f)
if f == :symbol
on_ex_symbol(tok)
else
on_ex_ident(tok) end end
# 定数。Gtk::TimeLine みたいなのが出てきた場合、on_const Gtk, on_op ::, on_const NestedQuote
# の順番でイベントが発生するみたい…。
def on_const(tok, f)
if f == :op
@last_const += '::' + tok
else
@last_const = tok end
case @last_const
when /\AG[td]k\Z/ # GtkクラスとかGdkクラス使ってたらgtkプラグインに依存してるだろう
depend :gtk3
when /\APlugin::(\w+)/ # Plugin::なんとか は、プラグインスラッグのキャメルケース名なので、使ってたら依存してる
depend $1.gsub(/([a-z])([A-Z])/, '\1_\2').downcase.to_sym end end
def on_op(tok, f)
case tok
when "::"
:op end end
# シンボル
def on_ex_symbol(tok)
end
# 変数とかメソッド的なやつ。
# command DSLを検出してもcommandプラグインには依存させない。
# commandプラグインは基本的なmikutterコマンドを定義するだけで、mikutterコマンドの仕組み自体には関係ないから。
# commandプラグインで使われている条件クラスを使っていたら、on_constで依存してると判断される。
def on_ex_ident(tok)
case tok
when 'defactivity'
depend :activity
when 'tab', 'timeline', 'nativewidget' # UIっぽい単語があったらguiに依存してそう
depend :gui
when 'profiletab' # profiletabはプロフィールにも依存する
depend :gui
depend :profile
when 'settings' # 設定DSLの開始。settingsプラグイン。
depend :settings
end end
# slug に依存していることを登録する
# ==== Args
# [slug] 依存しているプラグイン (Symbol)
def depend(slug)
if spec['slug'].to_sym != slug and not spec["depends"]["plugin"].include?(slug.to_s)
spec["depends"]["plugin"] << slug.to_s end end
end
def spec_generate(dir)
dir = File.expand_path(dir)
specfile = File.join(dir, ".mikutter.yml")
legacy_specfile = File.join(dir, "spec")
spec = if FileTest.exist?(specfile)
YAML.load_file(specfile)
elsif FileTest.exist?(legacy_specfile)
YAML.load_file(legacy_specfile)
else
user = UserConfig[:verify_credentials] || {}
idname = user[:idname]
{"slug" => File.basename(dir).to_sym, "depends" => {"mikutter" => Environment::VERSION.to_s}, "version" => "1.0", "author" => idname} end
slug = spec["slug"].to_sym
basefile = File.join(dir, "#{slug}.rb")
unless FileTest.exist? basefile
puts "file #{basefile} notfound. select plugin slug."
expects = Dir.glob(File.join(dir, "*.rb")).map{ |filename| File.basename(filename, '.rb') }
if expects.empty?
puts "please create #{basefile}."
end
expects.each_with_index{ |filename, index|
puts "[#{index}] #{filename}"
}
print "input number or slug [q:quit, s:skip]> "
number = STDIN.gets(chomp: true)
case number
when /q/i
abort
when /s/i
return
when /\A[0-9]+\Z/
slug = expects[number.to_i].to_sym
else
slug = number.to_sym end
spec["slug"] = slug
basefile = File.join(dir, "#{slug}.rb") end
source = File.open(basefile){ |io| io.read }
if not spec.has_key?("name")
print "#{slug}: name> "
spec["name"] = STDIN.gets(chomp: true)
end
if not spec.has_key?("description")
print "#{slug}: description> "
spec["description"] = STDIN.gets(chomp: true)
end
spec["depends"] = {"version" => "1.0", "plugin" => []} if not spec.has_key?("depends")
spec["depends"]["plugin"] = [] if not spec["depends"].has_key?("plugin")
depend = Depend.new(source).set_spec(spec)
depend.parse
content = YAML.dump(depend.spec)
File.open(specfile, "w"){ |io| io.write content }
puts content
end
target = ARGV[1]
if target == "all"
unless ARGV[2]
puts "directory is not specified."
puts "usage: mikutter.rb spec all directory"
exit end
Dir.glob(File.join(ARGV[2], "*/")).each{ |dir|
spec_generate(dir) }
else
unless ARGV[1]
puts "directory is not specified."
puts "usage: mikutter.rb spec directory"
exit end
spec_generate(target)
end
|