indexer 0.1.0 → 0.2.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.
Files changed (35) hide show
  1. data/.index +8 -4
  2. data/Gemfile.lock +29 -0
  3. data/HISTORY.md +18 -1
  4. data/README.md +5 -2
  5. data/data/indexer/{r2013/index.kwalify → index.kwalify} +0 -0
  6. data/data/indexer/{r2013/index.yes → index.yes} +0 -0
  7. data/data/indexer/{r2013/index.yesi → index.yesi} +0 -0
  8. data/data/indexer/{r2013/ruby.txt → ruby.txt} +0 -0
  9. data/data/indexer/{r2013/yaml.txt → yaml.txt} +0 -0
  10. data/lib/indexer/attributes.rb +7 -3
  11. data/lib/indexer/command.rb +18 -13
  12. data/lib/indexer/components.rb +1 -0
  13. data/lib/indexer/components/conflict.rb +7 -0
  14. data/lib/indexer/components/engine.rb +87 -0
  15. data/lib/indexer/components/requirement.rb +17 -15
  16. data/lib/indexer/conversion/gemspec.rb +9 -9
  17. data/lib/indexer/conversion/gemspec_exporter.rb +2 -1
  18. data/lib/indexer/core_ext/hash/rekey.rb +89 -0
  19. data/lib/indexer/core_ext/hash/to_h.rb +4 -0
  20. data/lib/indexer/core_ext/kernel/cli.rb +54 -0
  21. data/lib/indexer/importer/html.rb +5 -0
  22. data/lib/indexer/importer/markdown.rb +22 -4
  23. data/lib/indexer/metadata.rb +27 -10
  24. data/lib/indexer/validator.rb +7 -6
  25. data/lib/indexer/webui.rb +167 -0
  26. data/lib/indexer/webui/assets/dotruby_binding.js +41 -0
  27. data/lib/indexer/webui/assets/dotruby_model.js +203 -0
  28. data/lib/indexer/webui/assets/jquery-1.4.2.min.js +154 -0
  29. data/lib/indexer/webui/assets/json2.js +482 -0
  30. data/lib/indexer/webui/assets/knockout-2.0.0.js +97 -0
  31. data/lib/indexer/webui/assets/testdata.json +23 -0
  32. data/lib/indexer/webui/assets/underscore-min.js +31 -0
  33. data/lib/indexer/webui/index-old.html +92 -0
  34. data/lib/indexer/webui/index.html +286 -0
  35. metadata +53 -19
@@ -0,0 +1,4 @@
1
+ class Hash
2
+ def to_h; self; end unless method_defined?(:to_h)
3
+ end
4
+
@@ -0,0 +1,54 @@
1
+ module Kernel
2
+ private
3
+ #
4
+ # CLI is based on Clap library
5
+ # Copyright (c) 2010 Michel Martens
6
+ #
7
+ def cli(*args)
8
+ opts = args.pop
9
+ argv = (args.first || ARGV).dup
10
+ args = []
11
+
12
+ # Split option aliases.
13
+ opts = opts.inject({}) do |h,(k,v)|
14
+ k.to_s.split(/\s+/).each{|o| h[o]=v}; h
15
+ end
16
+
17
+ # Convert single dash flags into multiple flags.
18
+ argv = argv.inject([]) do |a, v|
19
+ if v[0,1] == '-' && v[1,1] != '-'
20
+ a.concat(v[1..-1].chars.map{|c| "-#{c}"})
21
+ else
22
+ a << v
23
+ end
24
+ a
25
+ end
26
+
27
+ while argv.any?
28
+ item = argv.shift
29
+ flag = opts[item]
30
+
31
+ if flag
32
+ # Work around lambda semantics in 1.8.7.
33
+ arity = [flag.arity, 0].max
34
+
35
+ # Raise if there are not enough parameters
36
+ # available for the flag.
37
+ if argv.size < arity
38
+ raise ArgumentError
39
+ end
40
+
41
+ # Call the lambda with N items from argv,
42
+ # where N is the lambda's arity.
43
+ flag.call(*argv.shift(arity))
44
+ else
45
+
46
+ # Collect the items that don't correspond to
47
+ # flags.
48
+ args << item
49
+ end
50
+ end
51
+
52
+ args
53
+ end
54
+ end
@@ -153,6 +153,11 @@ module Indexer
153
153
  entry['version'] = n.content.strip
154
154
  end
155
155
 
156
+ # TODO: better approach to optional field?
157
+ if n = node.at_css('.optional')
158
+ entry['optional'] = true #n.content.strip != "false"
159
+ end
160
+
156
161
  if n = (node.at_css('.groups') || node.at_css('.group'))
157
162
  text = n.content.strip
158
163
  text = text.sub(/^[(]/, '').sub(/[)]$/, '').strip
@@ -25,14 +25,32 @@ module Indexer
25
25
  #
26
26
  def load_markdown(file)
27
27
  require 'nokogiri'
28
- require 'redcarpet'
29
28
 
29
+ text = File.read(file)
30
+
31
+ begin
32
+ require 'redcarpet'
33
+ html = render_with_redcarpet(text)
34
+ rescue LoadError
35
+ require 'kramdown'
36
+ html = render_with_kramdown(text)
37
+ end
38
+
39
+ doc = Nokogiri::HTML(html)
40
+
41
+ load_html(doc)
42
+ end
43
+
44
+ #
45
+ def render_with_redcarpet(text)
30
46
  renderer = Redcarpet::Render::HTML.new()
31
47
  markdown = Redcarpet::Markdown.new(renderer, :autolink=>true, :tables=>true, :space_after_headers=>true)
32
- html = markdown.render(File.read(file))
33
- doc = Nokogiri::HTML(html)
48
+ markdown.render(text)
49
+ end
34
50
 
35
- load_html(doc)
51
+ #
52
+ def render_with_kramdown(text)
53
+ Kramdown::Document.new(text).to_html
36
54
  end
37
55
 
38
56
  end
@@ -51,7 +51,7 @@ module Indexer
51
51
  end
52
52
 
53
53
  #
54
- # Create a new Meta::Spec given a Gem::Specification or .gemspec file.
54
+ # Create a new Metadata instance given a Gem::Specification or .gemspec file.
55
55
  #
56
56
  # @param [Gem::Specification,String] gemspec
57
57
  # RubyGems Gem::Specification object or path to .gemspec file.
@@ -319,17 +319,20 @@ module Indexer
319
319
 
320
320
  # TODO: should we warn if directory does not exist?
321
321
 
322
- # Sets the require paths of the project.
322
+ # Sets the named paths of the project.
323
323
  #
324
- # @param [Array<String>, String] paths
325
- # The require-paths or a glob-pattern.
324
+ # @param [Hash[String]=Array<String>] path_map
325
+ # Mappaing of names to list of paths.
326
326
  #
327
- def load_path=(paths)
328
- @data[:load_path] = \
329
- Array(paths).map do |path|
330
- Valid.path!(path)
331
- path
327
+ def paths=(path_map)
328
+ @data[:paths] = \
329
+ map = {}
330
+ path_map = path_map.to_hash if path_map.respond_to?(:to_hash)
331
+ Valid.hash!(path_map)
332
+ path_map.each do |name, paths|
333
+ map[name.to_s] = Array(paths).map{ |path| Valid.path!(path) }
332
334
  end
335
+ map
333
336
  end
334
337
 
335
338
  # List of language engine/version family supported.
@@ -534,6 +537,20 @@ module Indexer
534
537
 
535
538
  # -- Utility Methods ----------------------------------------------------
536
539
 
540
+ #
541
+ # Legacy method to common Ruby path via `paths['load']`.
542
+ #
543
+ def load_path
544
+ paths['load']
545
+ end
546
+
547
+ #
548
+ # Legacy method to set `paths['load']`.
549
+ #
550
+ def load_path=(path)
551
+ paths['load'] = Array(path).map{ |path| Valid.path!(path) }
552
+ end
553
+
537
554
  #
538
555
  # Adds a new requirement.
539
556
  #
@@ -599,7 +616,7 @@ module Indexer
599
616
  true
600
617
  end
601
618
 
602
- # TODO: What was used for again, load_path ?
619
+ # TODO: What was used for again, load path ?
603
620
  =begin
604
621
  #
605
622
  # Iterates over the paths.
@@ -101,11 +101,12 @@ module Indexer
101
101
  super(value)
102
102
  end
103
103
 
104
- # Loadpath must be an Array of valid pathnames or a String of pathnames
105
- # separated by colons or semi-colons.
106
- def load_path=(value)
107
- Valid.array!(value, :load_path)
108
- value.each_with_index{ |path, i| Valid.path!(path, "load_path #{i}") }
104
+ # Paths must be a Hash of names mapped to an Array of valid pathnames.
105
+ def paths=(value)
106
+ Valid.hash!(value, :paths)
107
+ value.each do |name, paths|
108
+ paths.each_with_index{ |path, i| Valid.path!(path, "paths[#{name}] ##{i}") }
109
+ end
109
110
  super(value)
110
111
  end
111
112
 
@@ -294,7 +295,7 @@ module Indexer
294
295
  :resources => [],
295
296
  :repositories => [],
296
297
  :categories => [],
297
- :load_path => ['lib'],
298
+ :paths => {'load' => ['lib']},
298
299
  :copyrights => []
299
300
  }
300
301
  end
@@ -0,0 +1,167 @@
1
+ #require 'fileutils'
2
+ #require 'tmpdir'
3
+ require 'optparse'
4
+ require 'json'
5
+
6
+ require 'rack'
7
+ require 'rack/server'
8
+ require 'rack/handler'
9
+ require 'rack/builder'
10
+ require 'rack/directory'
11
+ require 'rack/file'
12
+
13
+ module Indexer
14
+
15
+ module WebUI
16
+
17
+ # Server is a Rack-based server that simply serves up the editing page.
18
+ #
19
+ class Server
20
+
21
+ ROOT = File.join(File.dirname(__FILE__), 'webui')
22
+
23
+ # Rack configuration file.
24
+ #RACK_FILE = 'brite.ru'
25
+
26
+ #
27
+ #
28
+ #
29
+ def self.start(argv)
30
+ new(argv).start
31
+ end
32
+
33
+ #
34
+ # Server options, parsed from command line.
35
+ #
36
+ attr :options
37
+
38
+ #
39
+ # Setup new instance of Brite::Server.
40
+ #
41
+ def initialize(argv)
42
+ @options = ::Rack::Server::Options.new.parse!(argv)
43
+
44
+ @root = argv.first || Dir.pwd
45
+
46
+ @options[:app] = app
47
+ #@options[:pid] = "#{tmp_dir}/pids/server.pid"
48
+
49
+ @options[:Port] ||= '4444'
50
+ end
51
+
52
+ # THINK: Should we be using a local tmp directory instead?
53
+ # Then again, why do we need them at all, really?
54
+
55
+ #
56
+ # Temporary directory used by the rack server.
57
+ #
58
+ def tmp_dir
59
+ @tmp_dir ||= File.join(Dir.tmpdir, 'indexer', root)
60
+ end
61
+
62
+ #
63
+ # Start the server.
64
+ #
65
+ def start
66
+ # ensure_site
67
+
68
+ # create required tmp directories if not found
69
+ # %w(cache pids sessions sockets).each do |dir_to_make|
70
+ # FileUtils.mkdir_p(File.join(tmp_dir, dir_to_make))
71
+ # end
72
+
73
+ ::Rack::Server.start(options)
74
+ end
75
+
76
+ # # Ensure root is a Brite Site.
77
+ # def ensure_site
78
+ # return true if File.exist?(rack_file)
79
+ # #return true if config.file
80
+ # abort "Where's the site?"
81
+ # end
82
+
83
+ # # Load Brite configuration.
84
+ # def config
85
+ # @config ||= Brite::Config.new(root)
86
+ # end
87
+
88
+ #
89
+ # Site root directory.
90
+ #
91
+ def root
92
+ ROOT
93
+ end
94
+
95
+ # Configuration file for server.
96
+ #def rack_file
97
+ # RACK_FILE
98
+ #end
99
+
100
+ #
101
+ # If the site has a `brite.ru` file, that will be used to start the server,
102
+ # otherwise a standard Rack::Directory server ise used.
103
+ #
104
+ def app
105
+ @app ||= (
106
+ #if ::File.exist?(rack_file)
107
+ # app, options = Rack::Builder.parse_file(rack_file, opt_parser)
108
+ # @options.merge!(options)
109
+ # app
110
+ #else
111
+ root = self.root
112
+ json = index_json
113
+
114
+ Rack::Builder.new do
115
+ use IndexHTML, root
116
+ map '/index' do
117
+ run Proc.new{ |env| [200, {"Content-Type" => "text/json"}, [json]] }
118
+ end
119
+ run Rack::Directory.new("#{root}")
120
+ end
121
+ #end
122
+ )
123
+ end
124
+
125
+ #
126
+ #
127
+ #
128
+ def index_json
129
+ YAML.load_file('.index').to_json
130
+ end
131
+
132
+ # Rack middleware to serve `index.html` file by default.
133
+ #
134
+ class IndexHTML
135
+ def initialize(app, root)
136
+ @app = app
137
+ @root = root || Dir.pwd
138
+ end
139
+
140
+ def call(env)
141
+ path = Rack::Utils.unescape(env['PATH_INFO'])
142
+ index_file = File.join(@root, path, 'index.html')
143
+ if File.exists?(index_file)
144
+ [200, {'Content-Type' => 'text/html'}, File.new(index_file)]
145
+ else
146
+ @app.call(env) #Rack::Directory.new(@root).call(env)
147
+ end
148
+ end
149
+ end
150
+
151
+ #
152
+ #def log_path
153
+ # "_brite.log"
154
+ #end
155
+
156
+ #
157
+ #def middleware
158
+ # middlewares = []
159
+ # #middlewares << [Rails::Rack::LogTailer, log_path] unless options[:daemonize]
160
+ # #middlewares << [Rails::Rack::Debugger] if options[:debugger]
161
+ # Hash.new(middlewares)
162
+ #end
163
+ end
164
+
165
+ end
166
+
167
+ end
@@ -0,0 +1,41 @@
1
+
2
+ // Remove list items.
3
+ $('body').delegate(".remove", "click", function() {
4
+ var list = $(this).attr('list');
5
+
6
+ //retrieve the context
7
+ var context = ko.contextFor(this);
8
+ var parentArray = context.$parent[list];
9
+
10
+ //remove the data (context.$data) from the appropriate array on its parent (context.$parent)
11
+ parentArray.remove(context.$data);
12
+
13
+ return false;
14
+ });
15
+
16
+ // Add list items.
17
+ $('body').delegate(".insert", "click", function() {
18
+ var list = $(this).attr('list');
19
+
20
+ //retrieve the context
21
+ var context = ko.contextFor(this);
22
+
23
+ var newItem = prompt("Enter new entry for " + list + ': ');
24
+
25
+ if (newItem != '' && newItem != null) {
26
+ context.$data[list].push(newItem);
27
+ };
28
+
29
+ return false;
30
+ });
31
+
32
+ //function save() {
33
+ // $(). ko.toJSON(DotRubyViewModel);
34
+ //}
35
+
36
+ function save() {
37
+ //var json = ko.toJSON(dotrubyInstance);
38
+ var json = JSON.stringify( ko.toJS(dotrubyInstance), null, 2 );
39
+ $('#lastSavedJson').val(json);
40
+ };
41
+
@@ -0,0 +1,203 @@
1
+ DotRuby = {
2
+
3
+ viewModel: function(data) {
4
+ var self = this;
5
+ var data = DotRuby.prepareData(data);
6
+
7
+ self.name = ko.observable(data.name);
8
+ self.title = ko.observable(data.title);
9
+ self.version = ko.observable(data.version);
10
+ self.codename = ko.observable(data.codename);
11
+ self.summary = ko.observable(data.summary);
12
+ self.description = ko.observable(data.description);
13
+ self.created = ko.observable(data.created);
14
+ self.date = ko.observable(data.date);
15
+ self.organization = ko.observable(data.organization);
16
+ self.suite = ko.observable(data.suite);
17
+ self.install_message = ko.observable(data.install_message);
18
+
19
+ self.authors = ko.observableArray(data.authors);
20
+ self.repositories = ko.observableArray(data.repositories);
21
+ self.requirements = ko.observableArray(data.requirements);
22
+ self.dependencies = ko.observableArray(data.dependencies);
23
+ self.conflicts = ko.observableArray(data.conflicts);
24
+ self.alternatives = ko.observableArray(data.alternatives);
25
+ self.resources = ko.observableArray(data.resources);
26
+ self.copyrights = ko.observableArray(data.copyrights);
27
+ self.load_path = ko.observableArray(data.load_path);
28
+
29
+ self.addResource = function(){
30
+ this.resources.push(new DotRuby.resourceModel( {label: '', uri: ''} ));
31
+ };
32
+
33
+ self.addRepository = function(){
34
+ this.repositories.push(new DotRuby.repositoryModel( {label: '', uri: '', scm: ''} ));
35
+ };
36
+
37
+ self.addRequirement = function(){
38
+ this.requirements.push(new DotRuby.requirementModel( {name: '', version: '', development: false, groups: [], engines: [], platforms: []} ));
39
+ };
40
+
41
+ self.addDependency = function(){
42
+ this.dependencies.push(new DotRuby.dependencyModel( {name: '', version: '', development: false, groups: [], engines: [], platforms: []} ));
43
+ };
44
+
45
+ self.addCopyright = function(){
46
+ this.copyrights.push(new DotRuby.copyrightModel( {holder: '', year: '', license: ''} ));
47
+ };
48
+
49
+ self.addAuthor = function(){
50
+ this.authors.push(new DotRuby.authorModel( {name: '', email: '', website: ''} ));
51
+ };
52
+
53
+ self.addAlternative = function(){
54
+ this.alternatives.push('');
55
+ };
56
+
57
+ self.addConflict = function(){
58
+ this.conflicts.push('');
59
+ };
60
+
61
+ self.addLoadpath = function(){
62
+ this.load_path.push('');
63
+ };
64
+
65
+ self.json = function(){
66
+ // @todo Convert resources back to mapping
67
+ ko.toJSON(this)
68
+ };
69
+ },
70
+
71
+ authorModel: function(data) {
72
+ var self = this;
73
+ self.name = ko.observable(data.name);
74
+ self.email = ko.observable(data.email);
75
+ self.website = ko.observable(data.website);
76
+ self.roles = ko.observableArray(data.roles);
77
+ },
78
+
79
+ repositoryModel: function(data) {
80
+ var self = this;
81
+ self.label = ko.observable(data.label);
82
+ self.uri = ko.observable(data.uri);
83
+ self.scm = ko.observable(data.scm);
84
+ },
85
+
86
+ requirementModel: function(data) {
87
+ var self = this;
88
+ self.name = ko.observable(data.name);
89
+ self.version = ko.observable(data.version);
90
+ self.groups = ko.observableArray(makeArray(data.groups));
91
+ self.platforms = ko.observableArray(makeArray(data.platforms));
92
+ self.engines = ko.observableArray(makeArray(data.engines));
93
+ self.development = ko.observable(data.development);
94
+ self.repository = ko.observable(data.repository);
95
+ },
96
+
97
+ dependencyModel: function(data) {
98
+ var self = this;
99
+ self.name = ko.observable(data.name);
100
+ self.version = ko.observable(data.version);
101
+ self.groups = ko.observableArray(makeArray(data.groups));
102
+ self.engines = ko.observableArray(makeArray(data.engines));
103
+ self.platforms = ko.observableArray(makeArray(data.platforms));
104
+ self.development = ko.observable(data.development);
105
+ self.repository = ko.observable(data.repository);
106
+ },
107
+
108
+ resourceModel: function(data) {
109
+ var self = this;
110
+ self.label = ko.observable(data.label);
111
+ self.uri = ko.observable(data.uri);
112
+ },
113
+
114
+ copyrightModel: function(data) {
115
+ var self = this;
116
+ self.holder = ko.observable(data.holder);
117
+ self.year = ko.observable(data.year);
118
+ self.license = ko.observable(data.license);
119
+ },
120
+
121
+ // take raw hash and convert elements to models
122
+ // also ensure all fields are accounted for
123
+ prepareData: function(data) {
124
+ newData = {
125
+ name: '',
126
+ version: '0.0.0',
127
+ date: '',
128
+ title: '',
129
+ organization: '',
130
+ summary: '',
131
+ description: '',
132
+ requirements: [],
133
+ dependencies: [],
134
+ alternatives: [],
135
+ repositories: [],
136
+ resources: [],
137
+ authors: [],
138
+ copyrights: []
139
+ };
140
+
141
+ _.each(data, function(val, key){
142
+ newData[key] = val;
143
+ });
144
+
145
+ newData.resources = _.map(data.resources, function(v,k){
146
+ return(new DotRuby.resourceModel({'label': k, 'uri': v}));
147
+ });
148
+
149
+ newData.requirements = _.map(data.requirements, function(a){
150
+ return(new DotRuby.requirementModel(a));
151
+ });
152
+
153
+ newData.dependencies = _.map(data.dependencies, function(a){
154
+ return(new DotRuby.dependencyModel(a));
155
+ });
156
+
157
+ newData.repositories = _.map(data.repositories, function(x){
158
+ return(new DotRuby.repositoryModel(x));
159
+ });
160
+
161
+ newData.authors = _.map(data.authors, function(x){
162
+ return(new DotRuby.authorModel(x));
163
+ });
164
+
165
+ newData.copyrights = _.map(data.copyrights, function(x){
166
+ return(new DotRuby.copyrightModel(x));
167
+ });
168
+
169
+ //newData.conflicts = _.map(data.conflicts, function(x){
170
+ // return(new DotRuby.confictModel(x));
171
+ //});
172
+
173
+ //newData.alternatives = _.map(data.alternatives, function(x){
174
+ // return(new DotRuby.copyrightModel(x));
175
+ //});
176
+
177
+ return newData;
178
+ },
179
+
180
+ };
181
+
182
+ //DotRuby.resourceModel.create = function(){
183
+ // return( new DotRuby.resourceModel({label: '', uri: ''}) );
184
+ //};
185
+
186
+ // support functions
187
+
188
+ function makeArray(value){
189
+ if (typeof(value) == Array) {
190
+ return value;
191
+ } else {
192
+ return _.compact([value]);
193
+ }
194
+ };
195
+
196
+ function makeString(value){
197
+ if (typeof(value) == String) {
198
+ return value;
199
+ } else {
200
+ return '' + value;
201
+ }
202
+ };
203
+