Commit 4e70d7c1 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Refactor implementation of team project assignments

parent 20d57429
Pipeline #7649650 passed with stages
in 12 minutes and 24 seconds
--color
--require spec_helper
--format documentation
......@@ -32,4 +32,5 @@ group :development, :test do
gem 'docopt'
gem 'scss_lint', require: false
gem 'yaml-lint', require: false
gem 'rspec', '~> 3.5', require: false
end
......@@ -29,6 +29,7 @@ GEM
sass (>= 3.2, < 3.5)
concurrent-ruby (1.0.5)
contracts (0.13.0)
diff-lcs (1.3)
docopt (0.5.0)
dotenv (2.2.0)
em-websocket (0.5.1)
......@@ -125,6 +126,19 @@ GEM
rb-inotify (0.9.8)
ffi (>= 0.5.0)
rouge (2.0.7)
rspec (3.5.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
sass (3.4.23)
scss_lint (0.52.0)
rake (>= 0.9, < 13)
......@@ -156,6 +170,7 @@ DEPENDENCIES
middleman-syntax
mini_racer (~> 0.1)
nokogiri
rspec (~> 3.5)
scss_lint
stringex
tzinfo-data
......
gitlab-ce:
name: GitLab Community Edition (CE)
path: gitlab-org/gitlab-ce
link: https://gitlab.com/gitlab-org/gitlab-ce
mirrors:
- https://github.com/gitlabhq/gitlabhq
- https://dev.gitlab.org/gitlab/gitlabhq
description: |
This is the community edition of GitLab. Most of the development happens here,
then gets merged into GitLab EE periodically. Unless you're making a change
specific to GitLab EE, add it to CE.
gitlab-ee:
name: GitLab Enterprise Edition (EE)
path: gitlab-org/gitlab-ee
link: https://gitlab.com/gitlab-org/gitlab-ee
description: |
This is _not_ an open source project, but we made the source code available for
viewing and contributions.
GitLab Community Edition is merged daily to GitLab Enterprise Edition (look for
the [`CE Upstream` merge requests]) and as a developer it's your responsibility
to ensure that your merge requests [apply cleanly to GitLab EE][ce-ee-docs].
Please consult [Limit conflicts with EE when developing on CE][ce-ee-docs] for
more details.
GitLab EE requires a license key to be used. To be able to run your
own instances for development you can use one of the shared licenses (like <https://license.gitlab.com/licenses/1449>) or you
can clone <https://dev.gitlab.org/gitlab/license-app> and generate your own
licenses.
[`CE Upstream` merge requests]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests?label_name%5B%5D=CE+upstream
[ce-ee-docs]: https://docs.gitlab.com/ee/development/limit_ee_conflicts.html
gitlab-shell:
name: GitLab Shell
path: gitlab-org/gitlab-shell
link: https://gitlab.com/gitlab-org/gitlab-shell
mirrors:
- https://dev.gitlab.org/gitlab/gitlab-shell
- https://github.com/gitlabhq/gitlab-shell
description: |
GitLab Shell handles Git commands for GitLab. It's an essential part of GitLab.
gitlab-workhorse:
name: GitLab Workhorse
path: gitlab-org/gitlab-workhorse
link: https://gitlab.com/gitlab-org/gitlab-workhorse
mirrors: []
description: |
Gitlab-workhorse is a smart reverse proxy for GitLab. It handles "large" HTTP
requests such as file downloads, file uploads, Git push/pull and Git archive
downloads.
omnibus-gitlab:
name: Omnibus GitLab
path: gitlab-org/omnibus-gitlab
link: https://gitlab.com/gitlab-org/omnibus-gitlab
mirrors:
- https://dev.gitlab.org/gitlab/omnibus-gitlab
- https://github.com/gitlabhq/omnibus-gitlab
description: |
Omnibus GitLab creates the packages for GitLab.
gitaly:
name: Gitaly
path: gitlab-org/gitaly
link: https://gitlab.com/gitlab-org/gitaly
mirrors: []
description: |
Git RPC service for handling all the git calls made by GitLab.
gitlab-qa:
name: GitLab QA
path: gitlab-org/gitlab-qa
link: https://gitlab.com/gitlab-org/gitlab-qa
mirrors: []
description: |
End-to-end, black-box, entirely click-driven integration tests for GitLab.
www-gitlab-com:
name: GitLab Inc. Homepage
path: gitlab-com/www-gitlab-com
link: https://gitlab.com/gitlab-com/www-gitlab-com
mirrors: []
description: GitLab Inc. Homepage available at about.gitlab.com
......@@ -7,9 +7,8 @@
gitlab: dzaporozhets
picture: picture_dmitriy.png
projects:
maintains:
- gitlab-ce
- gitlab-ee
gitlab-ce: maintainer backend
gitlab-ee: maintainer backend
maintains: |
<li>Maintainer of <a href="https://gitlab.com/gitlab-org/gitlab-ce/">GitLab CE</a> and <a href="https://gitlab.com/gitlab-org/gitlab-ee/">EE</a></li>
story: |
......@@ -28,6 +27,9 @@
twitter: sytses
gitlab: sytses
picture: picture_sytse.png
projects:
gitlab-ce: owner
gitlab-ee: owner
story: |
Sid saw the first ruby code in 2007 and loved it so much he learned to program and made this his profession.
Before that he was engaged in various businesses, from selling programmable infrared receivers to starting a recreational submarine company.
......@@ -44,9 +46,9 @@
twitter: maxlazio
gitlab: marin
projects:
owns:
owner:
- omnibus-gitlab
maintains:
maintainer:
- cookbook-omnibus-gitlab
maintains: |
<li>Maintainer of <a href="https://gitlab.com/gitlab-org/omnibus-gitlab/">Omnibus GitLab</a></li>
......@@ -69,7 +71,7 @@
twitter: jacobvosmaer
gitlab: jacobvosmaer
projects:
maintains:
maintainer:
- gitlab-workhorse
maintains: |
<li>Maintainer of <a href="https://gitlab.com/gitlab-org/gitaly/">Gitaly</a></li>
......@@ -91,7 +93,7 @@
twitter: Jobvo
gitlab: JobV
projects:
owns:
owner:
- gitlab-ce
- gitlab-ee
story: |
......
......@@ -5,6 +5,7 @@ module Gitlab
class Team
autoload :Member, 'lib/team/member'
autoload :Project, 'lib/team/project'
autoload :Assignment, 'lib/team/assignment'
end
end
end
require 'yaml'
module Gitlab
module Homepage
class Team
......@@ -11,10 +13,10 @@ module Gitlab
end
end
def project(name)
Team::Project.new(name).tap do |project|
def projects
@projects ||= Team::Project.all! do |project|
members.each do |member|
project.add_member(member) if member.involved_in?(name)
project.assign(member) if member.involved?(project)
end
end
end
......
module Gitlab
module Homepage
class Team
class Assignment
attr_reader :member, :project
def initialize(member, project, role)
@member = member
@project = project
@role = role.to_s
end
def responsibility
@role.split(' ')[0]
end
def description
@role.split(' ')[1]
end
def owner?
responsibility == 'owner'
end
def maintainer?
responsibility == 'maintainer'
end
def reviewer?
responsibility == 'reviewer'
end
end
end
end
end
......@@ -4,31 +4,30 @@ module Gitlab
class Member
def initialize(data)
@data = data
@projects = data.fetch('projects', {})
end
def username
@data.fetch('gitlab')
end
def project_names
@project_names ||= @projects.values.flatten.uniq
def country
@data.fetch('country')
end
def involved_in?(name)
project_names.include?(name)
def story
@data.fetch('story')
end
def owns?(project)
@projects.fetch('owns', []).include?(project.name)
def involved?(project)
roles.has_key?(project.key)
end
def maintains?(project)
@projects.fetch('maintains', []).include?(project.name)
end
def reviews?(project)
@projects.fetch('reviews', []).include?(project.name)
def roles
@roles ||= Hash.new.tap do |hash|
@data.fetch('projects', {}).each do |project, roles|
Array(roles).each { |role| (hash[project] ||= []) << role }
end
end
end
end
end
......
......@@ -2,32 +2,43 @@ module Gitlab
module Homepage
class Team
class Project
attr_reader :name, :members
attr_reader :key, :assignments
def initialize(name)
@name = name
@members = []
def initialize(key, data)
@key = key
@data = data
@assignments = []
end
def add_member(member)
@members << member
def name
@data.fetch('name')
end
def owners
@members.select do |member|
member.owns?(self)
def description
@data.fetch('description')
end
def assign(member)
member.roles[key].each do |role|
@assignments << Team::Assignment.new(member, self, role)
end
end
def owners
@assignments.select(&:owner?)
end
def maintainers
@members.select do |member|
member.maintains?(self)
end
@assignments.select(&:maintainer?)
end
def reviewers
@members.select do |member|
member.reviews?(self)
@assignments.select(&:reviewer?)
end
def self.all!
YAML.load_file('data/projects.yml').map do |key, data|
self.new(key, data).tap { |project| yield project if block_given? }
end
end
end
......
%h2 Description
= project.description
%h3 Assignments
%table.table.col-md-4
%tr
%td Owners
%td
- project.owners.each do |owner|
= owner.username
- project.owners.each do |assignment|
= partial 'assignment', locals: { assignment: assignment }
%tr
%td Maintainers
%td
- project.maintainers.each do |maintainer|
= maintainer.username
- project.maintainers.each do |assignment|
= partial 'assignment', locals: { assignment: assignment }
%tr
%td Reviewers
%td
- project.reviewers.each do |reviewer|
= reviewer.username
- project.reviewers.each do |assignment|
= partial 'assignment', locals: { assignment: assignment }
......@@ -3,100 +3,6 @@ layout: markdown_page
title: "Engineering Projects"
---
:markdown
## GitLab Projects
- team.projects.each do |project|
= partial 'project', locals: { project: project }
| Project | Location | Who to ask about it? |
|-----------|-----------|---------|--------------|
| [GitLab CE](#gitlab-community-edition-ce) | [gitlab-org/gitlab-ce](https://gitlab.com/gitlab-org/gitlab-ce) | `@JobV @dzaporozhets` |
| [GitLab EE](#gitlab-enterprise-edition-ee) | [gitlab-org/gitlab-ee](https://gitlab.com/gitlab-org/gitlab-ee) | `@JobV @vsizow` |
| [GitLab Shell](#gitlab-shell) | [gitlab-org/gitlab-shell](https://gitlab.com/gitlab-org/gitlab-shell) | `@MikeB @DouweM` |
| [Omnibus GitLab](#omnibus-gitlab) | [gitlab-org/omnibus-gitlab](https://gitlab.com/gitlab-org/omnibus-gitlab) | `@regisF @marin` |
| [GitLab Workhorse](#gitlab-workhorse) | [gitlab-org/gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) | `@jacobvosmaer-gitlab @nick.thomas` |
| [Gitaly](#gitaly) | [gitlab-org/gitaly](https://gitlab.com/gitlab-org/gitaly) | `@pcarranza` |
| [GitLab QA](#gitlab-qa) | [gitlab-org/gitlab-qa](https://gitlab.com/gitlab-org/gitlab-qa) | `@rymai @grzesiek` |
| [GitLab Runner](#gitlab-runner) | [gitlab-org/gitlab-ci-multi-runner](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner) | `@ayufan @tmaczukin` |
| [about.gitlab.com](#www-gitlab-com) | [gitlab-com/www-gitlab-com](https://gitlab.com/gitlab-com/www-gitlab-com) | `@sytses @JobV` |
| [customers.gitlab.com](#customers-gitlab-com) | [gitlab-com/customers-gitlab-com](https://gitlab.com/gitlab-com/cusomers-gitlab-com) | `@regisF` |
| [version.gitlab.com](#version-gitlab-com) | [gitlab-com/customers-gitlab-com](https://gitlab.com/gitlab-com/cusomers-gitlab-com) | `@regisF` |
| [license.gitlab.com](#license-gitlab-com) | [gitlab-com/customers-gitlab-com](https://gitlab.com/gitlab-com/cusomers-gitlab-com) | `@regisF` |
| [customers.gitlab.com](#customers-gitlab-com) | [gitlab-com/customers-gitlab-com](https://gitlab.com/gitlab-com/cusomers-gitlab-com) | `@regisF` |
### GitLab Community Edition (CE)
This is the community edition of GitLab. Most of the development happens here,
then gets merged into GitLab EE periodically. Unless you're making a change
specific to GitLab EE, add it to CE.
- [https://gitlab.com/gitlab-org/gitlab-ce](https://gitlab.com/gitlab-org/gitlab-ce)
- [https://dev.gitlab.org/gitlab/gitlabhq](https://dev.gitlab.org/gitlab/gitlabhq)
- [https://github.com/gitlabhq/gitlabhq](https://github.com/gitlabhq/gitlabhq)
%div
= partial 'project', locals: { project: team.project('gitlab-ce') }
:markdown
### GitLab Enterprise Edition (EE)
This is _not_ an open source project, but we made the source code available for
viewing and contributions.
GitLab Community Edition is merged daily to GitLab Enterprise Edition (look for
the [`CE Upstream` merge requests]) and as a developer it's your responsibility
to ensure that your merge requests [apply cleanly to GitLab EE][ce-ee-docs].
Please consult [Limit conflicts with EE when developing on CE][ce-ee-docs] for
more details.
GitLab EE requires a license key to be used. To be able to run your
own instances for development you can use one of the shared licenses (like <https://license.gitlab.com/licenses/1449>) or you
can clone <https://dev.gitlab.org/gitlab/license-app> and generate your own
licenses.
- [https://gitlab.com/gitlab-org/gitlab-ee](https://gitlab.com/gitlab-org/gitlab-ee)
- [https://dev.gitlab.org/gitlab/gitlab-ee](https://dev.gitlab.org/gitlab/gitlab-ee)
[`CE Upstream` merge requests]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests?label_name%5B%5D=CE+upstream
[ce-ee-docs]: https://docs.gitlab.com/ee/development/limit_ee_conflicts.html
### GitLab Shell
GitLab Shell handles Git commands for GitLab. It's an essential part of GitLab.
- [https://gitlab.com/gitlab-org/gitlab-shell](https://gitlab.com/gitlab-org/gitlab-shell)
- [https://dev.gitlab.org/gitlab/gitlab-shell](https://dev.gitlab.org/gitlab/gitlab-shell)
- [https://github.com/gitlabhq/gitlab-shell](https://github.com/gitlabhq/gitlab-shell)
### GitLab Workhorse
Gitlab-workhorse is a smart reverse proxy for GitLab. It handles "large" HTTP
requests such as file downloads, file uploads, Git push/pull and Git archive
downloads.
- [https://gitlab.com/gitlab-org/gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse)
### Omnibus GitLab
Omnibus GitLab creates the packages for GitLab.
- [https://gitlab.com/gitlab-org/omnibus-gitlab](https://gitlab.com/gitlab-org/omnibus-gitlab)
- [https://dev.gitlab.org/gitlab/omnibus-gitlab](https://dev.gitlab.org/gitlab/omnibus-gitlab)
- [https://github.com/gitlabhq/omnibus-gitlab](https://github.com/gitlabhq/omnibus-gitlab)
### Gitaly
Git RPC service for handling all the git calls made by GitLab.
- [https://gitlab.com/gitlab-org/gitaly](https://gitlab.com/gitlab-org/gitaly)
### GitLab QA
End-to-end, black-box, entirely click-driven integration tests for GitLab.
- [https://gitlab.com/gitlab-org/gitlab-qa](https://gitlab.com/gitlab-org/gitlab-qa)
### www-gitlab-com
GitLab Inc. Homepage.
- [https://gitlab.com/gitlab-com/www-gitlab-com](https://gitlab.com/gitlab-com/www-gitlab-com)
describe Gitlab::Homepage::Team::Assignment do
let(:member) { double('member') }
let(:project) { double('project') }
subject do
described_class.new(member, project, 'maintainer backend')
end
describe '#responsibility' do
it { expect(subject.responsibility).to eq 'maintainer' }
end
describe '#description' do
it { expect(subject.description).to eq 'backend' }
end
describe '#member' do
it { expect(subject.member).to eq member }
end
describe '#project' do
it { expect(subject.project).to eq project }
end
describe '#owner?' do
it { expect(subject).not_to be_owner }
end
describe '#maintainer?' do
it { expect(subject).to be_maintainer }
end
describe '#reviewer?' do
it { expect(subject).not_to be_reviewer }
end
end
describe Gitlab::Homepage::Team::Member do
describe 'team member template integration' do
let(:member) do
Gitlab::Homepage::Team.build!
.members.first
end
it 'correctly integrates with data/team.yml' do
expect(member.username).to eq 'dzaporozhets'
expect(member.country).to eq 'Ukraine'
expect(member.story).to match /Dmitriy started GitLab/
expect(member.roles).to be_a Hash
end
end
describe '#roles' do
context 'when user has only one role in the project' do
subject do
described_class.new('projects' =>
{ 'gitlab-ce' =>
'maintainer backend' })
end
it 'returns an inverted project role hash' do
expect(subject.roles['gitlab-ce']).not_to be_empty
expect(subject.roles['gitlab-ce']).to all(be_a String)
end
end
context 'when user has only one role in the project' do
subject do
described_class.new('projects' =>
{ 'gitlab-ce' =>
['maintainer backend', 'owner'] })
end
it 'returns an inverted project role hash' do
expect(subject.roles['gitlab-ce']).not_to be_nil
expect(subject.roles['gitlab-ce']).to all(be_a String)
end
end
end
describe '#involved?' do
subject do
described_class.new('projects' =>
{ 'gitlab-ce' =>
['maintainer backend', 'owner'] })
end
context 'when user is involved in the project' do
it 'indicates that user is involved in the project' do
project = double(key: 'gitlab-ce')
expect(subject.involved?(project)).to be true
end
end
context 'when user is not involved in the project' do
it 'indicates that user is not involved in the project' do
project = double(key: 'gitlab-ee')
expect(subject.involved?(project)).to be false
end
end
end
end
describe Gitlab::Homepage::Team::Project do
describe 'integration with projects template' do
subject { described_class.all! }
it 'correctly integrates with data/projects.yml' do
expect(subject).not_to be_empty
expect(subject).to all(be_a described_class)
expect(subject.first.name).to eq 'GitLab Community Edition (CE)'
end
end
end
describe Gitlab::Homepage::Team do
subject { described_class.build! }
describe '#members' do
it 'returns an array of team members' do
expect(subject.members).to all(be_a Gitlab::Homepage::Team::Member)
end
end
describe '#projects' do
it 'returns a list of projects with members assigned' do
expect(subject.projects.first.key).to eq 'gitlab-ce'
expect(subject.projects.first.maintainers.count).to be_nonzero
end
end
describe '.build!' do
it 'builds a team object by reading team.yml' do
expect(subject).to be_a described_class
expect(subject.members).not_to be_empty
end
end
end
$LOAD_PATH << File.expand_path('..', __dir__)
require 'lib/homepage'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.order = :random
Kernel.srand config.seed
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment