trackington 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 835a6b6162d41dd5040a9a3992a7ee3598ab7426
4
+ data.tar.gz: 828145201ee43eb13a64dedfd2bb7b924fdceb6c
5
+ SHA512:
6
+ metadata.gz: bdfa7f6ca8d9b34bd37c01b6f74d7556062188a457fb7421d1cb0e9aa9be9d3a3db8942ebda2b9a7387417f7c0ba33b5eae85624dd56aee2b1ee423d7564f22d
7
+ data.tar.gz: 7dc50add501044e7e0fbc1c9686a98d99dbf9942d6fee963c4653456d6dcc266835d2780e30f163ece5be26826f2e2519d39edc90ec1d3ca2cf975e0b2546e7b
@@ -0,0 +1,12 @@
1
+ require_relative 'trackington/app/core'
2
+ require_relative 'trackington/app/projects'
3
+ require_relative 'trackington/app/sprints'
4
+ require_relative 'trackington/app/tasks'
5
+ require_relative 'trackington/app/users'
6
+
7
+ require_relative 'trackington/db/models/credential'
8
+ require_relative 'trackington/db/models/project'
9
+ require_relative 'trackington/db/models/project_role'
10
+ require_relative 'trackington/db/models/sprint'
11
+ require_relative 'trackington/db/models/task'
12
+ require_relative 'trackington/db/models/user'
@@ -0,0 +1,33 @@
1
+ require 'active_record'
2
+ require 'yaml'
3
+
4
+ require_relative 'users'
5
+ require_relative 'projects'
6
+
7
+ module Trackington
8
+ class Application
9
+ attr_reader :users, :projects
10
+
11
+ def initialize(connection_config = nil)
12
+ @users = UserRepository.new
13
+ @projects = ProjectRepository.new
14
+
15
+ establish_connection(connection_config)
16
+ end
17
+
18
+ private
19
+
20
+ def establish_connection(config)
21
+ if config.nil?
22
+ config_path = File.expand_path('../../db/config.yml', __FILE__)
23
+ config = YAML.load(IO.read(config_path))
24
+
25
+ env = ENV['DB'] || 'development'
26
+
27
+ ActiveRecord::Base.establish_connection(config[env])
28
+ else
29
+ ActiveRecord::Base.establish_connection(config)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,175 @@
1
+ require_relative 'sprints'
2
+
3
+ module Trackington
4
+ class ProjectRepository
5
+ def create(user_id, project_information)
6
+ project = Models::Project.new(project_information)
7
+ project.save
8
+
9
+ project_role = Models::ProjectRole.new(user_id: user_id,
10
+ project_id: project.id,
11
+ role_type: :owner)
12
+ project_role.save
13
+
14
+ sprint = Models::Sprint.new(project_id: project.id, is_backlog: true)
15
+ sprint.save
16
+
17
+ project.id
18
+ end
19
+
20
+ def get(project_id)
21
+ db_project = Models::Project.find(project_id)
22
+
23
+ Project.new(db_project.id,
24
+ db_project.title,
25
+ db_project.description,
26
+ db_project.public)
27
+ end
28
+
29
+ def all(user_id)
30
+ get_projects(user_id: user_id)
31
+ end
32
+
33
+ def public
34
+ get_projects(public: true)
35
+ end
36
+
37
+ private
38
+
39
+ def get_projects(params)
40
+ project_ids = Models::ProjectRole
41
+ .where(params)
42
+ .select(:project_id)
43
+ .map(&:project_id)
44
+
45
+ Models::Project.find(project_ids).map do |db_project|
46
+ Project.new(db_project.id, db_project.title, db_project.description,
47
+ db_project.public)
48
+ end
49
+ end
50
+ end
51
+
52
+ class Project
53
+ attr_reader :id, :title, :description, :public, :sprints
54
+
55
+ def initialize(id, title, description, public)
56
+ @id = id
57
+ @title = title
58
+ @description = description
59
+ @public = public
60
+ @sprints = SprintRepository.new(@id)
61
+ end
62
+
63
+ def add_user(project_user, user_to_add, type = nil)
64
+ check_user_role(project_user, 'owner')
65
+
66
+ type ||= 'contributor'
67
+
68
+ existing = Models::ProjectRole.where(user_id: user_to_add,
69
+ project_id: @id).first
70
+
71
+ return unless existing.nil?
72
+
73
+ new_role = Models::ProjectRole.new(user_id: user_to_add,
74
+ project_id: @id,
75
+ role_type: type)
76
+
77
+ new_role.save
78
+ end
79
+
80
+ def remove_user(project_user, user_to_remove)
81
+ check_user_role(project_user, 'owner')
82
+
83
+ Models::ProjectRole.destroy_all(project_id: @id,
84
+ user_id: user_to_remove)
85
+
86
+ nil
87
+ end
88
+
89
+ def update_user(project_user, user, new_type)
90
+ check_user_role(project_user, 'owner')
91
+
92
+ role = Models::ProjectRole.where(project_id: @id, user_id: user).first
93
+
94
+ role.role_type = new_type
95
+
96
+ role.save
97
+ end
98
+
99
+ def update(project_user, data)
100
+ check_user_role(project_user, 'owner')
101
+
102
+ @title = data[:title]
103
+ @description = data[:description]
104
+ @public = data[:public]
105
+
106
+ db_project = Models::Project.find(@id)
107
+ db_project.title = @title
108
+ db_project.description = @description
109
+ db_project.public = @public
110
+ db_project.save
111
+ end
112
+
113
+ def current_sprint(project_user)
114
+ check_user_role project_user
115
+
116
+ @sprints.current
117
+ end
118
+
119
+ def create_sprint(project_user, data)
120
+ check_user_role(project_user, 'owner')
121
+
122
+ @sprints.create(data)
123
+ end
124
+
125
+ def start_sprint(project_user)
126
+ check_user_role(project_user, 'owner')
127
+
128
+ @sprints.start_sprint
129
+ end
130
+
131
+ def complete_sprint(project_user)
132
+ check_user_role(project_user, 'owner')
133
+
134
+ @sprints.complete_sprint
135
+ end
136
+
137
+ def backlog(project_user)
138
+ check_user_role project_user
139
+
140
+ @sprints.backlog
141
+ end
142
+
143
+ def user_is?(user_id, type)
144
+ role = Models::ProjectRole.where(project_id: @id, user_id: user_id).first
145
+
146
+ return false if role.nil?
147
+
148
+ return true if role.role_type == 'owner'
149
+
150
+ role.role_type == type
151
+ end
152
+
153
+ def users
154
+ Models::Project.find(@id).project_roles.map do |role|
155
+ ProjectRole.new(role)
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ def check_user_role(user_id, type = 'spectator')
162
+ fail 'User not in role.' unless user_is?(user_id, type)
163
+ end
164
+ end
165
+
166
+ class ProjectRole
167
+ attr_reader :user_id, :user_email, :type
168
+
169
+ def initialize(project_role)
170
+ @user_id = project_role.user_id
171
+ @user_email = project_role.user.email
172
+ @type = project_role.role_type
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,101 @@
1
+ require_relative '../db/models/user'
2
+ require_relative '../db/models/credential'
3
+ require_relative 'tasks'
4
+
5
+ module Trackington
6
+ class SprintRepository
7
+ def initialize(project_id)
8
+ @project_id = project_id
9
+ end
10
+
11
+ def create(data)
12
+ data[:project_id] = @project_id
13
+ sprint = Models::Sprint.new(data)
14
+ sprint.is_active = true if current.nil?
15
+ sprint.save
16
+ end
17
+
18
+ def current
19
+ db_sprint = Models::Sprint.where(project_id: @project_id,
20
+ is_active: true).first
21
+
22
+ return db_sprint if db_sprint.nil?
23
+
24
+ Sprint.new(db_sprint)
25
+ end
26
+
27
+ def get(sprint_id)
28
+ db_sprint = Models::Sprint.find(sprint_id)
29
+ Sprint.new(db_sprint)
30
+ end
31
+
32
+ def complete_sprint
33
+ return if current.nil?
34
+
35
+ current.tasks.move_to(backlog.id)
36
+ current.end
37
+ end
38
+
39
+ def start_sprint
40
+ project_sprints = Models::Sprint.where(project_id: @project_id)
41
+ next_sprint_db = project_sprints.where('start_time > ?', Date.today).first
42
+
43
+ return if next_sprint_db.nil?
44
+
45
+ next_sprint = Sprint.new(next_sprint_db)
46
+
47
+ backlog.tasks.move_to(next_sprint.id)
48
+ next_sprint.start
49
+ end
50
+
51
+ def backlog
52
+ query = Models::Sprint.where(project_id: @project_id, is_backlog: true)
53
+ backlog = query.first
54
+ Sprint.new(backlog)
55
+ end
56
+ end
57
+
58
+ class Sprint
59
+ attr_reader :id, :start_time, :end_time, :is_active, :is_backlog, :tasks
60
+
61
+ def initialize(sprint)
62
+ @id = sprint.id
63
+ @start_time = sprint.start_time
64
+ @end_time = sprint.end_time
65
+ @is_active = sprint.is_active
66
+ @is_backlog = sprint.is_backlog
67
+ @project_id = sprint.project_id
68
+ @tasks = TaskRepository.new(@id)
69
+ end
70
+
71
+ def start
72
+ sprint = Models::Sprint.find(@id)
73
+ sprint.is_active = true
74
+ sprint.save
75
+ end
76
+
77
+ def end
78
+ sprint = Models::Sprint.find(@id)
79
+ sprint.is_active = false
80
+ sprint.save
81
+ end
82
+
83
+ def add_task(user_id, data)
84
+ check_user_role user_id
85
+ data[:created_by] = user_id
86
+ @tasks.add(data)
87
+ end
88
+
89
+ def all
90
+ @tasks.all
91
+ end
92
+
93
+ private
94
+
95
+ def check_user_role(user_id, role = 'spectator')
96
+ repo = ProjectRepository.new
97
+ project = repo.get(@project_id)
98
+ project.user_is?(user_id, role)
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,121 @@
1
+ require_relative '../db/models/task'
2
+
3
+ module Trackington
4
+ class TaskRepository
5
+ STATUSES = %w(open in_progress resolved closed reopened)
6
+ PRIORITIES = %w(blocker critical major minor trivial)
7
+ TYPES = %w(bug improvement new_feature story task)
8
+
9
+ def initialize(sprint_id)
10
+ @sprint_id = sprint_id
11
+ end
12
+
13
+ def move_to(sprint_id)
14
+ tasks = Models::Task.where(sprint_id: sprint_id)
15
+
16
+ tasks.each do |task|
17
+ task.sprint_id = sprint_id if active?(task.status)
18
+ task.save
19
+ end
20
+ end
21
+
22
+ def add(data)
23
+ data[:sprint_id] = @sprint_id
24
+ task = Models::Task.new(data)
25
+ task.save
26
+ end
27
+
28
+ def all
29
+ Models::Task.where(sprint_id: @sprint_id).map do |db_task|
30
+ Task.new(db_task)
31
+ end
32
+ end
33
+
34
+ def get(id)
35
+ db_task = Models::Task.where(sprint_id: @sprint_id, id: id).first
36
+ Task.new(db_task)
37
+ end
38
+
39
+ def status_types
40
+ STATUSES
41
+ end
42
+
43
+ def priorities
44
+ PRIORITIES
45
+ end
46
+
47
+ def types
48
+ TYPES
49
+ end
50
+
51
+ private
52
+
53
+ def active?(status)
54
+ %w(in_progress reopened open).include? status
55
+ end
56
+ end
57
+
58
+ class Task
59
+ STATUSES = %w(open in_progress resolved closed reopened)
60
+ PRIORITIES = %w(blocker critical major minor trivial)
61
+ TYPES = %w(bug improvement new_feature story task)
62
+
63
+ attr_reader :id, :title, :description, :time_planned, :time_actual
64
+ attr_reader :priority, :task_type, :status, :assigned_to, :created_by
65
+
66
+ def initialize(db_task)
67
+ basic_properties(db_task)
68
+ status_properties(db_task)
69
+ person_properties(db_task)
70
+ end
71
+
72
+ def active?
73
+ %w(in_progress reopened open).include? @status
74
+ end
75
+
76
+ def update(data)
77
+ db_task = Models::Task.find(@id)
78
+
79
+ data.each do |property, new_value|
80
+ db_task[property] = get_value(property, new_value) if property != :id
81
+ end
82
+
83
+ db_task.save
84
+
85
+ basic_properties(db_task)
86
+ status_properties(db_task)
87
+ person_properties(db_task)
88
+ end
89
+
90
+ private
91
+
92
+ def basic_properties(db_task)
93
+ @id = db_task.id
94
+ @title = db_task.title
95
+ @description = db_task.description
96
+ end
97
+
98
+ def status_properties(db_task)
99
+ @time_planned = db_task.time_planned
100
+ @time_actual = db_task.time_actual
101
+
102
+ @priority = db_task.priority
103
+ @task_type = db_task.task_type
104
+ @status = db_task.status
105
+ end
106
+
107
+ def person_properties(db_task)
108
+ @assigned_to = db_task.assigned_to
109
+ @created_by = db_task.created_by
110
+ end
111
+
112
+ def get_value(property, value)
113
+ case property
114
+ when :status then STATUSES.index(value)
115
+ when :priority then PRIORITIES.index(value)
116
+ when :task_type then TYPES.index(value)
117
+ else value
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,107 @@
1
+ require_relative '../db/models/user'
2
+ require_relative '../db/models/credential'
3
+
4
+ module Trackington
5
+ class UserRepository
6
+ SALT_LENGHT = 50
7
+ SESSION_KEY_LENGTH = 50
8
+
9
+ def register(email, password)
10
+ check_existing email
11
+
12
+ user = Models::User.new
13
+ user.email = email
14
+ user.save
15
+
16
+ credential = create_credentials(user.id, password)
17
+
18
+ credential.session_key
19
+ end
20
+
21
+ def user(session_key)
22
+ db_credential = Models::Credential.where(session_key: session_key).first
23
+
24
+ db_user = Models::User.find(db_credential.user_id)
25
+
26
+ User.new(db_user.id, db_user.email)
27
+ end
28
+
29
+ def login(email, password)
30
+ user = Models::User.where(email: email).first
31
+
32
+ fail "Email/password don't match" if user.nil?
33
+
34
+ credential = Models::Credential.where(user_id: user.id).first
35
+
36
+ check_credentials(credential, password)
37
+
38
+ credential.session_key = generate_string SESSION_KEY_LENGTH
39
+
40
+ credential.save
41
+
42
+ credential.session_key
43
+ end
44
+
45
+ def logout(session_key)
46
+ credential = Models::Credential.where(session_key: session_key).first
47
+
48
+ return if credential.nil?
49
+
50
+ credential.session_key = nil
51
+ credential.save
52
+ end
53
+
54
+ def count
55
+ Models::User.count
56
+ end
57
+
58
+ def search(query)
59
+ Models::User.where('email like ?', "%#{query}%").map do |user|
60
+ User.new(user.id, user.email)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def check_credentials(credential, password)
67
+ expected = hash(credential.salt + password)
68
+
69
+ fail "Username/password don't match." if expected != credential.password
70
+ end
71
+
72
+ def check_existing(email)
73
+ existing_user = Models::User.where(email: email).first
74
+
75
+ fail 'User already exists.' unless existing_user.nil?
76
+ end
77
+
78
+ def create_credentials(user_id, password)
79
+ salt = hash(generate_string(SALT_LENGHT))
80
+ credential = Models::Credential.new
81
+ credential.password = hash(salt + password)
82
+ credential.salt = salt
83
+ credential.session_key = generate_string SESSION_KEY_LENGTH
84
+ credential.user_id = user_id
85
+ credential.save
86
+ credential
87
+ end
88
+
89
+ def hash(input)
90
+ Digest::SHA256.base64digest(input)
91
+ end
92
+
93
+ def generate_string(length)
94
+ o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
95
+ (0...length).map { o[rand(o.length)] }.join
96
+ end
97
+ end
98
+
99
+ class User
100
+ attr_reader :id, :email
101
+
102
+ def initialize(id, email)
103
+ @id = id
104
+ @email = email
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,21 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: lib/db/development.sqlite3
4
+ pool: 5
5
+ timeout: 5000
6
+
7
+ # production:
8
+ # adapter: pg
9
+ # encoding: utf8
10
+ # reconnect: false
11
+ # database: somedatabase_dev
12
+ # pool: 5
13
+ # username: root
14
+ # password:
15
+ # socket: /var/run/mysqld/mysqld.sock
16
+
17
+ test: &test
18
+ adapter: sqlite3
19
+ database: lib/trackington/db/tmp/test.sqlite3
20
+ pool: 5
21
+ timeout: 5000
@@ -0,0 +1,7 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :users do |t|
4
+ t.string :email
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUserCredentials < ActiveRecord::Migration
2
+ def change
3
+ create_table :credentials do |t|
4
+ t.string :password
5
+ t.string :salt
6
+ t.string :session_key
7
+
8
+ t.belongs_to :user, index: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class CreateProjects < ActiveRecord::Migration
2
+ def change
3
+ create_table :projects do |t|
4
+ t.string :description
5
+ t.string :title
6
+ t.boolean :public, default: false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class CreateProjectRoles < ActiveRecord::Migration
2
+ def change
3
+ create_table :project_roles do |t|
4
+ t.integer :role_type, default: 0
5
+
6
+ t.belongs_to :user, index: true
7
+ t.belongs_to :project, index: true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSprints < ActiveRecord::Migration
2
+ def change
3
+ create_table :sprints do |t|
4
+ t.date :start_time
5
+ t.date :end_time
6
+ t.boolean :is_backlog
7
+
8
+ t.belongs_to :project, index: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ class CreateTasks < ActiveRecord::Migration
2
+ def change
3
+ create_table :tasks do |t|
4
+ t.string :title
5
+ t.string :description
6
+
7
+ t.integer :time_planned
8
+ t.integer :time_actual
9
+
10
+ t.integer :priority # Blocker, Critical, Major, Minor, Trivial
11
+ t.integer :type # Epic, Bug, Improvement, New Feature, Story, Task
12
+ t.integer :status
13
+
14
+ t.integer :assigned_to # should be belongs_to :user
15
+ t.integer :created_by # should be belongs_to :user
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ class UpdateSprintColumns < ActiveRecord::Migration
2
+ def change
3
+ add_column :sprints, :is_active, :boolean
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class UpdateTasksReferences < ActiveRecord::Migration
2
+ def change
3
+ add_reference :tasks, :sprint, index: true, foreign_key: true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class UpdateTasksColumn < ActiveRecord::Migration
2
+ def change
3
+ rename_column :tasks, :type, :task_type
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_record'
2
+
3
+ module Trackington
4
+ module Models
5
+ class Credential < ActiveRecord::Base
6
+ belongs_to :user
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'active_record'
2
+
3
+ module Trackington
4
+ module Models
5
+ class Project < ActiveRecord::Base
6
+ has_many :sprints
7
+ has_many :project_roles
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'active_record'
2
+
3
+ module Trackington
4
+ module Models
5
+ class ProjectRole < ActiveRecord::Base
6
+ enum role_type: [:owner, :contributor, :spectator]
7
+
8
+ belongs_to :project
9
+ belongs_to :user
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ require 'active_record'
2
+
3
+ module Trackington
4
+ module Models
5
+ class Sprint < ActiveRecord::Base
6
+ has_many :tasks
7
+
8
+ belongs_to :project
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_record'
2
+
3
+ module Trackington
4
+ module Models
5
+ class Task < ActiveRecord::Base
6
+ enum status: [:open, :in_progress, :resolved, :closed, :reopened]
7
+ enum priority: [:blocker, :critical, :major, :minor, :trivial]
8
+ enum task_type: [:bug, :improvement, :new_feature, :story, :task]
9
+
10
+ belongs_to :sprint
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_record'
2
+
3
+ module Trackington
4
+ module Models
5
+ class User < ActiveRecord::Base
6
+ has_many :project_roles
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ require 'rake'
2
+ require 'rake/tasklib'
3
+ require 'uri'
4
+ require 'active_record'
5
+
6
+ module Trackington
7
+ class RakeTask < ::Rake::TaskLib
8
+ include ::Rake::DSL if defined?(::Rake::DSL)
9
+
10
+ def initialize
11
+ namespace :trackington do
12
+ namespace :db do
13
+ task :migrate do
14
+ establish_connection
15
+
16
+ migrate
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def establish_connection
25
+ db_query = ENV['DB_QUERY']
26
+
27
+ db = URI.parse(db_query)
28
+
29
+ ActiveRecord::Base.establish_connection(
30
+ adapter: db.scheme == 'postgres' ? 'postgresql' : db.scheme,
31
+ host: db.host,
32
+ username: db.user,
33
+ password: db.password,
34
+ database: db.path[1..-1],
35
+ encoding: 'utf8')
36
+ end
37
+
38
+ def migrate
39
+ migrations_path = File.expand_path('../../db/migrate', __FILE__)
40
+
41
+ ActiveRecord::Migrator.migrate(migrations_path, nil)
42
+ end
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: trackington
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yoan Dinkov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-10 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Simple bug tracking system based on projects, sprints, tasks. (University
14
+ project)
15
+ email:
16
+ - yoandinkov@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/trackington.rb
22
+ - lib/trackington/app/core.rb
23
+ - lib/trackington/app/projects.rb
24
+ - lib/trackington/app/sprints.rb
25
+ - lib/trackington/app/tasks.rb
26
+ - lib/trackington/app/users.rb
27
+ - lib/trackington/db/config.yml
28
+ - lib/trackington/db/migrate/20160207202529_create_users.rb
29
+ - lib/trackington/db/migrate/20160207203302_create_user_credentials.rb
30
+ - lib/trackington/db/migrate/20160209100247_create_projects.rb
31
+ - lib/trackington/db/migrate/20160209101604_create_project_roles.rb
32
+ - lib/trackington/db/migrate/20160209153945_create_sprints.rb
33
+ - lib/trackington/db/migrate/20160209154117_create_tasks.rb
34
+ - lib/trackington/db/migrate/20160209165534_update_sprint_columns.rb
35
+ - lib/trackington/db/migrate/20160209193650_update_tasks_references.rb
36
+ - lib/trackington/db/migrate/20160209195016_update_tasks_column.rb
37
+ - lib/trackington/db/models/credential.rb
38
+ - lib/trackington/db/models/project.rb
39
+ - lib/trackington/db/models/project_role.rb
40
+ - lib/trackington/db/models/sprint.rb
41
+ - lib/trackington/db/models/task.rb
42
+ - lib/trackington/db/models/user.rb
43
+ - lib/trackington/rake/task.rb
44
+ homepage: http://rubygems.org/gems/trackington
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.4.5.1
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Trackington - bug tracking system. (University project)
68
+ test_files: []