diggit 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2fa14be04009f4668ce08541bcc05aa050308de7
4
- data.tar.gz: 2f956728d1a7d6e2ea999a0d2aa59d60ecbad58a
3
+ metadata.gz: 60e58099916b06eceaa99f9bad1f18822ac74106
4
+ data.tar.gz: 5568fc8c3a6bd36f09f25d7ceeb9233da126ffea
5
5
  SHA512:
6
- metadata.gz: 53da80f0affd555bb133b5b36129772d1a915fb5d04661f1d5b7a7c94d00a1cf347d092d5775f05372bd7b434ee28a21e6b3c0822d4a84485e4d94c4e2c20d7c
7
- data.tar.gz: 44488dca2f0ad7d39b788012e73c1ee17c608d958bde77be62cdb1cd6d20c5f84f11a6ac022e0e8663d0ad054a63f6bd89ce730e0a8d16d760ef477adbb82d90
6
+ metadata.gz: 84dd036f313699556b0fafc8604d56b45ceb7441dc7f4530061c98816973f6bb0c71406245b3569dcfa9cf244caab20d96702ba16e9f802dafce94994f6ea2e5
7
+ data.tar.gz: d82cc5a83c57e774af69f367df32dc695b72cb2807963e687502f3de309d7bf4ea784b4fa7bad6216484feab48e2c1e675f3120fefb99af444784e92c98217b3
@@ -1,5 +1,11 @@
1
1
  # Changelog of Diggit
2
2
 
3
+ ### Version 2.1.1
4
+ * Fixed small bugs in the CLI
5
+ * Fixed source error not showing up in case of clone error
6
+ * Now urls can have a trailing |id to enable checkout a tag, branch or commit with a specific id
7
+ * Out addon have more utility methods
8
+
3
9
  ### Version 2.1.0
4
10
  * Now repositories are reseted to master by default
5
11
  * Journal infrastructure has been vastly improved
data/README.md CHANGED
@@ -8,9 +8,20 @@ A ruby tool to analyze Git repositories
8
8
 
9
9
  Just run `gem install diggit`.
10
10
 
11
- ## From the source
11
+ ## From the source, with bundler
12
12
 
13
- Clone diggit using the following command: `git clone https://github.com/jrfaller/diggit.git`. The `dgit` tool is in the `bin` folder.
13
+ Install diggit using the following commands:
14
+ ```
15
+ git clone https://github.com/jrfaller/diggit.git
16
+ cd diggit
17
+ gem install bundler --user-install
18
+ bundler install
19
+ ```
20
+ Beware, the gem bin directory must be in your path. Also, the `dgit` command is in the `bin` folder of diggit.
21
+
22
+ ## From the source, with vagrant
23
+
24
+ You can automatically get a working VM with all required dependencies with only one command, how cool is that? For this, just install [vagrant](https://www.vagrantup.com/) and [virtualbox](https://www.virtualbox.org/), and `vagrant up` in a freshly cloned diggit folder (see previous section). Beware, this magic only works on Mac OS and Linux because it uses NFS shared folders.
14
25
 
15
26
  # Usage
16
27
 
@@ -26,15 +37,15 @@ You can add some repositories to be analyzed with the following command: `dgit s
26
37
 
27
38
  ### Using addons
28
39
 
29
- Addons add features the the diggit tool: for instance capability of writing to a MongoDB database, etc. To enable addons for your current diggit folder you can use the following command: `dgit addons add TestAddon`.
40
+ Addons add features the the diggit tool: for instance capability of writing to a MongoDB database, etc. To enable addons for your current diggit folder you can use the following command: `dgit addons add test_addon`.
30
41
 
31
42
  ### Setting-up analyses
32
43
 
33
- An analysis is applied to each repository. You can configure the analyses to be performed with the following command: `dgit analyses add TestAnalysis`. Analyses are performed in the order they have been added.
44
+ An analysis is applied to each repository. You can configure the analyses to be performed with the following command: `dgit analyses add test_analysis`. Analyses are performed in the order they have been added.
34
45
 
35
46
  ### Setting-up joins
36
47
 
37
- A join is performed after all analyses of all repositories have been performed. You can configure the joins to be performed with the following command: `dgit joins add TestJoin`. Joins are performed in the order they have been added.
48
+ A join is performed after all analyses of all repositories have been performed. You can configure the joins to be performed with the following command: `dgit joins add test_join`. Joins are performed in the order they have been added.
38
49
 
39
50
  ## Running analyses
40
51
 
data/bin/dgit CHANGED
@@ -49,8 +49,8 @@ module Diggit
49
49
  c.action do |_global_options, _options, _args|
50
50
  Log.info "Config"
51
51
  Log.info "======"
52
- Log.info "- Analyses: #{Diggit::Dig.it.config.get_analyses.join(', ')}"
53
- Log.info "- Joins: #{Diggit::Dig.it.config.get_joins.join(', ')}"
52
+ Log.info "- Analyses: #{Diggit::Dig.it.config.get_analyses.map(&:name).join(', ')}"
53
+ Log.info "- Joins: #{Diggit::Dig.it.config.get_joins.map(&:name).join(', ')}"
54
54
  Log.info ""
55
55
  Log.info "Journal"
56
56
  Log.info "======="
@@ -64,6 +64,20 @@ module Diggit
64
64
  Log.ok "* Ok: #{Diggit::Dig.it.journal.sources_by_state(:cloned).size}"
65
65
  Log.error "* Error: #{Diggit::Dig.it.journal.sources_by_state(:cloned, true).size}"
66
66
  end
67
+ Log.info "- Performed joins:" unless Diggit::Dig.it.journal.workspace.performed.empty?
68
+ Diggit::Dig.it.journal.workspace.performed.each do |e|
69
+ Log.indent { Log.info "#{e.name}, time: #{e.duration}" }
70
+ end
71
+ Log.info "- Canceled joins:" unless Diggit::Dig.it.journal.workspace.canceled.empty?
72
+ Diggit::Dig.it.journal.workspace.canceled.each do |e|
73
+ Log.indent do
74
+ Log.info "#{e.name}, time: #{e.duration}"
75
+ Log.indent do
76
+ Log.error e.error.message
77
+ Log.error e.error.backtrace.join("\n")
78
+ end
79
+ end
80
+ end
67
81
  end
68
82
  end
69
83
 
@@ -74,7 +88,7 @@ module Diggit
74
88
  list.action do |_global_options, _options, _args|
75
89
  sources = Diggit::Dig.it.journal.sources
76
90
  sources.each_index do |idx|
77
- msg = "#{idx} #{sources[idx].url} (#{sources[idx].state})"
91
+ msg = "#{idx} #{sources[idx].url} (#{sources[idx].entry.state})"
78
92
  sources[idx].entry.error? ? Log.error(msg) : Log.ok(msg)
79
93
  end
80
94
  end
@@ -86,11 +100,18 @@ module Diggit
86
100
  Diggit::Dig.it.journal.add_source args[0]
87
101
  end
88
102
  end
103
+ c.desc 'Delete a source.'
104
+ c.arg_name 'id'
105
+ c.command :del do |del|
106
+ del.action do |_global_options, _options, args|
107
+ Diggit::Dig.it.journal.del_source args[0]
108
+ end
109
+ end
89
110
  c.desc 'Import sources from a file.'
90
111
  c.arg_name 'file'
91
112
  c.command :import do |import|
92
113
  import.action do |_global_options, _options, args|
93
- File.open(args[0]).each { |line| Diggit::Dig.it.journal.add_source(line) }
114
+ File.open(args[0]).each { |line| Diggit::Dig.it.journal.add_source(line.strip) }
94
115
  end
95
116
  end
96
117
  c.desc 'Display all sources in error.'
@@ -110,11 +131,13 @@ module Diggit
110
131
  src = Diggit::Dig.it.journal.sources_by_ids(args[0].to_i)[0]
111
132
  Log.info "URL: #{src.url}"
112
133
  Log.info "State: #{src.entry.state}"
134
+ unless src.entry.error.nil?
135
+ Log.error src.entry.error.message
136
+ Log.error src.entry.error.backtrace.join("\n")
137
+ end
113
138
  Log.info "Performed analyses:" unless src.entry.performed.empty?
114
139
  src.entry.performed.each do |e|
115
- Log.indent do
116
- Log.info "#{e.name}, time: #{e.duration}"
117
- end
140
+ Log.indent { Log.info "#{e.name}, time: #{e.duration}" }
118
141
  end
119
142
  Log.info "Canceled analyses:" unless src.entry.canceled.empty?
120
143
  src.entry.canceled.each do |e|
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: utf-8
2
3
  #
3
4
  # This file is part of Diggit.
@@ -28,8 +29,7 @@ class String
28
29
  # Returns a underscore cased version of the string.
29
30
  # @return [String]
30
31
  def underscore
31
- gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
32
- .gsub(/([a-z\d])([A-Z])/, '\1_\2'). tr("-", "_").downcase
32
+ gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2'). tr("-", "_").downcase
33
33
  end
34
34
 
35
35
  # Returns a camel cased version of the string.
@@ -57,10 +57,14 @@ end
57
57
 
58
58
  module Diggit
59
59
  class Source
60
- attr_reader :url, :repository, :entry
60
+ DEFAULT_BRANCH = "origin/master".freeze
61
+
62
+ attr_reader :url, :repository, :entry, :oid
61
63
 
62
64
  def initialize(url)
63
- @url = url
65
+ infos = url.split(/\|/)
66
+ @url = infos[0]
67
+ @oid = infos.size > 1 ? infos[1] : DEFAULT_BRANCH
64
68
  @entry = SourceEntry.new
65
69
  @repository = nil
66
70
  end
@@ -75,21 +79,19 @@ module Diggit
75
79
 
76
80
  def clone
77
81
  @entry.error = nil
78
- if File.exist?(folder)
79
- Rugged::Repository.new(folder)
80
- else
81
- Rugged::Repository.clone_at(url, folder)
82
- end
82
+ @repository = File.exist?(folder) ? Rugged::Repository.new(folder) : Rugged::Repository.clone_at(url, folder)
83
+ @repository.checkout(@oid, { strategy: :force })
83
84
  @entry.state = :cloned
84
85
  rescue => e
85
- Log.error "Error cloning #{url}."
86
+ Log.error "Error cloning #{url}: #{e}"
87
+ e.backtrace.each { |l| Log.debug(l) }
86
88
  @entry.error = e
87
89
  end
88
90
 
89
91
  def load_repository
90
- fail "Source not cloned #{url}." if @entry.new?
92
+ raise "Source not cloned #{url}." if @entry.new?
91
93
  @repository = Rugged::Repository.new(folder)
92
- @repository.checkout("origin/master")
94
+ @repository.checkout(@oid, { strategy: :force })
93
95
  end
94
96
  end
95
97
 
@@ -114,7 +116,7 @@ module Diggit
114
116
  source_array = sources
115
117
  result = []
116
118
  ids.each do |id|
117
- fail "No such source index #{id}." if id >= source_array.length
119
+ raise "No such source index #{id}." if id >= source_array.length
118
120
  result << source_array[id]
119
121
  end
120
122
  result
@@ -125,7 +127,14 @@ module Diggit
125
127
  end
126
128
 
127
129
  def add_source(url)
128
- @sources[url] = Source.new(url) unless @sources.key?(url)
130
+ key = url.split(/\|/)[0]
131
+ @sources[key] = Source.new(url) unless @sources.key?(key)
132
+ Dig.it.save_journal
133
+ end
134
+
135
+ def del_source(id)
136
+ source = sources_by_ids(id).first
137
+ @sources.delete(source.url)
129
138
  Dig.it.save_journal
130
139
  end
131
140
  end
@@ -207,7 +216,7 @@ module Diggit
207
216
  class PluginLoader
208
217
  include Singleton
209
218
 
210
- PLUGINS_TYPES = [:addon, :analysis, :join]
219
+ PLUGINS_TYPES = [:addon, :analysis, :join].freeze
211
220
 
212
221
  # Load the plugin with the given name and type.
213
222
  # @param name [String] the name of the plugin
@@ -216,15 +225,9 @@ module Diggit
216
225
  # @return [Plugin, Class] the instance or class of the plugin.
217
226
  def load_plugin(name, type, instance = false)
218
227
  plugin = search_plugin(name, type)
219
- if plugin
220
- if instance
221
- return plugin.new(Dig.it.options)
222
- else
223
- return plugin
224
- end
225
- else
226
- fail "Plugin #{name} not found."
227
- end
228
+ raise "Plugin #{name} not found." unless plugin
229
+ return plugin.new(Dig.it.options) if instance
230
+ plugin
228
231
  end
229
232
 
230
233
  def self.plugin_paths(name, type, root)
@@ -241,13 +244,13 @@ module Diggit
241
244
 
242
245
  def search_plugin(name, type)
243
246
  return @plugins[name] if @plugins.key?(name)
244
- fail "Unknown plugin type #{type}." unless PLUGINS_TYPES.include?(type)
245
- fail "File #{name}.rb in #{type} directories not found." unless load_file(name, type)
247
+ raise "Unknown plugin type #{type}." unless PLUGINS_TYPES.include?(type)
248
+ raise "File #{name}.rb in #{type} directories not found." unless load_file(name, type)
246
249
 
247
250
  base_class = Object.const_get("Diggit::#{type.to_s.camel_case}")
248
251
  plugins = ObjectSpace.each_object(Class).select { |c| c < base_class && c.simple_name == name }
249
252
 
250
- fail "No plugin #{name} of kind #{type} found." if plugins.empty?
253
+ raise "No plugin #{name} of kind #{type} found." if plugins.empty?
251
254
  warn "Ambiguous plugin name: several plugins of kind #{type} named #{name} were found." if plugins.size > 1
252
255
 
253
256
  @plugins[name] = plugins[0]
@@ -291,11 +294,11 @@ module Diggit
291
294
  # @!attribute [r] plugin_loader
292
295
  # @return [PluginLoader] utility classes to load plugins.
293
296
  class Dig
294
- DGIT_FOLDER = ".dgit"
295
- DGIT_SOURCES = "sources"
296
- DGIT_CONFIG = "config"
297
- DGIT_OPTIONS = "options"
298
- DGIT_JOURNAL = "journal"
297
+ DGIT_FOLDER = ".dgit".freeze
298
+ DGIT_SOURCES = "sources".freeze
299
+ DGIT_CONFIG = "config".freeze
300
+ DGIT_OPTIONS = "options".freeze
301
+ DGIT_JOURNAL = "journal".freeze
299
302
 
300
303
  private_constant :DGIT_SOURCES, :DGIT_CONFIG, :DGIT_OPTIONS, :DGIT_JOURNAL
301
304
 
@@ -306,7 +309,7 @@ module Diggit
306
309
  # Returns the diggit instance.
307
310
  # @return [Dig] the instance.
308
311
  def self.it
309
- fail "Diggit has not been initialized." if @diggit.nil?
312
+ raise "Diggit has not been initialized." if @diggit.nil?
310
313
  @diggit
311
314
  end
312
315
 
@@ -338,12 +341,11 @@ module Diggit
338
341
  Oj.to_file(File.expand_path(DGIT_JOURNAL, dgit_folder), Journal.new)
339
342
  end
340
343
  FileUtils.mkdir(File.expand_path('sources', folder)) unless File.exist?(File.expand_path('sources', folder))
341
- unless File.exist?(File.expand_path("plugins", folder))
342
- FileUtils.mkdir_p(File.expand_path("plugins", folder))
343
- FileUtils.mkdir_p(File.expand_path("plugins/analysis", folder))
344
- FileUtils.mkdir_p(File.expand_path("plugins/addon", folder))
345
- FileUtils.mkdir_p(File.expand_path("plugins/join", folder))
346
- end
344
+ return if File.exist?(File.expand_path("plugins", folder))
345
+ FileUtils.mkdir_p(File.expand_path("plugins", folder))
346
+ FileUtils.mkdir_p(File.expand_path("plugins/analysis", folder))
347
+ FileUtils.mkdir_p(File.expand_path("plugins/addon", folder))
348
+ FileUtils.mkdir_p(File.expand_path("plugins/join", folder))
347
349
  end
348
350
 
349
351
  # Return the path of the given config file
@@ -364,7 +366,7 @@ module Diggit
364
366
  # Use {.init} and {.it} instead.
365
367
  # @return [Dig] a diggit object.
366
368
  def initialize(folder)
367
- fail "Folder #{folder} is not a diggit folder." unless File.exist?(File.expand_path(DGIT_FOLDER, folder))
369
+ raise "Folder #{folder} is not a diggit folder." unless File.exist?(File.expand_path(DGIT_FOLDER, folder))
368
370
  @plugin_loader = PluginLoader.instance
369
371
  @folder = folder
370
372
  end
@@ -474,7 +476,8 @@ module Diggit
474
476
  entry.toc
475
477
  entry.error = e
476
478
  placeholder.canceled << entry
477
- Log.error "Error cleaning #{runnable.name}"
479
+ Log.error "Error cleaning #{runnable.name}: #{e}"
480
+ e.backtrace.each { |l| Log.debug(l) }
478
481
  ensure
479
482
  save_journal
480
483
  end
@@ -488,7 +491,8 @@ module Diggit
488
491
  entry.toc
489
492
  entry.error = e
490
493
  placeholder.canceled << entry
491
- Log.error "Error running #{runnable.name}"
494
+ Log.error "Error running #{runnable.name}: #{e}"
495
+ e.backtrace.each { |l| Log.debug(l) }
492
496
  else
493
497
  entry.toc
494
498
  placeholder.performed << entry
@@ -29,11 +29,7 @@ module Diggit
29
29
  # @param e [Exception, nil] the error, to indicate an absence of error, pass +nil+.
30
30
  # @return [void]
31
31
  def error=(e)
32
- if e.nil?
33
- @error = nil
34
- else
35
- @error = ErrorEntry.new(e)
36
- end
32
+ @error = e.nil? ? nil : ErrorEntry.new(e)
37
33
  end
38
34
  end
39
35
 
@@ -54,7 +50,7 @@ module Diggit
54
50
  # Error status of the element.
55
51
  # @return [Boolean]
56
52
  def error?
57
- @canceled.size > 0
53
+ !@canceled.empty?
58
54
  end
59
55
 
60
56
  # Check if a runnable has been performed or canceled.
@@ -63,13 +59,9 @@ module Diggit
63
59
  # @return [Boolean]
64
60
  def has?(runnable_or_string, state = :all)
65
61
  name = retrieve_name(runnable_or_string)
66
- if state == :performed
67
- return @performed.count { |e| e.name == name } > 0
68
- elsif state == :canceled
69
- return @canceled.count { |e| e.name == name } > 0
70
- elsif state == :all
71
- return (@performed + @canceled).count { |e| e.name == name } > 0
72
- end
62
+ return @performed.count { |e| e.name == name } > 0 if state == :performed
63
+ return @canceled.count { |e| e.name == name } > 0 if state == :canceled
64
+ return (@performed + @canceled).count { |e| e.name == name } > 0 if state == :all
73
65
  end
74
66
 
75
67
  # Remove a runnable from all the entries.
@@ -84,11 +76,8 @@ module Diggit
84
76
  private
85
77
 
86
78
  def retrieve_name(runnable_or_string)
87
- if runnable_or_string.is_a? String
88
- return runnable_or_string
89
- else
90
- return runnable_or_string.name
91
- end
79
+ return runnable_or_string if runnable_or_string.is_a? String
80
+ runnable_or_string.name
92
81
  end
93
82
  end
94
83
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: utf-8
2
3
  #
3
4
  # This file is part of Diggit.
@@ -18,5 +19,5 @@
18
19
  # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
20
 
20
21
  module Diggit
21
- VERSION = '2.1.0'
22
+ VERSION = '2.1.1'.freeze
22
23
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: utf-8
2
3
  #
3
4
  # This file is part of Diggit.
@@ -25,8 +26,8 @@ require 'mongo'
25
26
  # @!attribute [r] db
26
27
  # @return [Mongo::DB] the mongo database object.
27
28
  class Db < Diggit::Addon
28
- DEFAULT_SERVER = '127.0.0.1:27017'
29
- DEFAULT_DB = 'diggit'
29
+ DEFAULT_SERVER = '127.0.0.1:27017'.freeze
30
+ DEFAULT_DB = 'diggit'.freeze
30
31
 
31
32
  attr_reader :client
32
33
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: utf-8
2
3
  #
3
4
  # This file is part of Diggit.
@@ -17,7 +18,7 @@
17
18
  #
18
19
  # Copyright 2015 Jean-Rémy Falleri <jr.falleri@gmail.com>
19
20
 
20
- # A output addon for Diggit. The name of the addon is :output, and can be reached in the
21
+ # An output addon for Diggit. The name of the addon is :output, and can be reached in the
21
22
  # addons hash. This addon might use an :output hash in the global options. In this hash, the
22
23
  # :out key allows to configure the name of the output folder and :tmp the name of the temporary output
23
24
  # folder.
@@ -28,8 +29,8 @@
28
29
  class Out < Diggit::Addon
29
30
  attr_reader :out, :tmp
30
31
 
31
- DEFAULT_OUT = 'out'
32
- DEFAULT_TMP = 'tmp'
32
+ DEFAULT_OUT = 'out'.freeze
33
+ DEFAULT_TMP = 'tmp'.freeze
33
34
 
34
35
  def initialize(*args)
35
36
  super
@@ -45,4 +46,25 @@ class Out < Diggit::Addon
45
46
  FileUtils.mkdir_p(@out) unless File.exist?(@out)
46
47
  FileUtils.mkdir_p(@tmp) unless File.exist?(@tmp)
47
48
  end
49
+
50
+ # Get an output path for a file/directory.
51
+ # @param paths [Array<String>] the different folders of the path.
52
+ # @return [String] the absolute path.
53
+ def out_path(*paths)
54
+ File.join(@out, *paths)
55
+ end
56
+
57
+ # Get a temporary path for a file/directory.
58
+ # @param paths [Array<String>] the different folders of the path.
59
+ # @return [String] the absolute path.
60
+ def tmp_path(*paths)
61
+ File.join(@tmp, *paths)
62
+ end
63
+
64
+ # Clean the output and temporary folders.
65
+ # @return [void]
66
+ def clean
67
+ FileUtils.rm_rf(@out)
68
+ FileUtils.rm_rf(@tmp)
69
+ end
48
70
  end