diggit 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
20
+
21
+ require 'formatador'
22
+
23
+ class Formatador
24
+ @level = :normal
25
+
26
+ class << self
27
+ attr_accessor :level
28
+ end
29
+
30
+ def self.info(str)
31
+ Formatador.display_line(str) if visible(__method__)
32
+ end
33
+
34
+ def self.debug(str)
35
+ Formatador.display_line(str) if visible(__method__)
36
+ end
37
+
38
+ def self.ok(str)
39
+ Formatador.display_line("[green]#{str}[/]") if visible(__method__)
40
+ end
41
+
42
+ def self.warn(str)
43
+ Formatador.display_line("[yellow]#{str}[/]") if visible(__method__)
44
+ end
45
+
46
+ def self.error(str)
47
+ Formatador.display_line("[red]#{str}[/]") if visible(__method__)
48
+ end
49
+
50
+ def self.visible(method)
51
+ target = method.to_sym
52
+ if target == :ok || target == :error || target == :info
53
+ true
54
+ elsif (target == :warn || target == :debug) && level == :fine
55
+ true
56
+ else
57
+ false
58
+ end
59
+ end
60
+ end
61
+
62
+ Log = Formatador
@@ -1,8 +1,31 @@
1
1
  # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
2
20
 
3
21
  require_relative 'core'
4
22
 
5
23
  module Diggit
24
+ # Base class for plugins. They have associated options.
25
+ #
26
+ # @abstract Abstract superclass for all plugins.
27
+ # @!attribute [r] options
28
+ # @return [Hash<String, Object>] the hash of options.
6
29
  class Plugin
7
30
  attr_reader :options
8
31
 
@@ -25,6 +48,15 @@ module Diggit
25
48
  end
26
49
  end
27
50
 
51
+ # Base class for analyses and joins. Runnables can be runned or cleaned.
52
+ # These methods have to be implemented in the subclasses.
53
+ # Addons can be made available to a runnable through a call to {.require\_addons}.
54
+ # Addons can be accessed through the addons attribute, and they contain
55
+ # automatically methods that has names of their addons.
56
+ # @see Addon
57
+ # @abstract Abstract superclass for analysis and joins.
58
+ # @!attribute [r] addons
59
+ # @return [Hash<String, Addon>] the hash of addons.
28
60
  class Runnable < Plugin
29
61
  attr_reader :addons
30
62
 
@@ -35,22 +67,57 @@ module Diggit
35
67
  @addons.each_key { |a| self.class.class_eval { define_method(a) { return @addons[a] } } }
36
68
  end
37
69
 
70
+ # Run the runnable.
71
+ # @abstract This method must be overrided.
72
+ # @return [void]
38
73
  def run
39
74
  end
40
75
 
76
+ # Clean the runnable.
77
+ # @abstract This method must be overrided.
78
+ # @return [void]
41
79
  def clean
42
80
  end
43
81
 
82
+ # Add an addon as a required addon.
83
+ #
84
+ # @param names Array<String> the names of addons to require.
85
+ # They correspond to the name of their class with underscore case.
86
+ # @return [void]
87
+ def self.require_addons(*names)
88
+ @required_addons = names
89
+ end
90
+
44
91
  def self.required_addons
45
92
  return [] if @required_addons.nil?
46
93
  @required_addons
47
94
  end
48
-
49
- def self.require_addons(*names)
50
- @required_addons = names
51
- end
52
95
  end
53
96
 
97
+ # Base class for joins. Joins are applied on each source that has been:
98
+ # 1. succesfully cloned,
99
+ # 2. has been analyzed by the required analyses.
100
+ # Required analyses are added with a call to {.require\_analyses}.
101
+ # They can access addons through the addons attribute or with a method having the addon name.
102
+ # @see Runnable
103
+ # @abstract Subclass and override run and clean to implement a custom join class.
104
+ # @!attribute [rw] sources
105
+ # @return [Array<Source>] the sources to be joined.
106
+ # @example A sample join using an addon.
107
+ # class JoinWithAddon < Diggit::Join
108
+ # require_addons "db"
109
+ #
110
+ # def run
111
+ # db.do_something
112
+ # puts @options
113
+ # puts @sources
114
+ # puts "Runned!"
115
+ # end
116
+ #
117
+ # def clean
118
+ # puts "Cleaned!"
119
+ # end
120
+ # end
54
121
  class Join < Runnable
55
122
  attr_accessor :sources
56
123
 
@@ -59,16 +126,42 @@ module Diggit
59
126
  @sources = []
60
127
  end
61
128
 
129
+ # Add an analysis as a required analysis.
130
+ #
131
+ # @param names Array<String> the names of analyses to require.
132
+ # They correspond to the name of their class with underscore case.
133
+ # @return [void]
134
+ def self.require_analyses(*names)
135
+ @required_analyses = names
136
+ end
137
+
62
138
  def self.required_analyses
63
139
  return [] if @required_analyses.nil?
64
140
  @required_analyses
65
141
  end
66
-
67
- def self.require_analyses(*names)
68
- @required_analyses = names
69
- end
70
142
  end
71
143
 
144
+ # Base class for analyses. Diggit analyses are applied on each source that has been succesfully cloned.
145
+ # They can access the Diggit addons through the addons attribute.
146
+ # @see Runnable
147
+ # @abstract Subclass and override run and clean to implement a custom analysis class.
148
+ # @!attribute [rw] source
149
+ # @return [Source] the source to be analyzed.
150
+ # @example A sample analysis using an addon
151
+ # class AnalysisWithAddon < Diggit::Analysis
152
+ # require_addons "db"
153
+ #
154
+ # def run
155
+ # db.do_something
156
+ # puts @options
157
+ # puts @source
158
+ # puts "Runned!"
159
+ # end
160
+ #
161
+ # def clean
162
+ # puts "Cleaned!"
163
+ # end
164
+ # end
72
165
  class Analysis < Runnable
73
166
  attr_accessor :source
74
167
 
@@ -1,5 +1,23 @@
1
1
  # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
2
20
 
3
21
  module Diggit
4
- VERSION = "2.0.0"
22
+ VERSION = "2.0.1"
5
23
  end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
20
+
21
+ require 'mongo'
22
+
23
+ # A MongoDB addon for Diggit. The name of this addon is :db.
24
+ # This addon might use an :mongo hash in the global options. In this
25
+ # hash, the :database key allows to configure the name of the database.
26
+ # @!attribute [r] db
27
+ # @return [Mongo::DB] the mongo database object.
28
+ class Db < Diggit::Addon
29
+ DEFAULT_URL = 'mongodb://127.0.0.1:27017/diggit'
30
+
31
+ attr_reader :client
32
+
33
+ def initialize(*args)
34
+ super
35
+ url = DEFAULT_URL
36
+ url = @options[:mongo][:url] if @options.key?(:mongo) && @options[:mongo].key?(:url)
37
+ @client = Mongo::Client.new(url)
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
20
+
21
+ # A output addon for Diggit. The name of the addon is :output, and can be reached in the
22
+ # addons hash. This addon might use an :output hash in the global options. In this hash, the
23
+ # :out key allows to configure the name of the output folder and :tmp the name of the temporary output
24
+ # folder.
25
+ # @!attribute [r] out
26
+ # @return [String] the absolute path of the output folder.
27
+ # @!attribute [r] tmp
28
+ # @return [String] the absolute path of the temporary output folder.
29
+ class Out < Diggit::Addon
30
+ attr_reader :out, :tmp
31
+
32
+ DEFAULT_OUT = 'out'
33
+ DEFAULT_TMP = 'tmp'
34
+
35
+ def initialize(*args)
36
+ super
37
+
38
+ out = DEFAULT_OUT
39
+ out = @options[:output][:out] if @options.key?(:output) && @options[:output].key?(:out)
40
+ tmp = DEFAULT_TMP
41
+ tmp = @options[:output][:tmp] if @options.key?(:output) && @options[:output].key?(:tmp)
42
+
43
+ @out = File.absolute_path(out)
44
+ @tmp = File.absolute_path(tmp)
45
+
46
+ FileUtils.mkdir_p(@out) unless File.exist?(@out)
47
+ FileUtils.mkdir_p(@tmp) unless File.exist?(@tmp)
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ # Copyright 2015 Matthieu Foucault <foucaultmatthieu@gmail.com>
20
+ #
21
+
22
+ R = nil # fixing SIGPIPE error in some cases. See http://hfeild-software.blogspot.fr/2013/01/rinruby-woes.html
23
+
24
+ require "rinruby"
25
+
26
+ class R < Diggit::Addon
27
+ def initialize(*args)
28
+ super(args)
29
+ @r = RinRuby.new({ interactive: false, echo: true })
30
+ end
31
+
32
+ def method_missing(meth, *args, &block)
33
+ @r.send meth, *args, &block
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
20
+
21
+ require 'yaml'
22
+
23
+ class Cloc < Diggit::Analysis
24
+ require_addons 'db'
25
+
26
+ def initialize(options)
27
+ super(options)
28
+ end
29
+
30
+ def run
31
+ cloc = `cloc . --progress-rate=0 --quiet --yaml`
32
+ return if cloc.empty?
33
+ yaml = YAML.load(cloc.lines[2..-1].join)
34
+ yaml.delete('header')
35
+ output = { source: @source.url, cloc: yaml }
36
+ db.client['cloc'].insert_one(output)
37
+ end
38
+
39
+ def clean
40
+ db.client['cloc'].find({ source: @source.url }).delete_one
41
+ end
42
+ end
@@ -1,4 +1,22 @@
1
1
  # encoding: utf-8
2
+ #
3
+ # This file is part of Diggit.
4
+ #
5
+ # Diggit is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # Diggit is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with Diggit. If not, see <http://www.gnu.org/licenses/>.
17
+ #
18
+ # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
+ #
2
20
 
3
21
  require 'spec_helper'
4
22
  require 'fileutils'
@@ -39,6 +57,16 @@ RSpec.describe Diggit::Dig do
39
57
  expect(analysis_instance.test_addon.foo).to eq("Foo.")
40
58
  end
41
59
 
60
+ it "should load an analysis enlosed in a module" do
61
+ analysis = Diggit::Dig.it.plugin_loader.load_plugin("other_analysis", :analysis)
62
+ expect(analysis.to_s).to eq('MyModule::OtherAnalysis')
63
+ end
64
+
65
+ it "should emit a warning in case of ambiguous analysis name" do
66
+ expect(Diggit::Dig.it.plugin_loader).to receive(:warn).with(/Ambiguous plugin name/)
67
+ Diggit::Dig.it.plugin_loader.load_plugin("duplicate_analysis", :analysis)
68
+ end
69
+
42
70
  it "should load a join" do
43
71
  join = Diggit::Dig.it.plugin_loader.load_plugin("test_join", :join)
44
72
  expect(join.to_s).to eq('TestJoin')
@@ -80,21 +108,23 @@ RSpec.describe Diggit::Dig do
80
108
  expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].url).to eq TEST_URL
81
109
  end
82
110
 
83
- it "should perform analyses" do
111
+ it "should perform analyses in order" do
84
112
  Diggit::Dig.it.config.add_analysis("test_analysis")
113
+ Diggit::Dig.it.config.add_analysis("test_analysis_with_addon")
85
114
  Diggit::Dig.it.analyze
86
115
  # expect(TestAnalysis.state).to eq("runned")
87
- expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].analysis?('test_analysis')).to be true
116
+ expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].all_analyses).to eq(%w(test_analysis test_analysis_with_addon))
88
117
  Diggit::Dig.init("spec/dgit")
89
- expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].analysis?('test_analysis')).to be true
118
+ expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].all_analyses).to eq(%w(test_analysis test_analysis_with_addon))
90
119
  end
91
120
 
92
121
  it "should handle analyses with error" do
93
122
  Diggit::Dig.it.config.add_analysis("test_analysis_with_error")
94
123
  Diggit::Dig.it.analyze
95
- expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].analysis?('test_analysis')).to be true
96
- expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].error?).to be true
97
- expect(Diggit::Dig.it.journal.sources_by_ids(0)[0].error[:message]).to eq("Error!")
124
+ src = Diggit::Dig.it.journal.sources_by_ids(0)[0]
125
+ expect(src.all_analyses).to include("test_analysis")
126
+ expect(src.error?).to be true
127
+ expect(src.error[:message]).to eq("Error!")
98
128
  end
99
129
 
100
130
  it "should perform joins" do