tfs_graph 0.1.1 → 0.1.2

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +12 -4
  4. data/Rakefile +1 -0
  5. data/lib/tfs_graph.rb +1 -2
  6. data/lib/tfs_graph/abstract_store.rb +23 -0
  7. data/lib/tfs_graph/associators/branch_associator.rb +1 -1
  8. data/lib/tfs_graph/associators/changeset_tree_builder.rb +29 -0
  9. data/lib/tfs_graph/behaviors.rb +9 -0
  10. data/lib/tfs_graph/behaviors/neo4j_repository/branch.rb +39 -0
  11. data/lib/tfs_graph/behaviors/neo4j_repository/changeset.rb +12 -0
  12. data/lib/tfs_graph/behaviors/neo4j_repository/project.rb +89 -0
  13. data/lib/tfs_graph/behaviors/related_repository/branch.rb +26 -0
  14. data/lib/tfs_graph/behaviors/related_repository/changeset.rb +8 -0
  15. data/lib/tfs_graph/behaviors/related_repository/project.rb +48 -0
  16. data/lib/tfs_graph/branch.rb +84 -37
  17. data/lib/tfs_graph/branch/branch_archive_handler.rb +10 -6
  18. data/lib/tfs_graph/branch/branch_store.rb +13 -26
  19. data/lib/tfs_graph/changeset.rb +46 -25
  20. data/lib/tfs_graph/changeset/changeset_normalizer.rb +1 -0
  21. data/lib/tfs_graph/changeset/changeset_store.rb +13 -36
  22. data/lib/tfs_graph/changeset_merge.rb +20 -18
  23. data/lib/tfs_graph/changeset_merge/changeset_merge_store.rb +13 -10
  24. data/lib/tfs_graph/config.rb +12 -4
  25. data/lib/tfs_graph/entity.rb +34 -6
  26. data/lib/tfs_graph/extensions.rb +27 -0
  27. data/lib/tfs_graph/graph_populator.rb +9 -1
  28. data/lib/tfs_graph/persistable_entity.rb +60 -0
  29. data/lib/tfs_graph/populators/everything.rb +16 -4
  30. data/lib/tfs_graph/populators/for_archived_branch.rb +28 -0
  31. data/lib/tfs_graph/populators/for_branch.rb +35 -0
  32. data/lib/tfs_graph/populators/for_project.rb +22 -5
  33. data/lib/tfs_graph/populators/since_date.rb +21 -5
  34. data/lib/tfs_graph/populators/since_last.rb +22 -10
  35. data/lib/tfs_graph/populators/utilities.rb +4 -19
  36. data/lib/tfs_graph/project.rb +49 -13
  37. data/lib/tfs_graph/project/project_store.rb +13 -22
  38. data/lib/tfs_graph/repository.rb +78 -0
  39. data/lib/tfs_graph/repository/neo4j_repository.rb +97 -0
  40. data/lib/tfs_graph/repository/related_repository.rb +89 -0
  41. data/lib/tfs_graph/repository_registry.rb +60 -0
  42. data/lib/tfs_graph/server_registry.rb +45 -0
  43. data/lib/tfs_graph/store_helpers.rb +4 -5
  44. data/lib/tfs_graph/version.rb +1 -1
  45. data/schema.cypher +7 -0
  46. data/spec/branch_spec.rb +120 -0
  47. data/spec/neo4j_repository_integration_spec.rb +346 -0
  48. data/spec/persistable_entity_spec.rb +91 -0
  49. data/spec/project_spec.rb +29 -0
  50. data/spec/related_repository_integration_spec.rb +328 -0
  51. data/spec/repository_registry_spec.rb +48 -0
  52. data/spec/repository_spec.rb +73 -0
  53. data/spec/server_registery_spec.rb +36 -0
  54. data/spec/spec_helper.rb +12 -24
  55. data/tfs_graph.gemspec +3 -2
  56. metadata +67 -21
  57. data/lib/tfs_graph/associators/changeset_tree_creator.rb +0 -19
  58. data/spec/factories.rb +0 -20
@@ -7,16 +7,20 @@ module TFSGraph
7
7
  # is fairly useless, we'll hide it in favor of the "ghost" branch.
8
8
  class << self
9
9
  def hide_all_archives
10
- ProjectStore.all_cached.map {|project| hide_moved_archives_for_project(project) }
10
+ RepositoryRegistry.project_repository.all.map {|project| hide_moved_archives_for_project(project) }
11
11
  end
12
12
 
13
13
  def hide_moved_archives_for_project(project)
14
- archived = project.branches.group_by(&:path).select {|_, group| group.size > 1 }
15
- archived.each do |path, group|
16
- group.select(&:archived?).each(&:hide!)
17
- group.reject(&:archived?).each(&:archive!)
14
+ project.branches.group_by(&:path).map do |path, group|
15
+ next unless group.size > 1
16
+
17
+ group.each do |branch|
18
+ branch.hide! if branch.archived?
19
+ branch.archive! unless branch.archived?
20
+ end
21
+
22
+ group
18
23
  end
19
- archived
20
24
  end
21
25
  end
22
26
  end
@@ -1,53 +1,40 @@
1
- require 'tfs_graph/tfs_client'
2
- require 'tfs_graph/tfs_helpers'
3
- require 'tfs_graph/store_helpers'
1
+ require 'tfs_graph/abstract_store'
4
2
 
5
3
  require 'tfs_graph/branch/branch_normalizer'
6
4
  require 'tfs_graph/branch'
7
5
 
8
6
  module TFSGraph
9
- class BranchStore
10
- include TFSClient
11
- include TFSHelpers
12
- include StoreHelpers
13
-
7
+ class BranchStore < AbstractStore
14
8
  LIMIT = 1000
15
9
 
16
10
  def initialize(project)
17
11
  @project = project
18
12
  end
19
13
 
20
- def cache_all
21
- persist(all)
14
+ def fetch_since_last_update
15
+ fetch_since_date(@project.last_updated.iso8601)
22
16
  end
23
17
 
24
- def cache_since_last_update
25
- persist since_last_update
18
+ def fetch_since_date(date)
19
+ normalize root_query.where("DateCreated gt DateTime'#{date}'").run
26
20
  end
27
21
 
28
- def all
29
- normalize root_query.run
30
- end
22
+ def cache(attrs)
23
+ branch = RepositoryRegistry.branch_repository.build attrs
24
+
25
+ # add_branch action runs save! on branch
26
+ @project.add_branch(branch)
31
27
 
32
- def since_last_update
33
- normalize root_query.where("DateCreated gt DateTime'#{last_updated_on.iso8601}'").run
28
+ branch
34
29
  end
35
30
 
36
31
  private
37
32
  def root_query
38
- tfs.projects(@project.name).branches.limit(LIMIT)
33
+ tfs.projects(@project.name).branches.order_by('DateCreated desc').limit(LIMIT)
39
34
  end
40
35
 
41
36
  def normalize(branches)
42
37
  BranchNormalizer.normalize_many branches
43
38
  end
44
-
45
- def persist(branches)
46
- branches.map do |branch_attrs|
47
- branch = Branch.create branch_attrs
48
- Related::Relationship.create(:branches, @project, branch)
49
- branch
50
- end
51
- end
52
39
  end
53
40
  end
@@ -1,21 +1,20 @@
1
- require 'tfs_graph/entity'
1
+ require 'tfs_graph/persistable_entity'
2
2
  require 'tfs_graph/tfs_helpers'
3
3
 
4
4
  # FIXME: DRY along side the Branch class
5
5
  module TFSGraph
6
- class Changeset < Entity
6
+ class Changeset < PersistableEntity
7
7
  extend TFSHelpers
8
- extend Comparable
9
8
 
10
9
  SCHEMA = {
11
10
  comment: {key: "Comment", type: String},
12
11
  committer: {key: "Committer", converter: ->(name) { base_username(name) }, type: String},
13
- created: {key: "CreationDate", type: DateTime},
12
+ created: {key: "CreationDate", type: Time},
14
13
  id: {key: "Id", type: Integer},
15
14
  branch_path: {type: String, default: nil},
16
- tags: {type: Array, default: []},
17
- parent: {type: Integer, default: nil},
18
- merge_parent: {type: Integer, default: nil}
15
+ # tags: {type: Array, default: []},
16
+ parent: {type: Integer, default: 0},
17
+ merge_parent: {type: Integer, default: 0}
19
18
  }
20
19
 
21
20
  act_as_entity
@@ -24,14 +23,45 @@ module TFSGraph
24
23
  id <=> other.id
25
24
  end
26
25
 
26
+ # override for the & (intersect) operator
27
+ def eql?(other)
28
+ other.is_a?(self.class) && other == self
29
+ end
30
+
31
+ def hash
32
+ @internal_id.hash
33
+ end
34
+
35
+ def id
36
+ @id.to_i unless @id.nil?
37
+ end
38
+
39
+ def merge?
40
+ !base? && @merge_parent != 0
41
+ end
42
+
43
+ def base?
44
+ @parent == 0 || @parent == @merge_parent
45
+ end
46
+
47
+ def created
48
+ return nil unless @created
49
+ return @created unless @created.is_a? String
50
+ @created = Time.parse @created
51
+ end
52
+
53
+ def add_child(changeset)
54
+ @repo.relate(:child, self.db_object, changeset.db_object)
55
+ end
56
+
27
57
  def next
28
- child = outgoing(:child).options(model: self.class).nodes.to_a.first
58
+ child = @repo.get_nodes(db_object, :outgoing, :child, self.class).first
29
59
  raise StopIteration unless child
30
60
  child
31
61
  end
32
62
 
33
63
  def branch
34
- incoming(:changesets).options(model: Branch).nodes.to_a.first
64
+ @repo.get_nodes(db_object, :incoming, :changesets, Branch).first
35
65
  end
36
66
 
37
67
  def formatted_created
@@ -39,8 +69,9 @@ module TFSGraph
39
69
  end
40
70
 
41
71
  %w(merges merged).each do |type|
72
+ directon = (type == "merges") ? :outgoing : :incoming
42
73
  define_method type do
43
- get_merges_for outgoing(type.to_sym)
74
+ @repo.get_nodes(db_object, directon, :merges, self.class)
44
75
  end
45
76
 
46
77
  define_method "#{type}_ids" do
@@ -49,23 +80,13 @@ module TFSGraph
49
80
  end
50
81
 
51
82
  def as_json(options={})
52
- options.merge! methods: [:merges_ids, :merged_ids]
53
- super
54
- end
83
+ results = super
55
84
 
56
- def set_merging_to
57
- into = merged.max
58
- self.merge_parent = into.id if into
59
- end
60
-
61
- def set_merging_from
62
- from = merges.max
63
- self.merge_parent = from.id if from
64
- end
85
+ [:merges_ids, :merged_ids].each do |key|
86
+ results[key] = self.send key
87
+ end
65
88
 
66
- private
67
- def get_merges_for(merge)
68
- merge.options(model: self.class).nodes.to_a
89
+ results
69
90
  end
70
91
  end
71
92
  end
@@ -10,6 +10,7 @@ module TFSGraph
10
10
  def normalize(item, branch)
11
11
  item = super(item)
12
12
  item[:branch_path] = branch
13
+ item[:comment] = item[:comment].gsub(/\\+/, "|")
13
14
  item
14
15
  end
15
16
 
@@ -1,65 +1,42 @@
1
- require 'tfs_graph/tfs_client'
2
- require 'tfs_graph/store_helpers'
1
+ require 'tfs_graph/abstract_store'
3
2
 
4
3
  require 'tfs_graph/changeset/changeset_normalizer'
5
4
  require 'tfs_graph/changeset'
5
+
6
6
  # Wraps domain knowledge of changeset TFS access
7
7
 
8
8
  module TFSGraph
9
- class ChangesetStore
10
- include TFSClient
11
- include StoreHelpers
12
-
9
+ class ChangesetStore < AbstractStore
13
10
  LIMIT = 10000
14
11
 
15
12
  def initialize(branch)
16
13
  @branch = branch
17
14
  end
18
15
 
19
- def cache_all
20
- persist all
16
+ def fetch_since_last_update
17
+ fetch_since_date(@branch.last_updated.iso8601)
21
18
  end
22
19
 
23
- def cache_since_last_update
24
- persist since_last_update
25
- end
26
-
27
- def cache_since_date(start)
28
- persist since_date(start)
20
+ def fetch_since_date(date)
21
+ normalize root_query.where("CreationDate gt DateTime'#{date}'").run
29
22
  end
30
23
 
31
- def all
32
- normalize root_query.run
33
- end
24
+ def cache(attrs)
25
+ changeset = RepositoryRegistry.changeset_repository.build attrs
34
26
 
35
- def since_date(date)
36
- normalize root_query.where("CreationDate gt DateTime'#{date}'").run
37
- end
27
+ # add_changeset action runs save! on changeset
28
+ @branch.add_changeset changeset
38
29
 
39
- def since_last_update
40
- since_date(last_updated_on.iso8601)
30
+ changeset
41
31
  end
42
32
 
43
33
  private
44
34
  def root_query
45
- tfs.branches(@branch.path).changesets.limit(LIMIT)
35
+ tfs.branches(@branch.path).changesets.order_by("Id asc").limit(LIMIT)
46
36
  end
47
37
 
48
38
  def normalize(changesets)
49
39
  ChangesetNormalizer.normalize_many changesets, @branch.path
50
40
  end
51
-
52
- def persist(changesets)
53
- changesets.map do |attrs|
54
- begin
55
- changeset = Changeset.create attrs
56
- Related::Relationship.create :changesets, @branch, changeset
57
- changeset
58
- rescue Related::ValidationsFailed => ex
59
- # puts ex.message
60
- next
61
- end
62
- end.compact
63
- end
64
41
  end
65
42
  end
@@ -1,4 +1,3 @@
1
- require 'tfs_graph/entity'
2
1
  require 'tfs_graph/changeset'
3
2
 
4
3
  module TFSGraph
@@ -6,8 +5,7 @@ module TFSGraph
6
5
 
7
6
  SCHEMA = {
8
7
  target_version: {key: "TargetVersion", type: Integer},
9
- source_version: {key: "SourceVersion", type: Integer},
10
- branch: {default: nil, type: String}
8
+ source_version: {key: "SourceVersion", type: Integer}
11
9
  }
12
10
 
13
11
  act_as_entity
@@ -18,40 +16,44 @@ module TFSGraph
18
16
  begin
19
17
  merge = new(attrs)
20
18
 
21
- # this will throw an error if one of the relations is not found
22
- # this is the desired condition as it will throw out the merge if there aren't two endpoints found
23
19
  target, source = merge.get_relations
20
+ return nil unless target.persisted? and source.persisted?
24
21
 
25
- Related::Relationship.create :merges, target, source
22
+ merge.join :merges, target, source
26
23
 
27
24
  # relate the branches as well
28
- Related::Relationship.create :related, source.branch, target.branch
25
+ if source.branch && target.branch
26
+ merge.join :related, source.branch, target.branch
29
27
 
30
- Related::Relationship.create :included, source.branch, target
31
- Related::Relationship.create :included, target.branch, source
28
+ merge.join :included, source.branch, target
29
+ merge.join :included, target.branch, source
30
+ end
32
31
 
33
32
  merge
34
- rescue Related::NotFound => ex
33
+ rescue TFSGraph::Repository::NotFound => ex
35
34
  # puts "Could not find a changeset to merge with: #{ex.message}"
36
- rescue Related::ValidationsFailed => ex
37
- # puts "Couldn't create relationship for #{merge.source_version} to #{merge.target_version}"
38
35
  end
39
36
  end
40
37
 
41
- def save
42
- # nothing, no need to save
43
- end
44
-
45
38
  def get_relations
46
39
  return get_target, get_source
47
40
  end
48
41
 
49
42
  def get_source
50
- Changeset.find(source_version)
43
+ repo.find(source_version)
51
44
  end
52
45
 
53
46
  def get_target
54
- Changeset.find(target_version)
47
+ repo.find(target_version)
48
+ end
49
+
50
+ def join(relation, target, source)
51
+ repo.relate(relation, target.db_object, source.db_object)
52
+ end
53
+
54
+ private
55
+ def repo
56
+ @repo ||= RepositoryRegistry.changeset_repository
55
57
  end
56
58
  end
57
59
  end
@@ -1,24 +1,27 @@
1
- require 'tfs_graph/tfs_client'
1
+ require 'tfs_graph/abstract_store'
2
+
2
3
  require 'tfs_graph/changeset_merge/changeset_merge_normalizer'
3
4
  require 'tfs_graph/changeset_merge'
4
5
 
5
6
  module TFSGraph
6
- class ChangesetMergeStore
7
- include TFSClient
8
-
7
+ class ChangesetMergeStore < AbstractStore
9
8
  LIMIT = 10000
10
9
 
11
10
  def initialize(branch)
12
11
  @branch = branch
13
12
  end
14
13
 
15
- def cache
16
- merges = tfs.branches(@branch.path).changesetmerges.limit(LIMIT).run
17
- normalized = ChangesetMergeNormalizer.normalize_many merges, @branch
14
+ def cache(attrs)
15
+ ChangesetMerge.create(attrs)
16
+ end
17
+
18
+ private
19
+ def root_query
20
+ tfs.branches(@branch.path).changesetmerges.limit(LIMIT)
21
+ end
18
22
 
19
- normalized.map do |attrs|
20
- ChangesetMerge.create(attrs)
21
- end.compact
23
+ def normalize(merges)
24
+ ChangesetMergeNormalizer.normalize_many merges, @branch
22
25
  end
23
26
  end
24
27
  end
@@ -1,10 +1,18 @@
1
1
  module TFSGraph
2
2
  class Config
3
- attr_accessor :tfs
4
- attr_reader :redis
3
+ attr_accessor :tfs, :graph
5
4
 
6
- def redis=(server)
7
- @redis = Related.redis = server
5
+ def redis(url: url, namespace: namespace)
6
+ ServerRegistry.register do |r|
7
+ r.redis url: url, namespace: namespace
8
+ end
9
+ end
10
+
11
+ def graph(repo_type: nil)
12
+ raise ArgumentError unless repo_type
13
+ RepositoryRegistry.register do |r|
14
+ r.type repo_type
15
+ end
8
16
  end
9
17
  end
10
18
  end
@@ -1,16 +1,44 @@
1
1
  module TFSGraph
2
- class Entity < Related::Node
2
+ class Entity
3
3
  def self.inherited(klass)
4
4
  define_singleton_method :act_as_entity do
5
- klass::SCHEMA.each do |key, details|
6
- property key, details[:type]
7
- end
5
+ attr_accessor *klass::SCHEMA.keys
8
6
  end
9
7
  end
10
8
 
11
- private
9
+ def initialize(args)
10
+ schema.each do |key, details|
11
+ value = (args[key] || details[:default])
12
+
13
+ value = ressurect_time(value) if details[:type] == Time
14
+
15
+ send "#{key}=", value
16
+ end
17
+ end
18
+
19
+ def to_hash
20
+ hash = {}
21
+ schema.keys.each do |key|
22
+ hash[key] = send key
23
+ end
24
+
25
+ hash.each do |k,v|
26
+ next unless v.is_a? Time
27
+ hash[k] = v.utc.to_i
28
+ end
29
+
30
+ hash
31
+ end
32
+ alias_method :attributes, :to_hash
33
+
12
34
  def schema
13
35
  self.class::SCHEMA
14
36
  end
37
+
38
+ private
39
+ def ressurect_time(time)
40
+ return time if (time.is_a?(Time) || time.nil?)
41
+ Time::at time.to_i
42
+ end
15
43
  end
16
- end
44
+ end