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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +12 -4
- data/Rakefile +1 -0
- data/lib/tfs_graph.rb +1 -2
- data/lib/tfs_graph/abstract_store.rb +23 -0
- data/lib/tfs_graph/associators/branch_associator.rb +1 -1
- data/lib/tfs_graph/associators/changeset_tree_builder.rb +29 -0
- data/lib/tfs_graph/behaviors.rb +9 -0
- data/lib/tfs_graph/behaviors/neo4j_repository/branch.rb +39 -0
- data/lib/tfs_graph/behaviors/neo4j_repository/changeset.rb +12 -0
- data/lib/tfs_graph/behaviors/neo4j_repository/project.rb +89 -0
- data/lib/tfs_graph/behaviors/related_repository/branch.rb +26 -0
- data/lib/tfs_graph/behaviors/related_repository/changeset.rb +8 -0
- data/lib/tfs_graph/behaviors/related_repository/project.rb +48 -0
- data/lib/tfs_graph/branch.rb +84 -37
- data/lib/tfs_graph/branch/branch_archive_handler.rb +10 -6
- data/lib/tfs_graph/branch/branch_store.rb +13 -26
- data/lib/tfs_graph/changeset.rb +46 -25
- data/lib/tfs_graph/changeset/changeset_normalizer.rb +1 -0
- data/lib/tfs_graph/changeset/changeset_store.rb +13 -36
- data/lib/tfs_graph/changeset_merge.rb +20 -18
- data/lib/tfs_graph/changeset_merge/changeset_merge_store.rb +13 -10
- data/lib/tfs_graph/config.rb +12 -4
- data/lib/tfs_graph/entity.rb +34 -6
- data/lib/tfs_graph/extensions.rb +27 -0
- data/lib/tfs_graph/graph_populator.rb +9 -1
- data/lib/tfs_graph/persistable_entity.rb +60 -0
- data/lib/tfs_graph/populators/everything.rb +16 -4
- data/lib/tfs_graph/populators/for_archived_branch.rb +28 -0
- data/lib/tfs_graph/populators/for_branch.rb +35 -0
- data/lib/tfs_graph/populators/for_project.rb +22 -5
- data/lib/tfs_graph/populators/since_date.rb +21 -5
- data/lib/tfs_graph/populators/since_last.rb +22 -10
- data/lib/tfs_graph/populators/utilities.rb +4 -19
- data/lib/tfs_graph/project.rb +49 -13
- data/lib/tfs_graph/project/project_store.rb +13 -22
- data/lib/tfs_graph/repository.rb +78 -0
- data/lib/tfs_graph/repository/neo4j_repository.rb +97 -0
- data/lib/tfs_graph/repository/related_repository.rb +89 -0
- data/lib/tfs_graph/repository_registry.rb +60 -0
- data/lib/tfs_graph/server_registry.rb +45 -0
- data/lib/tfs_graph/store_helpers.rb +4 -5
- data/lib/tfs_graph/version.rb +1 -1
- data/schema.cypher +7 -0
- data/spec/branch_spec.rb +120 -0
- data/spec/neo4j_repository_integration_spec.rb +346 -0
- data/spec/persistable_entity_spec.rb +91 -0
- data/spec/project_spec.rb +29 -0
- data/spec/related_repository_integration_spec.rb +328 -0
- data/spec/repository_registry_spec.rb +48 -0
- data/spec/repository_spec.rb +73 -0
- data/spec/server_registery_spec.rb +36 -0
- data/spec/spec_helper.rb +12 -24
- data/tfs_graph.gemspec +3 -2
- metadata +67 -21
- data/lib/tfs_graph/associators/changeset_tree_creator.rb +0 -19
- data/spec/factories.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3024420a800c31fc3676483f1bbd658dda5c22d0
|
4
|
+
data.tar.gz: 527426b7e59e38f884db6876c264d655b11836a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43141894fdff22dd10f8a25864af7cf41875dc611320c7671cfc91a2d60c02ae4a0e2e4a11a7f13044e3f3aee5c713e6be32d1b44c71b8a8099407512380e47e
|
7
|
+
data.tar.gz: a70fad3373c4ac4bddd91e0cfe722abe255f73f90dd6eaf75e150d5cb09e08cc80a69a5fc3c92cc9e35c3f006bf92d29a9e6174219e6505e838d926450ca1455
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.1.0
|
data/Gemfile
CHANGED
@@ -3,17 +3,25 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in tfs_graph.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem "related", git: "https://github.com/plukevdh/related.git", branch: "preserve_external_ids"
|
7
|
-
|
8
6
|
group :test do
|
9
7
|
gem 'rspec'
|
10
8
|
gem 'rspec-given'
|
9
|
+
gem 'flexmock'
|
11
10
|
gem 'webmock'
|
12
11
|
gem 'vcr'
|
13
|
-
gem 'factory_girl'
|
14
12
|
end
|
15
13
|
|
16
14
|
group :test, :development do
|
17
15
|
gem "pry"
|
18
16
|
gem 'benchmark-ips'
|
19
|
-
|
17
|
+
gem "related", git: "https://github.com/plukevdh/related.git", branch: "namespace_fix"
|
18
|
+
gem 'timecop'
|
19
|
+
|
20
|
+
gem 'neo4j-core', git: "https://github.com/plukevdh/neo4j-core.git"
|
21
|
+
|
22
|
+
platforms :jruby do
|
23
|
+
gem 'neo4j-community'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
gem 'simplecov', :require => false, :group => :test
|
data/Rakefile
CHANGED
data/lib/tfs_graph.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tfs_graph/tfs_client'
|
2
|
+
require 'tfs_graph/tfs_helpers'
|
3
|
+
require 'tfs_graph/store_helpers'
|
4
|
+
|
5
|
+
module TFSGraph
|
6
|
+
class AbstractStore
|
7
|
+
include TFSClient
|
8
|
+
include TFSHelpers
|
9
|
+
include StoreHelpers
|
10
|
+
|
11
|
+
def fetch_and_cache
|
12
|
+
cache_all fetch_all
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch_all
|
16
|
+
normalize root_query.run
|
17
|
+
end
|
18
|
+
|
19
|
+
def cache_all(attr_set)
|
20
|
+
attr_set.map {|attrs| cache(attrs) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module TFSGraph
|
2
|
+
class ChangesetTreeBuilder
|
3
|
+
class << self
|
4
|
+
def to_tree(branch, changesets)
|
5
|
+
changesets.map.with_index do |changeset, i|
|
6
|
+
parent = (i == 0) ? branch : changesets[i-1]
|
7
|
+
|
8
|
+
if parent.is_a? TFSGraph::Changeset
|
9
|
+
changeset.parent = parent.id
|
10
|
+
changeset.save!
|
11
|
+
end
|
12
|
+
|
13
|
+
parent.add_child changeset
|
14
|
+
changeset
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_branch_merges(changesets)
|
19
|
+
changesets.each do |cs|
|
20
|
+
from = cs.merges.max
|
21
|
+
next unless from
|
22
|
+
|
23
|
+
cs.merge_parent = from.id
|
24
|
+
cs.save!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module TFSGraph
|
2
|
+
class Behaviors
|
3
|
+
class Neo4jRepository
|
4
|
+
module Branch
|
5
|
+
def find_in_project(project, path)
|
6
|
+
# project.branches.detect {|b| b.path == path }
|
7
|
+
rebuild Neo4j::Label.query(:branch, conditions: {path: path, project: project.name }).first
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_by_path(path)
|
11
|
+
branch = Neo4j::Label.query(:branch, conditions: {path: path}).first
|
12
|
+
raise TFSGraph::Repository::NotFound, "No branch found for #{path}" if branch.nil?
|
13
|
+
|
14
|
+
rebuild branch
|
15
|
+
end
|
16
|
+
|
17
|
+
def absolute_root_for(branch)
|
18
|
+
root = branch
|
19
|
+
proj = project_for_branch branch
|
20
|
+
|
21
|
+
until(root.master?) do
|
22
|
+
root = proj.branches.detect {|b| b.path == root.root }
|
23
|
+
end
|
24
|
+
|
25
|
+
root
|
26
|
+
end
|
27
|
+
|
28
|
+
def project_for_branch(branch)
|
29
|
+
RepositoryRegistry.instance.project_repository.find_by_name branch.project
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def fetch_existing_record(obj)
|
34
|
+
find_by_path(obj.path).db_object
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module TFSGraph
|
2
|
+
class Behaviors
|
3
|
+
class Neo4jRepository
|
4
|
+
module Project
|
5
|
+
ROOT_BRANCH_QUERY = "MATCH (p:project {name: {project}})-[:branches]->(b:branch) WHERE (b.original_path = {path} OR b.root = {path})"
|
6
|
+
ACTIVITY_QUERY = "MATCH (a:project)-[:branches]->(b:branch)-[:changesets]->(c:changeset) where a.name = {name}"
|
7
|
+
|
8
|
+
def create(args)
|
9
|
+
obj = super
|
10
|
+
relate :projects, root, obj.db_object
|
11
|
+
|
12
|
+
obj
|
13
|
+
end
|
14
|
+
|
15
|
+
def all
|
16
|
+
get_nodes(root, :outgoing, :projects, TFSGraph::Project)
|
17
|
+
end
|
18
|
+
|
19
|
+
def active
|
20
|
+
projects = session.query "MATCH (p:project {hidden: 'false'}) RETURN p as `project`, ID(p) as `neo_id`"
|
21
|
+
rebuild_for_type self, projects, :project
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_by_name(name)
|
25
|
+
project = Neo4j::Label.query(:project, conditions: {name: name}).first
|
26
|
+
raise TFSGraph::Repository::NotFound, "No project found for #{name}" if project.nil?
|
27
|
+
|
28
|
+
rebuild project
|
29
|
+
end
|
30
|
+
|
31
|
+
def root_branches(project)
|
32
|
+
roots = session.query "MATCH (p:project {name: {project}})-[:branches]->(b:branch {hidden: 'false', archived: 'false'}) where not has(b.root) RETURN b AS `branch`, ID(b) AS `neo_id`",
|
33
|
+
project: project.name
|
34
|
+
|
35
|
+
rebuild_for_type RepositoryRegistry.branch_repository, roots, :branch
|
36
|
+
end
|
37
|
+
|
38
|
+
def branches_for_root(project, branch)
|
39
|
+
branches = session.query "#{ROOT_BRANCH_QUERY} RETURN b as `branch`, ID(b) as `neo_id`",
|
40
|
+
project: project.name,
|
41
|
+
path: branch.path
|
42
|
+
|
43
|
+
rebuild_for_type RepositoryRegistry.branch_repository, branches, :branch
|
44
|
+
end
|
45
|
+
|
46
|
+
def active_branches_for_root(project, branch)
|
47
|
+
branches = session.query "#{ROOT_BRANCH_QUERY} AND b.archived = 'false' AND b.hidden = 'false' RETURN b as `branch`, ID(b) as `neo_id`",
|
48
|
+
project: project.name,
|
49
|
+
path: branch.path
|
50
|
+
|
51
|
+
rebuild_for_type RepositoryRegistry.branch_repository, branches, :branch
|
52
|
+
end
|
53
|
+
|
54
|
+
def changesets_for_root(project, branch)
|
55
|
+
changesets = session.query "#{ROOT_BRANCH_QUERY} MATCH b-[:changesets]->(c:changeset) RETURN c AS `changeset`, ID(b) as `neo_id` ORDER BY c.id",
|
56
|
+
project: project.name,
|
57
|
+
path: branch.path
|
58
|
+
|
59
|
+
rebuild_for_type RepositoryRegistry.changeset_repository, changesets, :changeset
|
60
|
+
end
|
61
|
+
|
62
|
+
def activity(project)
|
63
|
+
changesets = session.query "#{ACTIVITY_QUERY} RETURN c as `changeset`, ID(b) as `neo_id`",
|
64
|
+
name: project.name
|
65
|
+
|
66
|
+
rebuild_for_type RepositoryRegistry.changeset_repository, changesets, :changeset
|
67
|
+
end
|
68
|
+
|
69
|
+
def activity_by_date(project, time)
|
70
|
+
changesets = session.query "#{ACTIVITY_QUERY} AND c.created >= {time} RETURN c as `changeset`, ID(b) as `neo_id`",
|
71
|
+
{ name: project.name, time: time.utc.to_i }
|
72
|
+
|
73
|
+
rebuild_for_type RepositoryRegistry.changeset_repository, changesets, :changeset
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def rebuild_for_type(repo, data, key)
|
78
|
+
data.each_slice(2).map do |data,id|
|
79
|
+
repo.rebuild_from_query data[key]['data'], id[:neo_id]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def fetch_existing_record(obj)
|
84
|
+
find_by_name(obj.name).db_object
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module TFSGraph
|
2
|
+
class Behaviors
|
3
|
+
class RelatedRepository
|
4
|
+
module Branch
|
5
|
+
def find_in_project(project, path)
|
6
|
+
project.branches.detect {|b| b.path == path }
|
7
|
+
end
|
8
|
+
|
9
|
+
def absolute_root_for(branch)
|
10
|
+
root = branch
|
11
|
+
proj = project_for_branch branch
|
12
|
+
|
13
|
+
until(root.master?) do
|
14
|
+
root = proj.branches.detect {|b| b.path == root.root }
|
15
|
+
end
|
16
|
+
|
17
|
+
root
|
18
|
+
end
|
19
|
+
|
20
|
+
def project_for_branch(branch)
|
21
|
+
RepositoryRegistry.instance.project_repository.find_by_name branch.project
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module TFSGraph
|
2
|
+
class Behaviors
|
3
|
+
class RelatedRepository
|
4
|
+
module Project
|
5
|
+
def create(args)
|
6
|
+
obj = super
|
7
|
+
relate :projects, root, obj.db_object
|
8
|
+
|
9
|
+
obj
|
10
|
+
end
|
11
|
+
|
12
|
+
def all
|
13
|
+
get_nodes(root, :outgoing, :projects, TFSGraph::Project)
|
14
|
+
end
|
15
|
+
|
16
|
+
def active
|
17
|
+
all.reject &:hidden?
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_by_name(name)
|
21
|
+
project = all.detect {|p| p.name == name }
|
22
|
+
raise TFSGraph::Repository::NotFound, "No project found for #{name}" if project.nil?
|
23
|
+
|
24
|
+
project
|
25
|
+
end
|
26
|
+
|
27
|
+
def branches_for_root(project, root)
|
28
|
+
project.branches.select {|b| b.root == branch.path || b.original_path == branch.path}
|
29
|
+
end
|
30
|
+
|
31
|
+
def changesets_for_root(project, root)
|
32
|
+
branches_for_root(project, root).map(&:changesets).flatten.sort
|
33
|
+
end
|
34
|
+
|
35
|
+
def activity(project)
|
36
|
+
project.branches.map {|b| b.changesets }.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
def activity_by_date(project, date)
|
40
|
+
activity = activity(project)
|
41
|
+
activity = activity.select {|c| c.created > date } unless date.nil?
|
42
|
+
|
43
|
+
activity
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/tfs_graph/branch.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require 'tfs_graph/
|
1
|
+
require 'tfs_graph/persistable_entity'
|
2
2
|
require 'tfs_graph/tfs_helpers'
|
3
3
|
|
4
4
|
module TFSGraph
|
5
|
-
class Branch <
|
5
|
+
class Branch < PersistableEntity
|
6
6
|
extend TFSHelpers
|
7
|
-
extend Comparable
|
8
7
|
|
9
8
|
SCHEMA = {
|
10
9
|
original_path: {key: "Path", type: String},
|
@@ -12,10 +11,11 @@ module TFSGraph
|
|
12
11
|
project: {converter: ->(path) { branch_project(path) }, key: "Path", type: String},
|
13
12
|
name: {converter: ->(path) { branch_path_to_name(path) }, key: "Path", type: String},
|
14
13
|
root: {converter: ->(path) { repath_archive(server_path_to_odata_path(path)) if path }, key: "ParentBranch", type: String},
|
15
|
-
created: {key: "DateCreated", type:
|
14
|
+
created: {key: "DateCreated", type: Time},
|
16
15
|
type: {default: "Feature", type: Integer},
|
17
16
|
archived: {default: false, type: String},
|
18
|
-
hidden: {default: false, type: String}
|
17
|
+
hidden: {default: false, type: String},
|
18
|
+
last_updated: {type: Time, default: Time.at(0).utc}
|
19
19
|
}
|
20
20
|
|
21
21
|
BRANCH_TYPES = [
|
@@ -29,7 +29,12 @@ module TFSGraph
|
|
29
29
|
|
30
30
|
act_as_entity
|
31
31
|
|
32
|
-
|
32
|
+
def initialize(repo, args)
|
33
|
+
super
|
34
|
+
|
35
|
+
detect_type
|
36
|
+
detect_archived
|
37
|
+
end
|
33
38
|
|
34
39
|
BRANCH_TYPES.each do |t|
|
35
40
|
define_method "#{t}?".to_sym do
|
@@ -37,6 +42,14 @@ module TFSGraph
|
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
45
|
+
def archived
|
46
|
+
@archived.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def hidden
|
50
|
+
@hidden.to_s
|
51
|
+
end
|
52
|
+
|
40
53
|
def archived?
|
41
54
|
archived.to_s == "true"
|
42
55
|
end
|
@@ -45,40 +58,40 @@ module TFSGraph
|
|
45
58
|
hidden.to_s == "true"
|
46
59
|
end
|
47
60
|
|
61
|
+
def active?
|
62
|
+
!hidden? && !archived?
|
63
|
+
end
|
64
|
+
|
48
65
|
def named_type
|
49
66
|
BRANCH_TYPES[type]
|
50
67
|
end
|
51
68
|
|
69
|
+
def updated!
|
70
|
+
@last_updated = Time.now.utc
|
71
|
+
save!
|
72
|
+
end
|
73
|
+
|
74
|
+
def updated_since?(date)
|
75
|
+
@last_updated > date
|
76
|
+
end
|
77
|
+
|
52
78
|
def hide!
|
53
79
|
self.hidden = true
|
54
|
-
save
|
80
|
+
save!
|
55
81
|
end
|
56
82
|
|
57
83
|
def archive!
|
58
84
|
self.archived = true
|
59
|
-
save
|
85
|
+
save!
|
60
86
|
end
|
61
87
|
|
62
88
|
def rootless?
|
63
89
|
!master? && root.empty?
|
64
90
|
end
|
65
91
|
|
66
|
-
def type_index(name)
|
67
|
-
BRANCH_TYPES.index(name.to_sym)
|
68
|
-
end
|
69
|
-
|
70
92
|
# returns a branch
|
71
93
|
def absolute_root
|
72
|
-
@absolute_root ||=
|
73
|
-
item = self
|
74
|
-
proj = ProjectStore.find_cached project
|
75
|
-
|
76
|
-
until(item.master?) do
|
77
|
-
item = proj.branches.detect {|branch| branch.path == item.root }
|
78
|
-
end
|
79
|
-
|
80
|
-
item
|
81
|
-
end
|
94
|
+
@absolute_root ||= @repo.absolute_root_for(self)
|
82
95
|
end
|
83
96
|
|
84
97
|
def branch?
|
@@ -87,11 +100,27 @@ module TFSGraph
|
|
87
100
|
|
88
101
|
# branches this one touches or is touched
|
89
102
|
def related_branches
|
90
|
-
|
103
|
+
@repo.get_nodes(db_object, :incoming, :related, Branch).map &:id
|
104
|
+
end
|
105
|
+
|
106
|
+
def merged_changesets
|
107
|
+
@repo.get_nodes(db_object, :outgoing, :included, Changeset)
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_changeset(changeset)
|
111
|
+
# attach branch path
|
112
|
+
changeset.branch_path = self.path
|
113
|
+
changeset.save!
|
114
|
+
|
115
|
+
@repo.relate(:changesets, self.db_object, changeset.db_object)
|
116
|
+
end
|
117
|
+
|
118
|
+
def add_child(changeset)
|
119
|
+
@repo.relate(:child, self.db_object, changeset.db_object)
|
91
120
|
end
|
92
121
|
|
93
122
|
def changesets
|
94
|
-
|
123
|
+
@repo.get_nodes(db_object, :outgoing, :changesets, Changeset)
|
95
124
|
end
|
96
125
|
|
97
126
|
def contributors
|
@@ -99,7 +128,7 @@ module TFSGraph
|
|
99
128
|
end
|
100
129
|
|
101
130
|
def root_changeset
|
102
|
-
@root
|
131
|
+
@root = @repo.get_nodes(db_object, :outgoing, :child, Changeset).first if (@root.nil? || @root.empty?)
|
103
132
|
end
|
104
133
|
|
105
134
|
def last_changeset
|
@@ -108,20 +137,30 @@ module TFSGraph
|
|
108
137
|
|
109
138
|
def ahead_of_master
|
110
139
|
return 0 unless absolute_root
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
140
|
+
my_changes = changesets
|
141
|
+
root_changes = absolute_root.merged_changesets
|
142
|
+
|
143
|
+
# get intersection between root and this branch
|
144
|
+
intersect = root_changes & my_changes
|
145
|
+
# get difference of intersect with my changes
|
146
|
+
diff = my_changes - intersect
|
147
|
+
|
148
|
+
diff.count
|
115
149
|
end
|
116
150
|
|
117
151
|
# gets the set of changesets that exist in both root and self
|
118
152
|
# then gets a diff of that set and the root.
|
119
153
|
def behind_master
|
120
154
|
return 0 unless absolute_root
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
155
|
+
my_changes = merged_changesets
|
156
|
+
root_changes = absolute_root.changesets
|
157
|
+
|
158
|
+
# get intersect between my changes and the root
|
159
|
+
intersect = my_changes & root_changes
|
160
|
+
# get diff of root changes to intersect
|
161
|
+
diff = root_changes - intersect
|
162
|
+
|
163
|
+
diff.count
|
125
164
|
end
|
126
165
|
|
127
166
|
def <=>(other)
|
@@ -129,20 +168,28 @@ module TFSGraph
|
|
129
168
|
end
|
130
169
|
|
131
170
|
def as_json(options={})
|
132
|
-
|
133
|
-
|
171
|
+
results = super
|
172
|
+
results[:related_branches] = related_branches
|
173
|
+
results[:id] = id
|
174
|
+
|
175
|
+
results
|
176
|
+
end
|
177
|
+
|
178
|
+
def type_index(name)
|
179
|
+
BRANCH_TYPES.index(name.to_sym)
|
134
180
|
end
|
135
181
|
|
136
182
|
private
|
183
|
+
|
137
184
|
def detect_type
|
138
|
-
return self.type = type_index(:master) if (root.empty?)
|
185
|
+
return self.type = type_index(:master) if (root.nil? || root.empty?)
|
139
186
|
return self.type = type_index(:release) if !(name =~ RELEASE_MATCHER).nil?
|
140
187
|
self.type = type_index(:feature)
|
141
188
|
nil
|
142
189
|
end
|
143
190
|
|
144
191
|
def detect_archived
|
145
|
-
self.archived = ARCHIVED_FLAGS.any? {|flag| original_path.include?
|
192
|
+
self.archived = ARCHIVED_FLAGS.any? {|flag| original_path && original_path.include?(flag) }
|
146
193
|
nil
|
147
194
|
end
|
148
195
|
|