shomen 0.1.0

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.
@@ -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