codebase 3.1.5 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/codebase.rb CHANGED
@@ -1,28 +1,44 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
 
3
+ require 'rubygems'
4
+ require 'json'
5
+ require 'highline/import'
6
+ HighLine.track_eof = false
7
+
3
8
  require 'codebase/command'
4
- require 'codebase/directory'
5
9
 
6
10
  module Codebase
7
-
11
+
8
12
  class Error < RuntimeError; end
13
+ class NotConfiguredError < StandardError; end
14
+ class MustBeInRepositoryError < StandardError; end
9
15
 
10
16
  extend self
11
17
 
12
18
  def run(args)
13
19
  begin
14
- repository = Directory.new
15
20
  method = args.shift || 'default'
16
- command = Codebase::Command.new(repository, args)
21
+ command = Codebase::Command.new
22
+
17
23
  if command.respond_to?(method)
18
24
  command.send(method, *args)
19
25
  else
20
26
  $stderr.puts "Command Not Found - please check http://docs.codebasehq.com/gem for documentation."
27
+ Process.exit(1)
21
28
  end
29
+
22
30
  rescue ArgumentError
23
31
  $stderr.puts "Invalid arguments provided to method. Check documentation."
32
+ Process.exit(1)
33
+ rescue Codebase::NotConfiguredError
34
+ puts "[Error] You have not configured the Codebase gem yet. Run 'cb setup' to run the setup tool."
35
+ Process.exit(1)
36
+ rescue Codebase::MustBeInRepositoryError
37
+ puts "[Error] You must be inside a Codebase repository to run this command."
38
+ Process.exit(1)
24
39
  rescue Codebase::Error => e
25
40
  $stderr.puts e.message
41
+ Process.exit(1)
26
42
  end
27
43
 
28
44
  end
@@ -1,37 +1,63 @@
1
- require 'codebase/commands/launchers'
2
- require 'codebase/commands/branches'
3
1
  require 'codebase/commands/setup'
4
- require 'codebase/commands/deployments'
5
2
  require 'codebase/commands/clone'
3
+ require 'codebase/commands/branches'
4
+ require 'codebase/commands/keys'
6
5
 
7
6
  module Codebase
8
7
  class Command
9
8
 
10
- include Codebase::Commands::Launchers
11
- include Codebase::Commands::Branches
12
9
  include Codebase::Commands::Setup
13
- include Codebase::Commands::Deployments
14
10
  include Codebase::Commands::Clone
15
-
16
- attr_reader :directory, :args
11
+ include Codebase::Commands::Branches
12
+ include Codebase::Commands::Keys
17
13
 
18
- def initialize(directory, args)
19
- @directory, @args = directory, args
14
+ def default
15
+ puts "CodebaseHQ"
16
+ puts "See http://docs.codebasehq.com/gem for documentation"
17
+ if configured?
18
+ puts "-> System configured for #{username} at #{domain}"
19
+ else
20
+ puts "-> Not configured yet. Run 'cb setup' to configure your local computer."
21
+ end
20
22
  end
21
23
 
22
24
  private
23
-
24
- def launch(*args)
25
- begin
26
- require 'rubygems'
27
- require 'launchy'
28
- url = "http://#{directory.domain}/" + args.join('/').gsub(/\?\z/, "")
29
- Launchy::Browser.new.visit(url)
30
- rescue Gem::LoadError
31
- raise Codebase::Error, "Sorry, you need to install launchy to do that - give '[sudo] gem install launchy' a go."
25
+
26
+ def configured?
27
+ domain && username && apikey
28
+ end
29
+
30
+ def domain
31
+ @domain ||= git_config_variable(:domain)
32
+ end
33
+
34
+ def username
35
+ @username ||= git_config_variable(:username)
36
+ end
37
+
38
+ def apikey
39
+ @apikey ||= git_config_variable(:apikey)
40
+ end
41
+
42
+ def in_repository?
43
+ repository_status != :false
44
+ end
45
+
46
+ def repository_properties
47
+ return false unless in_repository?
48
+ origin_name = (git_config_variable(:remote) || 'origin')
49
+ remote_url = git_config_variable("remote.#{origin_name}.url")
50
+ if remote_url =~ /git\@(gitbase|codebasehq|cbhqdev)\.com:(.*)\/(.*)\/(.*)\.git/
51
+ {:domain => $1, :account => $2, :project => $3, :repository => $4}
52
+ else
53
+ raise Codebase::Error, "Invalid Codebase repository (#{remote_url})"
32
54
  end
33
55
  end
34
56
 
57
+ def repository_status
58
+ @in_repository ||= (`git branch 2> /dev/null` && $?.success? ? true : :false)
59
+ end
60
+
35
61
  def execute_commands(array)
36
62
  for command in array
37
63
  puts "\e[44;33m" + command + "\e[0m"
@@ -48,7 +74,11 @@ module Codebase
48
74
  end
49
75
 
50
76
  def git_config_variable(name)
51
- r = `git config --global codebase.#{name.to_s}`.chomp
77
+ if name.is_a?(Symbol)
78
+ r = `git config codebase.#{name.to_s}`.chomp
79
+ else
80
+ r = `git config #{name.to_s}`.chomp
81
+ end
52
82
  r.empty? ? nil : r
53
83
  end
54
84
 
@@ -62,10 +92,9 @@ module Codebase
62
92
  else
63
93
  req = Net::HTTP::Get.new(uri.path)
64
94
  end
65
-
66
95
  req.basic_auth(username, password)
67
- req.add_field("Accept", "application/xml")
68
- req.add_field("Content-type", "application/xml")
96
+ req.add_field("Accept", "application/json")
97
+ req.add_field("Content-type", "application/json")
69
98
  res = Net::HTTP.new(uri.host, uri.port)
70
99
  if url.include?('https://')
71
100
  res.use_ssl = true
@@ -75,18 +104,19 @@ module Codebase
75
104
  case res
76
105
  when Net::HTTPSuccess
77
106
  return res.body
107
+ when Net::HTTPServiceUnavailable
108
+ puts "The API is currently unavailable. Please check your codebase account has been enabled for API access."
109
+ Process.exit(1)
78
110
  when Net::HTTPForbidden, Net::HTTPUnauthorized
79
111
  puts "Access Denied. Ensure you have correctly configured your local Gem installation using the 'cb setup' command."
80
112
  Process.exit(1)
81
113
  else
82
- puts res.body
83
-
84
114
  return false
85
115
  end
86
116
  end
87
117
 
88
118
  def api(path, data = nil)
89
- api_request("http://#{directory.domain}/#{path}", git_config_variable(:username), git_config_variable(:apikey), data)
119
+ api_request("http://#{domain}/#{path}", git_config_variable(:username), git_config_variable(:apikey), data)
90
120
  end
91
121
 
92
122
  end
@@ -2,13 +2,15 @@ module Codebase
2
2
  module Commands
3
3
  module Clone
4
4
 
5
- require 'xmlsimple'
6
- require 'highline/import'
7
- HighLine.track_eof = false
5
+ ## =========================================================================================================
6
+ ## Interactive Clone
7
+ ## =========================================================================================================
8
8
 
9
9
  def clone
10
- projects = XmlSimple.xml_in(api('projects'))
11
- projects = projects['project'].select{|p| p["status"].first == 'active'}
10
+ raise Codebase::NotConfiguredError unless configured?
11
+
12
+ projects = JSON.parse(api('projects'))
13
+ projects = projects.select{|p| p["project"]["status"].first == 'active'}.map{|p| p['project']}
12
14
 
13
15
  ## Please somebody tell me there is a better way to do this using highline...
14
16
  project_hash = {}
@@ -17,28 +19,29 @@ module Codebase
17
19
  menu.prompt = "Please select a project: "
18
20
  count = 0
19
21
  for project in projects
20
- project_hash[project['name'].first] = project['permalink'].first
21
- menu.choice(project['name'].first)
22
+ project_hash[project['name']] = project['permalink']
23
+ menu.choice(project['name'])
22
24
  end
23
25
  end
24
26
 
25
27
  project = project_hash[project_id]
26
28
 
27
- repositories = XmlSimple.xml_in(api("#{project}/repositories"))
28
- repositories = repositories['repository']
29
+ repositories = JSON.parse(api("#{project}/repositories"))
30
+ repositories = repositories.map{|r| r['repository']}
29
31
 
30
32
  repos_hash = {}
31
33
  repo_id = choose do |menu|
32
34
  menu.select_by = :index
33
35
  menu.prompt = "Please select a repository:"
34
36
  for repository in repositories
35
- repos_hash[repository['name'].first] = repository
36
- menu.choice(repository['name'].first)
37
+ repos_hash[repository['name']] = repository
38
+ menu.choice(repository['name'])
37
39
  end
38
40
  end
39
41
 
40
- repository = repos_hash[repo_id]['permalink'].first
41
- clone_url = repos_hash[repo_id]['clone-url'].first
42
+ repository = repos_hash[repo_id]['permalink']
43
+ clone_url = repos_hash[repo_id]['clone_url']
44
+ scm = repos_hash[repo_id]['scm']
42
45
 
43
46
  export_path = File.join(project, repository)
44
47
  folder = ask("Where would you like to clone this repository to? (default: #{export_path})")
@@ -47,7 +50,14 @@ module Codebase
47
50
  end
48
51
 
49
52
  system("mkdir -p #{export_path}")
50
- exec("git clone #{clone_url} #{export_path}")
53
+
54
+ case scm
55
+ when 'git' then exec("git clone #{clone_url} #{export_path}")
56
+ when 'hg' then exec("hg clone ssh://#{clone_url} #{export_path}")
57
+ when 'svn' then exec("svn checkout #{clone_url} #{export_path}")
58
+ else
59
+ puts "Unsupported SCM."
60
+ end
51
61
  end
52
62
 
53
63
  end
@@ -0,0 +1,36 @@
1
+ module Codebase
2
+ module Commands
3
+ module Keys
4
+
5
+ ## =========================================================================================================
6
+ ## Keys
7
+ ## =========================================================================================================
8
+
9
+ require 'hirb'
10
+ include Hirb::Console
11
+
12
+ def keys
13
+ keys = api("users/#{username}/public_keys")
14
+ keys = JSON.parse(keys).map{|k| k['public_key_join']}
15
+ keys = keys.map{|k| {:description => k['description'], :key => k['key'][0, 50] + '...' }}
16
+ table keys, :fields => [:description, :key], :headers => {:description => 'Description', :key => 'Key'}
17
+ end
18
+
19
+ def add_key(path = nil)
20
+ path = File.expand_path(".ssh/id_rsa.pub", "~") if path.nil?
21
+ unless File.exist?(path)
22
+ puts "Key file not found at '#{path}'"
23
+ Process.exit(1)
24
+ end
25
+
26
+ data = {'public_key' => {'description' => "Key", 'key' => File.read(path)}}.to_json
27
+ if api("users/#{username}/public_keys", data)
28
+ puts "Successfully added key."
29
+ else
30
+ puts "An error occured while adding your key."
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -1,47 +1,79 @@
1
1
  module Codebase
2
2
  module Commands
3
3
  module Setup
4
-
5
- require 'rubygems'
6
- require 'highline/import'
4
+
5
+ ## =========================================================================================================
6
+ ## API Setup Tools
7
+ ## =========================================================================================================
7
8
 
8
9
  def setup
10
+
11
+ ## We need git...
12
+ unless `which git` && $?.success?
13
+ puts "To use the Codebase gem you must have Git installed on your local computer. Git is used to store"
14
+ puts "important configuration variables which allow the gem to function."
15
+ Process.exit(1)
16
+ end
17
+
9
18
  puts "\e[33;44mWelcome to the CodebaseHQ Initial Setup Tool\e[0m"
10
19
  puts "This tool will get your local computer configured to use your codebase account. It will automatically configure"
11
20
  puts "the gem for API access so you can use many of the gem functions."
12
21
  puts
13
22
 
14
- ## Is this configured?
15
- if u = git_config_variable(:username)
16
- puts "This system is already configured as \e[32m#{u}\e[0m."
17
- puts "You can run 'cb unsetup' to clear settings."
18
- return
19
- else
20
- ## Get some details
21
- domain = ask_with_validation("CodebaseHQ domain (e.g. widgetinc.codebasehq.com): ", /\A(\w+).(codebasehq|cbhqdev).(com|local)\z/)
22
- username = ask_with_validation("Username: ", /[\w\.]+/)
23
- password = ask_for_password('Password: ')
24
-
25
- ## Get the API key and save it...
26
- api_key = api_request("https://#{domain}/apikey", username, password)
27
- if api_key
28
- api_key = api_key.chomp
29
- system("git config --global codebase.username #{username}")
30
- system("git config --global codebase.apikey #{api_key}")
31
- system("git config --global codebase.domain #{domain}")
32
- puts "\e[32mConfigured Codebase API authentication properties.\e[0m"
23
+ ## Are you in a repository?
24
+ if in_repository?
25
+ puts "You are currently in a repository directory."
26
+ if agree("Would you like to only apply configuration to actions carried out from within this directory?")
27
+ global = ''
28
+ puts "OK, we'll add your API details to this repository only."
33
29
  else
34
- puts "\e[37;41mAccess Denied. Please ensure you have entered your username & password correctly and try again.\e[0m"
35
- return
30
+ global = '--global'
31
+ puts "OK, we'll configure your API details for your whole user account."
32
+ end
33
+ end
34
+
35
+ ## Is this configured?
36
+ if configured? && !global.empty?
37
+ puts
38
+ puts "This system is already configured as \e[32m#{username}\e[0m."
39
+ unless agree("Do you wish to continue?")
40
+ Process.exit(0)
36
41
  end
37
42
  end
38
-
43
+
44
+ puts
45
+
46
+ ## Get some details
47
+ domain = ask_with_validation("CodebaseHQ domain (e.g. widgetinc.codebasehq.com): ", /\A(\w+).(codebasehq|cbhqdev).(com|local)\z/)
48
+ username = ask_with_validation("Username: ", /[\w\.]+/)
49
+ password = ask("Password: ") { |q| q.echo = false }
50
+
51
+ ## Get the API key and save it...
52
+ user_properties = api_request("https://#{domain}/profile", username, password)
53
+
54
+ if user_properties
55
+ user = JSON.parse(user_properties)["user"]
56
+ system("git config #{global} codebase.username #{username}")
57
+ system("git config #{global} codebase.apikey #{user['api_key']}")
58
+ system("git config #{global} codebase.domain #{domain}")
59
+ system("git config #{global} user.name '#{user['first_name']} #{user['last_name']}'")
60
+ puts "Set user.name to '#{user['first_name']} #{user['last_name']}'"
61
+ system("git config #{global} user.email #{user['email_address']}")
62
+ puts "Set user.email to '#{user['email_address']}'"
63
+ puts "\e[32mConfigured Codebase API authentication properties successfully.\e[0m"
64
+ else
65
+ puts "\e[37;41mAccess Denied. Please ensure you have entered your username & password correctly and try again.\e[0m"
66
+ return
67
+ end
68
+
39
69
  end
40
70
 
41
71
  def unsetup
42
- system("git config --global --unset codebase.username")
43
- system("git config --global --unset codebase.apikey")
44
- system("git config --global --unset codebase.domain")
72
+ ['', '--global'].each do |type|
73
+ system("git config #{type} --unset codebase.username")
74
+ system("git config #{type} --unset codebase.apikey")
75
+ system("git config #{type} --unset codebase.domain")
76
+ end
45
77
  puts "System has been unsetup. API details have been removed from your configuration."
46
78
  end
47
79
 
@@ -51,14 +83,6 @@ module Codebase
51
83
  ask(question) { |q| q.validate = regex }
52
84
  end
53
85
 
54
- def ask_for_password(question)
55
- system("stty -echo")
56
- password = ask(question)
57
- system("stty echo")
58
- puts
59
- password
60
- end
61
-
62
86
  end
63
87
  end
64
88
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codebase
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.5
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Cooke
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-26 00:00:00 +00:00
12
+ date: 2009-10-27 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -23,14 +23,14 @@ dependencies:
23
23
  version: 1.5.0
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
- name: xml-simple
26
+ name: json
27
27
  type: :runtime
28
28
  version_requirement:
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.12
33
+ version: 1.1.5
34
34
  version:
35
35
  description:
36
36
  email: adam@atechmedia.com
@@ -47,10 +47,8 @@ files:
47
47
  - lib/codebase/command.rb
48
48
  - lib/codebase/commands/branches.rb
49
49
  - lib/codebase/commands/clone.rb
50
- - lib/codebase/commands/deployments.rb
51
- - lib/codebase/commands/launchers.rb
50
+ - lib/codebase/commands/keys.rb
52
51
  - lib/codebase/commands/setup.rb
53
- - lib/codebase/directory.rb
54
52
  - lib/codebase/recipes.rb
55
53
  - lib/codebase.rb
56
54
  has_rdoc: true
@@ -1,33 +0,0 @@
1
- module Codebase
2
- module Commands
3
- module Deployments
4
-
5
- def track_deploy(revision)
6
-
7
- unless directory.repository?
8
- puts "This is not a valid Codebase repository. Ensure you are currently in the directory of the repository you wish to track."
9
- return
10
- end
11
-
12
- xml = []
13
- xml << "<deployment>"
14
- xml << "<servers>#{ENV['CBSERVERS']}</servers>"
15
- xml << "<revision>#{revision}</revision>"
16
- xml << "<environment>#{ENV['CBENVIRONMENT']}</environment>"
17
- xml << "<branch>#{ENV['CBBRANCH']}</branch>"
18
- xml << "</deployment>"
19
-
20
- username = git_config_variable(:username)
21
- password = git_config_variable(:apikey)
22
-
23
- if api_request("http://#{directory.account}.codebasehq.com/#{directory.project}/#{directory.repository}/deployments", username, password, xml.join)
24
- puts "\e[32mDeployment tracked successfully.\e[0m"
25
- else
26
- puts "\e[31mDeployment was not successfully tracked.\e[0m"
27
- end
28
-
29
- end
30
-
31
- end
32
- end
33
- end
@@ -1,70 +0,0 @@
1
- module Codebase
2
- module Commands
3
- module Launchers
4
-
5
- ## =========================================================================================================
6
- ## Launchers
7
- ## =========================================================================================================
8
-
9
- def default
10
- if directory.repository?
11
- launch directory.project
12
- else
13
- launch
14
- end
15
- end
16
- alias_method :dashboard, :default
17
-
18
- def messages
19
- launch 'messages'
20
- end
21
- alias_method :me, :messages
22
-
23
- def tickets
24
- launch directory.project, 'tickets'
25
- end
26
- alias_method :ti, :tickets
27
-
28
- def new_ticket
29
- launch directory.project, 'tickets', 'new'
30
- end
31
- alias_method :nti, :new_ticket
32
-
33
- def milestones
34
- launch directory.project, 'milestones'
35
- end
36
- alias_method :mi, :milestones
37
-
38
- def time
39
- launch directory.project, 'time'
40
- end
41
- alias_method :tm, :time
42
-
43
- def wiki
44
- launch directory.project, 'wiki'
45
- end
46
- alias_method :wi, :wiki
47
-
48
- def browser
49
- launch directory.project, directory.repository, 'tree', directory.working_branch
50
- end
51
- alias_method :br, :browser
52
-
53
- def commits
54
- launch directory.project, directory.repository, 'commits', directory.working_branch
55
- end
56
- alias_method :co, :commits
57
-
58
- def deployments
59
- launch directory.project, directory.repository, 'deployments'
60
- end
61
- alias_method :de, :deployments
62
-
63
- def tasks
64
- launch directory.project, directory.repository, 'tasks', directory.working_branch
65
- end
66
- alias_method :ta, :tasks
67
-
68
- end
69
- end
70
- end
@@ -1,73 +0,0 @@
1
- module Codebase
2
-
3
- ## A directory represents the directory the user is currently within.
4
-
5
- class Directory
6
-
7
- attr_reader :permalink, :account
8
-
9
- def initialize
10
- get_properties
11
- end
12
-
13
- def repository?
14
- working_branch
15
- end
16
-
17
- def working_branch
18
- @working_branch ||= git(:status).split("\n").first.split(" ").last rescue nil
19
- end
20
-
21
- def domain
22
- if @account
23
- "#{@account}.codebasehq.com"
24
- else
25
- git(:config, 'codebase.domain')
26
- end
27
- end
28
-
29
- def project
30
- raise Codebase::Error, "This is not a valid Codebase repository" unless repository?
31
- @project
32
- end
33
-
34
- def repository
35
- raise Codebase::Error, "This is not a valid Codebase repository" unless repository?
36
- @repository
37
- end
38
-
39
- def path
40
- File.expand_path(File.dirname(__FILE__))
41
- end
42
-
43
- private
44
-
45
- def codebase_remote_name
46
- configured = git(:config, 'codebase.remote')
47
- if configured.empty?
48
- 'origin'
49
- else
50
- configured
51
- end
52
- end
53
-
54
- ## Returns the project an repository names base on the git remote URL
55
- def get_properties
56
- return unless repository?
57
- remote_url = git(:config, "remote.#{codebase_remote_name}.url")
58
- if m = remote_url.match(/git\@(gitbase|codebasehq)\.com:(.*)\/(.*)\/(.*)\.git/)
59
- @account = m[2]
60
- @project = m[3]
61
- @repository = m[4]
62
- else
63
- raise Codebase::Error, "This is not a valid Codebase repository - #{remote_url} as '#{codebase_remote_name}'"
64
- end
65
- end
66
-
67
- def git(cmd, *args)
68
- `git #{cmd} #{args.join(' ')} 2> /dev/null`.strip.chomp
69
- end
70
-
71
-
72
- end
73
- end