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/README.md b/README.md index e40b99b..c22b909 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,13 @@ ```ruby github-team-remover \ - --organization FlatstackSchool \ - --login github-login \ - --password github-password + --organization FlatstackSchool, or --o \ + --login github-login, or --l \ + --password github-password, or --p \ +optional + --color color, like blue, or --c \ + --verbose or --v + --delete or --d ``` ## Install 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/github-team-remover.gemspec~ b/github-team-remover.gemspec~ new file mode 100644 index 0000000..d9b8661 --- /dev/null +++ b/github-team-remover.gemspec~ @@ -0,0 +1,28 @@ +# coding: utf-8 +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) + +require 'remover/version' + +Gem::Specification.new do |spec| + spec.name = "github-team-remover" + spec.version = Remover::VERSION + spec.authors = ["Flatstack School"] + spec.email = ["fs-admin+school@flatstack.com"] + spec.summary = %q{Show empty teams on github} + spec.description = %q{Show empty teams on github. Teams without members or tems without repositories.} + spec.homepage = "http://github.com/FlatstackSchool/github-team-remover" + spec.license = "MIT" + + spec.files = `git ls-files -z`.split("\x0") + spec.executables = ['github-team-remover'] + spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) + spec.require_paths = ["lib"] + + 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' +end diff --git a/lib/remover.rb b/lib/remover.rb index 01155dc..5ab3eea 100644 --- a/lib/remover.rb +++ b/lib/remover.rb @@ -3,6 +3,7 @@ require 'remover/github' require 'remover/team' require 'remover/list' +require 'remover/reporter' require 'remover/cli' require 'remover/configuration' diff --git a/lib/remover/cli.rb b/lib/remover/cli.rb index 4d2a35c..b76dc1e 100644 --- a/lib/remover/cli.rb +++ b/lib/remover/cli.rb @@ -1,18 +1,33 @@ require 'thor' +require 'colorize' module Remover class CLI < Thor - method_option :organization, required: true - method_option :login, required: true - method_option :password, required: true + method_option :organization, aliases: '--o', required: true + method_option :login, aliases: '--l', required: true + method_option :password, aliases: '--p', required: true + method_option :color, default: :white, aliases: '--c' + method_option :verbose, aliases: '--v' + method_option :delete, aliases: '--d' - desc('list', 'List unused teams') + desc('|Commands:', 'help list for more info') + + long_desc <<-LONGDESC + Optional commands: + --c color : will colorize your output. + + You can use red, yellow, green, white and maybe others colors + + --v => additional info, URL for users and repos + + --d => will delete all unused teams + LONGDESC def list Remover.configuration.load_from_options!(options) - - Remover::List.new(github).unused_teams.each do |team| - puts team.name + puts 'Unused teams:'.colorize(color) + Remover::List.new(github).unused_teams.each do |unused_team| + Remover::Reporter.new(unused_team, color, verbose?, delete?).report_to_cli end end @@ -20,6 +35,18 @@ def list private + def delete? + true if options[:delete] + end + + def verbose? + true if options[:verbose] + end + + def color + Remover.configuration.color.intern + end + def github Remover::Github.new(octokit) end diff --git a/lib/remover/configuration.rb b/lib/remover/configuration.rb index 4495f6d..b017331 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 color verbose delete) attr_accessor(*OPTIONS) diff --git a/lib/remover/reporter.rb b/lib/remover/reporter.rb new file mode 100644 index 0000000..96ed0c2 --- /dev/null +++ b/lib/remover/reporter.rb @@ -0,0 +1,63 @@ +require 'colorize' + +module Remover + class Reporter + attr_accessor :unused_team, :color, :verbose, :delete + + def initialize(unused_team, color, verbose, delete) + @unused_team, @color, @verbose, @delete = unused_team, color, verbose, delete + end + + def report_to_cli + puts ' ------------------------------'.colorize(color_it) + team_name + members_amount + members_url if verbose? + repos_amount + repos_url if verbose? + report_and_delete if delete? + puts ' ------------------------------'.colorize(color_it) + end + + private + + def verbose? + true if @verbose + end + + def delete? + true if @delete + end + + def team_name + puts " Team name: #{unused_team.name}".colorize(color_it) + end + + def members_amount + puts " Members: #{unused_team.members_amount}".colorize(color_it) + end + + def members_url + puts ' Members URL:'.colorize(color_it) + puts " #{unused_team.members_url.colorize(:yellow)}" if verbose? + end + + def repos_amount + puts " Repositories: #{unused_team.repositories_amount}".colorize(color_it) + end + + def repos_url + puts ' Repositories URL:'.colorize(color) + puts " #{unused_team.repositories_url.colorize(:yellow)}" if verbose? + end + + def report_and_delete + puts ' !DELETED!'.colorize(:red) if delete + unused_team.delete_team + end + + def color_it + color + end + end +end diff --git a/lib/remover/team.rb b/lib/remover/team.rb index f8b8ac8..382b910 100644 --- a/lib/remover/team.rb +++ b/lib/remover/team.rb @@ -14,6 +14,44 @@ def name github_team.name end + def delete_team + github_client.delete_team(github_team.id) + end + + def members_url + if with_members? + users_hash = Hash(*github_client.team_members(github_team.id)) + users_hash[:html_url].to_s + else + 'no members' + end + end + + def repositories_url + if with_repositories? + repos_hash = Hash(*github_client.team_repositories(github_team.id)) + repos_hash[:html_url].to_s + else + 'no repositories' + end + end + + def members_amount + if with_members? + github_client.team_members(github_team.id).size + else + 0 + end + end + + def repositories_amount + if with_repositories? + github_client.team_repositories(github_team.id).size + else + 0 + end + end + private def with_members? diff --git a/spec/remover/cli_spec.rb b/spec/remover/cli_spec.rb new file mode 100644 index 0000000..d576ddd --- /dev/null +++ b/spec/remover/cli_spec.rb @@ -0,0 +1,78 @@ +describe Remover::CLI do + let(:options) do + { 'organization' => 'FlatSchool', + 'login' => 'fs-school', + 'password' => '123456', + 'color' => :blue, + 'verbose' => 'true', + 'delete' => 'true' + } + end + + let(:configuration) { Remover::Configuration.new } + + describe '#color' do + before do + configuration.load_from_options!(options) + end + + it 'returns true' do + expect(configuration.color).to eq(:blue) + end + + context '--color not used' do + let(:options) do + { + 'color' => :white + } + end + + it 'is default => :white' do + expect(configuration.color).to eq(:white) + end + end + end + + describe '#verbose' do + before do + configuration.load_from_options!(options) + end + + it 'returns true' do + expect(configuration.verbose).to eq('true') + end + + context '--verbose not used' do + let(:options) do + { + 'verbose' => 'false' + } + end + it 'returns false' do + expect(configuration.verbose).not_to eq('true') + end + end + end + + describe '#delete_team' do + before do + configuration.load_from_options!(options) + end + + it 'returns true' do + expect(configuration.delete).to eq('true') + end + + context 'if --delete key not entered' do + let(:options) do + { + 'delete' => 'false' + } + end + + it 'returns false' do + expect(configuration.delete).not_to eq('true') + end + end + end +end diff --git a/spec/remover/configuration_spec.rb b/spec/remover/configuration_spec.rb index b656109..90b8f75 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', + 'color' => 'blue', + 'verbose' => '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.color).to eq('blue') + expect(configuration.verbose).to eq('true') end end end diff --git a/spec/remover/team_spec.rb b/spec/remover/team_spec.rb index f666388..88dafa4 100644 --- a/spec/remover/team_spec.rb +++ b/spec/remover/team_spec.rb @@ -9,6 +9,68 @@ end end + describe '#members_url' do + before do + allow(github_client).to receive(:team_members) { [] } + end + + it 'returns array' do + expect(team.members_url).to be_a(String) + end + end + + describe '#repositories_url' do + before do + allow(github_client).to receive(:team_repositories) { [] } + end + + it 'returns array' do + expect(team.repositories_url).to be_a(String) + end + end + + describe '#members' do + before do + allow(github_client).to receive(:team_members) { [] } + end + + it 'returns amount of members' do + expect(team.members_amount).to eq(github_client.team_members(github_team.id).size) + end + end + + describe '#repositories_amount' do + before do + allow(github_client).to receive(:team_repositories) { [] } + end + + it 'returns amount of repos' do + expect(team.repositories_amount).to eq(github_client.team_repositories(github_team.id).size) + 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 '#used' do let(:members) { [double('Github Member')] } let(:repositories) { [double('Github Repository')] }