shomen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,119 @@
1
+ module Shomen
2
+
3
+ require 'shomen/cli/abstract'
4
+
5
+ module CLI
6
+
7
+ # RDoc command line interface.
8
+ class TomDocCommand < Abstract
9
+
10
+ #
11
+ def self.run(*argv)
12
+ new.run(argv)
13
+ end
14
+
15
+ # New Shomen TomDoc command line interface.
16
+ def initialize
17
+ end
18
+
19
+ #
20
+ def run(argv)
21
+ require 'shomen/tomdoc'
22
+
23
+ defaults = {}
24
+ defaults[:format] = 'json'
25
+ defaults[:force] = false
26
+ defaults[:source] = true
27
+
28
+ options = parse(argv, :format, :force, :visibility, :main, :source, defaults)
29
+
30
+ if !options[:force] && !root?
31
+ $stderr.puts "Not a project directory. Use --force to override."
32
+ exit -1
33
+ end
34
+
35
+ if argv.empty?
36
+ if File.exist?('.document')
37
+ files = File.read('.document').split("\n")
38
+ files = files.reject{ |f| f.strip == '' or f.strip =~ /^\#/ }
39
+ files = files.map{ |f| Dir[f] }.flatten
40
+ else
41
+ files = ['lib']
42
+ end
43
+ else
44
+ files = argv
45
+ end
46
+
47
+ # TODO: limit extensions of files
48
+ files = files.map{ |f| File.directory?(f) ? Dir[File.join(f, '**/*')] : f }.flatten
49
+
50
+ main = options[:main] || Dir.glob('{README.*,README}').first
51
+ visibility = options[:visibility].to_s
52
+ format = options[:format]
53
+
54
+ case format
55
+ when 'json', 'yaml'
56
+ else
57
+ $stderr.puts "ERROR: Format must be 'yaml` or 'json`."
58
+ exit -1
59
+ end
60
+
61
+ argf = argf(files)
62
+
63
+ tomdoc = TomDoc::Generators::Shomen.new() #@options) ignore and pattern
64
+ tomdoc.generate(argf.read)
65
+
66
+ case format
67
+ when 'yaml'
68
+ $stdout.puts(tomdoc.table.to_yaml)
69
+ else
70
+ $stdout.puts(tomdoc.table.to_json)
71
+ end
72
+ end
73
+
74
+ # ARGF faker.
75
+ def argf(files)
76
+ buffer = ''
77
+
78
+ files.select{ |arg| File.exists?(arg) }.each do |file|
79
+ buffer << File.read(file)
80
+ end
81
+
82
+ require 'stringio'
83
+ StringIO.new(buffer)
84
+ end
85
+
86
+ =begin
87
+ on "-n", "--pattern=PATTERN",
88
+ "Limit results to strings matching PATTERN." do |pattern|
89
+
90
+ @options[:pattern] = pattern
91
+ end
92
+
93
+ on "-i", "--ignore",
94
+ "Ignore validation, print all methods we find with comments.." do
95
+
96
+ @options[:validate] = false
97
+ end
98
+ =end
99
+
100
+ #
101
+ def option_visibility(parser, options)
102
+ parser.on('-v', '--visibility TYPE') do |type|
103
+ options[:visibility] = type
104
+ end
105
+ end
106
+
107
+ #
108
+ def option_main(parser, options)
109
+ parser.on('-m', '--main FILE') do |file|
110
+ options[:main] = file
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+
@@ -0,0 +1,118 @@
1
+ module Shomen
2
+
3
+ module CLI
4
+
5
+ require 'shomen/cli/abstract'
6
+
7
+ # YARD command line interface.
8
+ #
9
+ # Unlike the RDoc command, this passes ARGV on to YARD's actual CLI interface,
10
+ # so all YARD commandline options are supported, albeit some options have
11
+ # no baring on the generation of a Shomen model).
12
+ #
13
+ # The yard command provides a utility to generate
14
+ # a Shomen doc file using YARD's .yardoc cache.
15
+ #
16
+ class YARDCommand < Abstract
17
+
18
+ #
19
+ def self.run(*argv)
20
+ new.run(argv)
21
+ end
22
+
23
+ # New Shomen YARD command line interface.
24
+ def initialize
25
+ end
26
+
27
+ #
28
+ def run(argv)
29
+ require 'shomen/yard'
30
+
31
+ force = argv.delete('--force')
32
+
33
+ if !(force or root?)
34
+ $stderr.puts "ERROR: Not a project directory. Use --force to override."
35
+ exit -1
36
+ end
37
+
38
+ # TODO: support -y/--yaml or -j/--json ?
39
+
40
+ format = (
41
+ if i = argv.index('--format') || argv.index('-f')
42
+ argv[i+1]
43
+ argv.delete_at(i)
44
+ argv.delete_at(i)
45
+ else
46
+ 'json'
47
+ end
48
+ )
49
+
50
+ case format
51
+ when 'json', 'yaml'
52
+ else
53
+ $stderr.puts "ERROR: Format must be 'yaml` or 'json`."
54
+ exit -1
55
+ end
56
+
57
+ argv.unshift('-n') # do not generate yard documentation
58
+ argv.unshift('-q') # supress yard's usual output
59
+
60
+ YARD::Registry.clear # clear the registry in memory to remove any previous runs
61
+
62
+ yard = YARD::CLI::Yardoc.new
63
+ yard.run(*argv)
64
+
65
+ files = yard.options[:files].map(&:filename) + yard.files
66
+ database = yard.options[:db]
67
+
68
+ options = {}
69
+ options[:format] = format
70
+ options[:files] = files
71
+ options[:db] = database
72
+
73
+ #options = parse(argv, :yaml, :clear, :db, :yardopts, :force, defaults)
74
+
75
+ yard = Shomen::YardAdaptor.new(options)
76
+ yard.generate
77
+
78
+ case format
79
+ when 'yaml'
80
+ $stdout.puts(yard.table.to_yaml)
81
+ else
82
+ $stdout.puts(yard.table.to_json)
83
+ end
84
+ end
85
+
86
+ #
87
+ #def option_yaml(parser, options)
88
+ # parser.on('-y', '--yaml', 'output YAML instead of JSON') do
89
+ # options[:format] = :yaml
90
+ # end
91
+ #end
92
+
93
+ #
94
+ #def option_clear(parser, options)
95
+ # parser.on('-c', '--clear') do
96
+ # options[:clear] = true
97
+ # end
98
+ #end
99
+
100
+ #
101
+ #def option_db(parser, options)
102
+ # parser.on('-b', '--db DIR') do |dir|
103
+ # options[:db] = dir
104
+ # end
105
+ #end
106
+
107
+ #
108
+ #def option_yardopts(parser, options)
109
+ # parser.on('--yardopts FILE') do |file|
110
+ # options[:yardopts] = file
111
+ # end
112
+ #end
113
+
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,3 @@
1
+ class Hash
2
+ def to_h; self; end
3
+ end
@@ -0,0 +1,81 @@
1
+ require 'yaml'
2
+
3
+ module Shomen
4
+
5
+ # Encapsulate metadata, which preferably comes from a .ruby file,
6
+ # but can fallback to a gemspec.
7
+ #
8
+ class Metadata
9
+ include Enumerable
10
+
11
+ # Present working directoty.
12
+ PWD = Dir.pwd
13
+
14
+ # Glob pattern for looking up gemspec.
15
+ GEMSPEC_PATTERN = '{.gemspec,*.gemspec}'
16
+
17
+ #
18
+ def initialize
19
+ @data = (
20
+ data = {}
21
+ if dotruby
22
+ data.merge!(YAML.load_file(dotruby))
23
+ elsif gemspec
24
+ # prefereably use dotruby library to convert,
25
+ # but wait until it's more mainstream
26
+ require 'rubygems/specification'
27
+ spec = ::Gem::Specification.load(gemspec)
28
+ data['name'] = spec.name,
29
+ data['title'] = spec.name.capitalize,
30
+ data['version'] = spec.version.to_s,
31
+ data['authors'] = [spec.author],
32
+ data['summary'] = spec.summary,
33
+ data['description'] = spec.description,
34
+ data['resources'] = {'homepage' => spec.homepage},
35
+ else
36
+ # TODO: Raise error instead ?
37
+ data['name'] = File.basename(Dir.pwd)
38
+ end
39
+ data['path'] = '(metadata)'
40
+ data['markup'] = 'rdoc'
41
+ data
42
+ )
43
+ end
44
+
45
+ #
46
+ def dotruby
47
+ file = File.join(PWD, '.ruby')
48
+ return nil unless File.exist?(file)
49
+ file
50
+ end
51
+
52
+ #
53
+ def gemspec
54
+ file = Dir[File.join(PWD, GEMSPEC_PATTERN)].first
55
+ return nil unless file && File.exist?(file)
56
+ file
57
+ end
58
+
59
+ #
60
+ def [](name)
61
+ @data[name]
62
+ end
63
+
64
+ #
65
+ def size
66
+ @data.size
67
+ end
68
+
69
+ #
70
+ def each(&blk)
71
+ @data.each(&blk)
72
+ end
73
+
74
+ #
75
+ def to_h
76
+ @data
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,21 @@
1
+ if RUBY_VERSION > '1.9'
2
+ require_relative 'model/abstract'
3
+ require_relative 'model/document'
4
+ require_relative 'model/script'
5
+ require_relative 'model/module'
6
+ require_relative 'model/class'
7
+ require_relative 'model/method'
8
+ require_relative 'model/attribute'
9
+ # require_relative 'model/function'
10
+ require_relative 'model/constant'
11
+ else
12
+ require 'shomen/model/abstract'
13
+ require 'shomen/model/document'
14
+ require 'shomen/model/script'
15
+ require 'shomen/model/module'
16
+ require 'shomen/model/class'
17
+ require 'shomen/model/method'
18
+ require 'shomen/model/attribute'
19
+ # require 'shomen/model/function'
20
+ require 'shomen/model/constant'
21
+ end
@@ -0,0 +1,84 @@
1
+ module Shomen
2
+
3
+ require 'shomen/core_ext/hash'
4
+
5
+ module Model
6
+
7
+ # Baseclass for all model classes.
8
+ #
9
+ class AbstractPrime
10
+ #
11
+ def self.attr_accessor(name)
12
+ name = name.to_s
13
+ define_method(name) do
14
+ self[name]
15
+ end
16
+ define_method(name+'=') do |x|
17
+ self[name] = x
18
+ end
19
+ end
20
+
21
+ #
22
+ def self.type
23
+ name.split('::').last.downcase
24
+ end
25
+
26
+ #
27
+ def initialize(settings={})
28
+ @table = {}
29
+ settings.each do |k,v|
30
+ s = "#{k}=".gsub('-','_')
31
+ __send__(s,v)
32
+ end
33
+ end
34
+
35
+ #
36
+ def [](k)
37
+ @table[k.to_s]
38
+ end
39
+
40
+ #
41
+ def []=(k,v)
42
+ @table[k.to_s] = v
43
+ end
44
+
45
+ #
46
+ def to_h
47
+ t = {}
48
+ @table.each do |k,v|
49
+ if v.respond_to?(:to_h)
50
+ t[k] = v.to_h
51
+ else
52
+ t[k] = v
53
+ end
54
+ end
55
+ t
56
+ end
57
+
58
+ end
59
+
60
+ #
61
+ class Abstract < AbstractPrime
62
+
63
+ #
64
+ def initialize(settings={})
65
+ super(settings)
66
+ @table['!'] = self.class.type
67
+ end
68
+
69
+ # Full name.
70
+ attr_accessor :path
71
+
72
+ # Hash of label => description.
73
+ attr_accessor :tags
74
+
75
+ #
76
+ def type
77
+ self['!']
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,25 @@
1
+ module Shomen
2
+
3
+ module Model
4
+
5
+ require 'shomen/model/method'
6
+
7
+ #
8
+ class Attribute < Method
9
+ #
10
+ def self.type; 'attribute'; end
11
+
12
+ #
13
+ def initialize(settings={})
14
+ super(settings)
15
+ self['!'] = settings['singleton'] ? 'class-attribute' : 'attribute'
16
+ end
17
+
18
+ # 'R', 'W' or 'RW'
19
+ attr_accessor :rw
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end