diff --git a/Gemfile.lock b/Gemfile.lock index e23a66f..50d9ff2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,7 @@ PATH remote: . specs: github-team-remover (0.0.2) + colorize octokit (~> 3.0) thor @@ -10,12 +11,13 @@ GEM specs: addressable (2.3.6) ast (1.1.0) + colorize (0.7.2) diff-lcs (1.2.5) faraday (0.9.0) multipart-post (>= 1.2, < 3) json (1.8.1) multipart-post (2.0.0) - octokit (3.0.0) + octokit (3.1.0) sawyer (~> 0.5.3) parser (2.1.7) ast (~> 1.1) diff --git a/bin/github-team-remover b/bin/github-team-remover index 4cd975d..2c9b4b2 100755 --- a/bin/github-team-remover +++ b/bin/github-team-remover @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +require 'bundler/setup' require 'rubygems' require 'remover' diff --git a/github-team-remover.gemspec b/github-team-remover.gemspec index 90f5aaa..d9b8661 100644 --- a/github-team-remover.gemspec +++ b/github-team-remover.gemspec @@ -21,6 +21,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'octokit', '~> 3.0' spec.add_dependency 'thor' + spec.add_dependency 'colorize' spec.add_development_dependency 'rubocop' spec.add_development_dependency 'rspec', '~> 3.0.0.beta2' diff --git a/lib/remover.rb b/lib/remover.rb index 01155dc..b99512d 100644 --- a/lib/remover.rb +++ b/lib/remover.rb @@ -3,8 +3,10 @@ require 'remover/github' require 'remover/team' require 'remover/list' +require 'remover/remove' require 'remover/cli' require 'remover/configuration' +require 'remover/formatter' module Remover def self.configuration diff --git a/lib/remover/cli.rb b/lib/remover/cli.rb index 4d2a35c..3aa9a67 100644 --- a/lib/remover/cli.rb +++ b/lib/remover/cli.rb @@ -2,17 +2,20 @@ module Remover class CLI < Thor - method_option :organization, required: true - method_option :login, required: true - method_option :password, required: true + method_option :organization, aliases: '--org', required: true + method_option :login, aliases: '--log', required: true + method_option :password, aliases: '--pas', required: true + method_option :verbose, aliases: '--ver', desc: 'Puts additional info' + method_option :remove, aliases: '--rem', desc: 'Removes unused teams' desc('list', 'List unused teams') def list Remover.configuration.load_from_options!(options) - Remover::List.new(github).unused_teams.each do |team| - puts team.name + puts Remover::Formatter.new(team).list_output + + team.delete_team if options[:remove] end end diff --git a/lib/remover/configuration.rb b/lib/remover/configuration.rb index 4495f6d..629c791 100644 --- a/lib/remover/configuration.rb +++ b/lib/remover/configuration.rb @@ -1,6 +1,6 @@ module Remover class Configuration - OPTIONS = %i(organization login password) + OPTIONS = %i(organization login password verbose remove) attr_accessor(*OPTIONS) @@ -9,5 +9,13 @@ def load_from_options!(options) send("#{option}=", options[option.to_s]) end end + + def verbose? + true if options[:verbose] + end + + def remove? + true if options[:remove] + end end end diff --git a/lib/remover/formatter.rb b/lib/remover/formatter.rb new file mode 100644 index 0000000..4e6a934 --- /dev/null +++ b/lib/remover/formatter.rb @@ -0,0 +1,52 @@ +require 'colored' + +module Remover + class Formatter + TEAM_NAME = " Team Name: %{count}" + MEMBERS_AMOUNT = " Members amount: %{count}" + REPOS_AMOUNT = " Repositories amount: %{count}" + REPOS_LIST = " %{count}" + MEMBERS_LIST = " %{count}" + + + attr_accessor :team + + def initialize(team) + @team = team + end + + def list_output + "#{put_team_name} + #{put_repos_amount} + #{put_repos_list} + #{put_members_amount} + #{put_members_list}" + end + + private + + def put_repos_amount + (REPOS_AMOUNT % {count: team.repos_amount}).green + end + + def put_members_amount + (MEMBERS_AMOUNT % {count: team.members_amount}).green + end + + def put_team_name + (TEAM_NAME % {count: team.name}).red + end + + def put_repos_list + team.list_repos.each do |repos| + (REPOS_LIST % {count: repos.html_url}).yellow + end + end + + def put_members_list + team.list_members.each do |member| + (MEMBERS_LIST % {count: member.html_url}).yellow + end + end + end +end diff --git a/lib/remover/output.rb b/lib/remover/output.rb new file mode 100644 index 0000000..2caa8a3 --- /dev/null +++ b/lib/remover/output.rb @@ -0,0 +1,52 @@ +require 'colored' + +module Remover + class Output + TEAM_NAME = " Team Name: %{count}" + MEMBERS_AMOUNT = " Members amount: %{count}" + REPOS_AMOUNT = " Repositories amount: %{count}" + REPOS_LIST = " %{count}" + MEMBERS_LIST = " %{count}" + + + attr_accessor :team + + def initialize(team) + @team = team + end + + def list_output + put_team_name + put_repos_amount + put_repos_list if verbose + put_members_amount + put_members_list if verbose + end + + private + + def put_repos_amount + (REPOS_AMOUNT % {count: team.repos_amount}).green + end + + def put_members_amount + (MEMBERS_AMOUNT % {count: team.members_amount}).green + end + + def put_team_name + (TEAM_NAME % {count: team.name}).red + end + + def put_repos_list + team.list_repos.each do |repos| + (REPOS_LIST % {count: repos.html_url}).yellow + end + end + + def put_members_list + team.list_members.each do |member| + (MEMBERS_LIST % {count: member.html_url}).yellow + end + end + end +end diff --git a/lib/remover/remove.rb b/lib/remover/remove.rb new file mode 100644 index 0000000..1a50d51 --- /dev/null +++ b/lib/remover/remove.rb @@ -0,0 +1,14 @@ +module Remover + class Remove + attr_accessor :team + + def initialize(team) + @team = team + end + + def remove_and_put_message + team.delete_team + puts " TEAM #{team.name} WAS REMOVED!".red_on_yellow + end + end +end diff --git a/lib/remover/team.rb b/lib/remover/team.rb index f8b8ac8..d0251ab 100644 --- a/lib/remover/team.rb +++ b/lib/remover/team.rb @@ -14,14 +14,34 @@ def name github_team.name end + def delete_team + github_client.delete_team(github_team.id) + end + + def members_amount + github_client.team_members(github_team.id).size + end + + def repos_amount + github_client.team_repositories(github_team.id).size + end + + def list_members + github_client.team_members(github_team.id) + end + + def list_repos + github_client.team_repositories(github_team.id) + end + private def with_members? - github_client.team_members(github_team.id).size > 0 + members_amount > 0 end def with_repositories? - github_client.team_repositories(github_team.id).size > 0 + repos_amount > 0 end end end diff --git a/spec/remover/cli_spec.rb b/spec/remover/cli_spec.rb new file mode 100644 index 0000000..7950db5 --- /dev/null +++ b/spec/remover/cli_spec.rb @@ -0,0 +1,33 @@ +describe Remover::CLI do + let(:options) do + { 'organization' => 'FlatSchool', + 'login' => 'fs-school', + 'password' => '123456', + 'verbose' => 'true', + 'remove' => 'true' + } + end + let(:configuration) { Remover::Configuration.new } + + describe '#verbose' do + before do + configuration.load_from_options!(options) + end + + it 'returns true' do + expect(configuration.verbose).to eq('true') + end + + context 'if --verbose key not entered' do + let(:options) do + { + 'verbose' => 'false' + } + end + + it 'returns false' do + expect(configuration.verbose).not_to eq('true') + end + end + end +end diff --git a/spec/remover/configuration_spec.rb b/spec/remover/configuration_spec.rb index b656109..81d68be 100644 --- a/spec/remover/configuration_spec.rb +++ b/spec/remover/configuration_spec.rb @@ -3,7 +3,9 @@ { 'organization' => 'FlatSchool', 'login' => 'fs-school', - 'password' => '123456' + 'password' => '123456', + 'verbose' => 'true', + 'remove' => 'true' } end @@ -18,6 +20,8 @@ expect(configuration.organization).to eq('FlatSchool') expect(configuration.login).to eq('fs-school') expect(configuration.password).to eq('123456') + expect(configuration.verbose).to eq('true') + expect(configuration.remove).to eq('true') end end end diff --git a/spec/remover/remove_spec.rb b/spec/remover/remove_spec.rb new file mode 100644 index 0000000..d508175 --- /dev/null +++ b/spec/remover/remove_spec.rb @@ -0,0 +1,33 @@ +describe Remover::Remove do + let(:options) do + { 'organization' => 'FlatSchool', + 'login' => 'fs-school', + 'password' => '123456', + 'verbose' => 'true', + 'remove' => 'true' + } + end + let(:configuration) { Remover::Configuration.new } + + describe '#remove_and_put_message' do + before do + configuration.load_from_options!(options) + end + + it 'returns true' do + expect(configuration.remove).to eq('true') + end + + context 'if --remove key not entered' do + let(:options) do + { + 'remove' => 'false' + } + end + + it 'returns false' do + expect(configuration.remove).not_to eq('true') + end + end + end +end diff --git a/spec/remover/team_spec.rb b/spec/remover/team_spec.rb index f666388..e189789 100644 --- a/spec/remover/team_spec.rb +++ b/spec/remover/team_spec.rb @@ -9,6 +9,68 @@ end end + describe '#members_amount' do + before do + allow(github_client).to receive(:team_members) { [] } + end + + it 'returns Github team members amount' do + expect(team.members_amount).to eq(github_client.team_members(github_team.id).size) + end + end + + describe '#repos_amount' do + before do + allow(github_client).to receive(:team_repositories) { [] } + end + + it 'returns Github team repository amount' do + expect(team.repos_amount).to eq(github_client.team_repositories(github_team.id).size) + end + end + + describe '#list_members' do + before do + allow(github_client).to receive(:team_members) { [] } + end + + it 'returns array' do + expect(team.list_members).to be_an(Array) + end + end + + describe '#delete_team' do + context 'if deleted' do + before do + allow(github_client).to receive(:delete_team) { true } + end + + it 'returns true' do + expect(team.delete_team).to eq(github_client.delete_team(github_team.id)) + end + end + + context 'if not deleted' do + before do + allow(github_client).to receive(:delete_team) { false } + end + + it 'returns false' do + expect(team.delete_team).to eq(github_client.delete_team(github_team.id)) + end + end + end + + describe '#list_repos' do + before do + allow(github_client).to receive(:team_repositories) { [] } + end + + it 'returns array' do + expect(team.list_repos).to be_an(Array) + end + end + describe '#used' do let(:members) { [double('Github Member')] } let(:repositories) { [double('Github Repository')] }