Skip to content
This repository has been archived by the owner on Feb 5, 2018. It is now read-only.

Add --forks option to clone_repos #93

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 76 additions & 32 deletions lib/teachers_pet/actions/clone_repos.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,99 @@ def read_info
@organization = self.options[:organization]
end

def load_files
@students = self.read_students_file
def students
@students ||= self.read_students_file.keys
end

def get_clone_method
def web_endpoint
self.options[:web]
end

def ssh_endpoint
@ssh_endpoint ||= self.web_endpoint.gsub("https://","git@").gsub("/",":")
end

def clone_method
self.options[:clone_method]
end

def create
cloneMethod = self.get_clone_method
def clone_endpoint
if self.clone_method == 'https'
self.web_endpoint
else
self.ssh_endpoint
end
end

# create a repo for each student
self.init_client
def clone_command(username)
path = self.repo_path(username)
"git clone #{self.clone_endpoint}#{path}.git #{@repository}/#{username}"
end

def clone(username)
command = self.clone_command(username)
puts " --> Cloning: '#{command}'"
self.execute(command)
end

def repo_owner(username)
if self.options[:forks]
username
else
@organization
end
end

def repo_name(username)
if self.options[:forks]
@repository
else
"#{username}-#{@repository}"
end
end

def repo_path(username)
name = self.repo_name(username)
owner = self.repo_owner(username)
"#{owner}/#{name}"
end

def clone_student(username)
if self.client.repository?(self.repo_owner(username), self.repo_name(username))
self.clone(username)
else
path = self.repo_path(username)
puts " ** ERROR ** - Can't find expected repository '#{path}'"
end
end

def verify_org_exists
org_hash = self.client.organization(@organization)
abort('Organization could not be found') if org_hash.nil?
if org_hash.nil?
abort('Organization could not be found')
end
puts "Found organization at: #{org_hash[:url]}"
end

def clone_all
self.init_client

unless self.options[:forks]
self.verify_org_exists
end

self.execute("mkdir -p #{@repository}")

# Load the teams - there should be one team per student.
org_teams = self.client.get_teams_by_name(@organization)
# For each student - pull the repository if it exists
puts "\nCloning assignment repositories for students..."
@students.keys.each do |student|
unless org_teams.key?(student)
puts(" ** ERROR ** - no team for #{student}")
next
end
repo_name = "#{student}-#{@repository}"

unless self.client.repository?(@organization, repo_name)
puts " ** ERROR ** - Can't find expected repository '#{repo_name}'"
next
end

web = self.options[:web]
sshEndpoint = web.gsub("https://","git@").gsub("/",":")
command = "git clone #{sshEndpoint}#{@organization}/#{repo_name}.git"
if cloneMethod.eql?('https')
command = "git clone #{web}#{@organization}/#{repo_name}.git"
end
puts " --> Cloning: '#{command}'"
self.execute(command)
self.students.each do |student|
self.clone_student(student)
end
end

def run
self.read_info
self.load_files
self.create
self.clone_all
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/teachers_pet/commands/clone_repos.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module TeachersPet
class Cli
option :organization, required: true
option :repository, required: true
option :forks, type: :boolean, default: false, desc: "If true, will clone forks of the repository from the provided list of students. Defaults to cloning repositories of the form <organization>/<user>-<repository>."
option :clone_method, default: 'https', desc: "'https' or 'ssh'"

students_option
Expand Down
34 changes: 31 additions & 3 deletions spec/commands/clone_repos_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
describe 'clone_repos' do
include CommandHelpers

it "runs" do
it "clones all private repositories" do
request_stubs = []

request_stubs << stub_get_json('https://testteacher:[email protected]/orgs/testorg',
login: 'testorg',
url: 'https://api.github.com/orgs/testorg'
)
request_stubs << stub_get_json('https://testteacher:[email protected]/orgs/testorg/teams?per_page=100', student_teams)

expect_any_instance_of(TeachersPet::Actions::CloneRepos).to receive(:execute).with("mkdir -p testrepo").once

student_usernames.each do |username|
request_stubs << stub_get_json("https://testteacher:[email protected]/repos/testorg/#{username}-testrepo", {})
expect_any_instance_of(TeachersPet::Actions::CloneRepos).to receive(:execute).with("git clone https://github.com/testorg/#{username}-testrepo.git").once
expect_any_instance_of(TeachersPet::Actions::CloneRepos).to receive(:execute).with("git clone https://github.com/testorg/#{username}-testrepo.git testrepo/#{username}").once
end

teachers_pet(:clone_repos,
Expand All @@ -30,4 +32,30 @@
expect(request_stub).to have_been_requested.once
end
end

it "clones forks of a repository" do
request_stubs = []

expect_any_instance_of(TeachersPet::Actions::CloneRepos).to receive(:execute).with("mkdir -p testrepo").once

student_usernames.each do |username|
request_stubs << stub_get_json("https://testteacher:[email protected]/repos/#{username}/testrepo", {})
expect_any_instance_of(TeachersPet::Actions::CloneRepos).to receive(:execute).with("git clone https://github.com/#{username}/testrepo.git testrepo/#{username}").once
end

teachers_pet(:clone_repos,
repository: 'testrepo',
organization: 'testorg', # TODO not actually needed

students: students_list_fixture_path,
forks: true,

username: 'testteacher',
password: 'abc123'
)

request_stubs.each do |request_stub|
expect(request_stub).to have_been_requested.once
end
end
end