Skip to content
This repository was archived by the owner on Jun 27, 2019. It is now read-only.

Command line and hide password #17

Open
wants to merge 15 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
iso-2022-jp
shift_jis
*.swp
*iso-2022-jp*
125 changes: 83 additions & 42 deletions csv_issues_to_github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,106 @@
require 'octokit'
require 'faraday'
require 'csv'
require 'optparse'
require 'ostruct'
require 'highline/import'

def password_prompt(message, mask='*')
ask(message) { |q| q.echo = mask}
end

# BEGIN INTERACTIVE SECTION
# Comment out this section (from here down to where the end is marked) if you want to use this interactively

puts "Username:"
username = gets.chomp
if username == ""
abort("You need to supply a username. Thank you, come again.")
end
options = OpenStruct.new
options.organization = ""
options.repository = ""
options.username = ""
options.password = ""
options.authkey = ""
options.file = ""

opts_parser = OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.separator ""
opts.separator "Specific options:"

opts.on("-o ORGANIZATION", "--organization ORGANIZATION", String, "Define you repo's local") do |o|
if o == ""
puts options
exit
end
options.organization = o
end

opts.on("-r REPO", "--repository REPO", String, "Define you repo name") do |r|
if r == ""
puts options
exit
end

options.repository = r
end

opts.on("-u USER", "--username USER", String, "Your username") do |u|
options.username = u
end

opts.on("-k KEY", "--authkey KEY", String, "Your 40 char token") do |k|
options.authkey = k
end

opts.on("-f FILE", "--file FILE", String, "CSV file") do |f|
if f == ""
puts options
exit
end
options.file = f
end

opts.separator ""
opts.separator "Common options:"

# No argument, shows at tail. This will print an options summary.
# Try it and see!
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end

puts "Password:"
password = gets.chomp
if password == ""
abort("You need to supply a password. Thank you, come again.")
end

puts "Path for the CSV file you want to use?"
input_file = gets.chomp
if input_file == ""
abort("You need to supply a CSV file. Thank you, come again.")
end
opts_parser.parse!(ARGV)

puts "Organization?"
org = gets.chomp
if org == ""
abort("You need to supply an organization. Thank you, come again.")
end
org_repo = options.organization + "/" + options.repository

puts "Repository?"
repo = gets.chomp
if repo == ""
abort("You need to supply a repository. Thank you, come again.")
if options.authkey == ""
options.password = password_prompt('#options.username password: ')
client = Octokit::Client.new(:login => options.username, :password => options.password)
else
client = Octokit::Client.new(:access_token => options.authkey)
end
user = client.user
user.login

# END INTERACTIVE SECTION
csv_text = File.read(options.file)
csv = CSV.parse(csv_text, :headers => true)

csv.each do |row|
puts "Creating issue: #{row['title']}"

# BEGIN HARD-CODED SECTION
# Un-comment out this section (from here down to where the end is marked) if you want to use this without any interaction
# All of these need to be filled out in order for it to work
=begin
input_file = ""
username = ""
password = ""
org = ""
repo = ""
=end # END HARD-CODED SECTION

org_repo = org + "/" + repo
options = {
:assignee => row['assignee_username'],
:labels => []}

client = Octokit::Client.new(:login => username, :password => password)
$i=1
while row['label#$i'] != nil do
options.labels << row['label#$i']
end

csv_text = File.read(input_file)
csv = CSV.parse(csv_text, :headers => true)
client.create_issue(org_repo, row['title'], row['description'], options)

csv.each do |row|
client.create_issue(org_repo, row['title'], row['description'], options = {
:assignee => row['assignee_username'],
:labels => [row['label1'],row['label2'],row['label3']]}) #Add or remove label columns here.
puts "Imported issue: #{row['title']}"
end

4 changes: 4 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM ruby:2.1-onbuild

RUN gem install octokit

1 change: 1 addition & 0 deletions docker/csv_issues_to_github.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker run -it --rm --name issue-csv-github -v "$PWD":/usr/src/myapp -w /usr/src/myapp ruby:2.1 ruby csv_issues_to_github.rb
130 changes: 82 additions & 48 deletions github_issues_to_csv.rb
Original file line number Diff line number Diff line change
@@ -1,69 +1,103 @@
#!/usr/bin/ruby
# See the README for how to use this.

require 'rubygems'
require 'octokit'
require 'faraday'
require 'csv'
require 'date'
require 'optparse'
require 'ostruct'
require 'highline/import'

def password_prompt(message, mask='*')
ask(message) { |q| q.echo = mask}
end

# BEGIN INTERACTIVE SECTION
# Comment out this section (from here down to where the end is marked) if you want to use this interactively

puts "Username:"
USERNAME = gets.chomp
if USERNAME == ""
abort("You need to supply a username. Thank you, come again.")
end
options = OpenStruct.new
options.organization = ""
options.repository = ""
options.username = ""
options.password = ""
options.authkey = ""
options.file = ""
options.milestone = ""

opts_parser = OptionParser.new do |opts|
opts.banner = "Usage: example.rb [options]"
opts.separator ""
opts.separator "Specific options:"

opts.on("-o ORGANIZATION", "--organization ORGANIZATION", String, "Define you repo's local") do |o|
if o == ""
puts options
exit
end
options.organization = o
end

puts "Password:"
PASSWORD = gets.chomp
if PASSWORD == ""
abort("You need to supply a password. Thank you, come again.")
end
opts.on("-r REPO", "--repository REPO", String, "Define you repo name") do |r|
if r == ""
puts options
exit
end

puts "Name of the file you want to create? (.csv will be appended automatically)"
OUTPUT_FILE = gets.chomp
if OUTPUT_FILE == ""
abort("You need to supply a CSV file. Thank you, come again.")
end
options.repository = r
end

puts "Organization?"
ORG = gets.chomp
if ORG == ""
abort("You need to supply an organization. Thank you, come again.")
end
opts.on("-u USER", "--username USER", String, "Your username") do |u|
options.username = u
end

puts "Repository?"
REPO = gets.chomp
if REPO == ""
abort("You need to supply a repository. Thank you, come again.")
end
opts.on("-k KEY", "--authkey KEY", String, "Your 40 char token") do |k|
options.authkey = k
end

puts "Do you want just one Milestone? If so, enter it now. Leave this blank to get the entire repo."
TARGET_MILESTONE = gets.chomp
opts.on("-f FILE", "--file FILE", String, "CSV file") do |f|
if f == ""
puts options
exit
end
options.file = f
end

opts.on("-m MILESTONE", "--milestone MILESTONE", String, "Milestone Target") do |m|
if m == ""
puts options
exit
end
options.milestone = m
end

# END INTERACTIVE SECTION
opts.separator ""
opts.separator "Common options:"

# No argument, shows at tail. This will print an options summary.
# Try it and see!
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end

# BEGIN HARD-CODED SECTION
# Un-comment out this section (from here down to where the end is marked) if you want to use this without any interaction
# All of these need to be filled out in order for it to work
=begin
OUTPUT_FILE = ""
USERNAME = "" # Put your GitHub username inside the quotes
PASSWORD = "" # Put your GitHub password inside the quotes
ORG = "" # Put your organization (or username if you have no org) name here
REPO = "" # Put the repository name here
# Want to only get a single milestone? Put the milestone name in here:
TARGET_MILESTONE="" # keep this equal to "" if you want all milestones
=end # END HARD-CODED SECTION
end

opts_parser.parse!(ARGV)

# Your local timezone offset to convert times
TIMEZONE_OFFSET="-4"
org_repo = options.organization + "/" + options.repository

if options.authkey == ""
options.password = password_prompt('#{options.username} password: ')
client = Octokit::Client.new(:login => options.username, :password => options.password)
else
client = Octokit::Client.new(:access_token => options.authkey)
end
user = client.user
user.login

client = Octokit::Client.new(:login => USERNAME, :password => PASSWORD)

csv = CSV.new(File.open(File.dirname(__FILE__) + "/" + OUTPUT_FILE + ".csv", 'w'))
csv = CSV.new(File.open(File.dirname(__FILE__) + "/" + options.file + ".csv", 'w', {:col_sep => ";"}))

puts "Initialising CSV file..."
#CSV Headers
Expand All @@ -88,14 +122,14 @@
page = 0
begin
page = page +1
temp_issues = client.list_issues("#{ORG}/#{REPO}", :state => "closed", :page => page)
temp_issues = client.list_issues("#{options.organization}/#{options.repository}", :state => "closed", :page => page)
issues = issues + temp_issues;
end while not temp_issues.empty?
temp_issues = []
page = 0
begin
page = page +1
temp_issues = client.list_issues("#{ORG}/#{REPO}", :state => "open", :page => page)
temp_issues = client.list_issues("#{options.organization}/#{options.repository}", :state => "open", :page => page)
issues = issues + temp_issues;
end while not temp_issues.empty?

Expand All @@ -121,7 +155,7 @@
milestone = milestone['title']
end

if ((TARGET_MILESTONE == "") || (milestone == TARGET_MILESTONE))
if ((options.milestone == "") || (milestone == options.milestone))
# Needs to match the header order above, date format are based on Jira default
row = [
issue['number'],
Expand Down
5 changes: 5 additions & 0 deletions test.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
title,description,assignee_username,label1,label2
Issue 1,decription issue 1,wapmesquita,bug,duplicate,
Issue 01,decription issue 1,wapmesquita,bug,duplicate,
Issue 2,decription issue 2,,bug,duplicate,
Issue 3,decription issue 3,,