jiveapps 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jiveapps (0.0.7)
4
+ jiveapps (0.0.8.alpha)
5
5
  activesupport (= 2.3.5)
6
6
  rest-client (= 1.6.1)
7
7
  rubigen (= 1.5.5)
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ === 0.0.8 2011-01-28
2
+ * Major Enhancements
3
+ * OAuth Services management for 3rd party services. Added jiveapps oauth:list, oauth:add, and oauth:remove commands.
4
+ * Display OAuth Services when running "jiveapps info"
5
+ * Auto-detect app name from within an app directory. No longer need to pass app name to "jiveapps info"
6
+ * Add recommended default module prefs and required features to template.
7
+
1
8
  === 0.0.7 2011-01-07
2
9
  * Bug fixes
3
10
  * If Git push fails, delete app and clean up.
@@ -1,8 +1,16 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Module>
3
- <ModulePrefs title="<%= name %>">
4
- <Require feature="views" />
3
+ <ModulePrefs title="<%= name %>"
4
+ author="<%= author_name = `git config --global user.name`.to_s.strip; author_name.length > 0 ? author_name : 'TODO: Author Name' %>"
5
+ height="300"
6
+ description="TODO: Replace with real description of <%= name %> inside app.xml: Module/ModulePrefs/description"
7
+ thumbnail="<%= Jiveapps::WEBHOST %>/apps/<%= name %>/images/j-icon-jaf-48.png">
5
8
  <Require feature="dynamic-height" />
9
+ <Require feature="jive-core-5.0.0" />
10
+ <Require feature="opensocial-1.0"/>
11
+ <Require feature="osapi"/>
12
+ <Require feature="settitle"/>
13
+ <Require feature="views" />
6
14
  </ModulePrefs>
7
15
 
8
16
  <!-- To begin development, remove the hello view and uncomment the home and canvas views below -->
@@ -0,0 +1,6 @@
1
+ gadgets.util.registerOnLoadHandler(function() {
2
+ // add code that should run on page load here
3
+
4
+ // resize app window to fit content
5
+ gadgets.window.adjustHeight();
6
+ });
@@ -30,7 +30,7 @@ class Jiveapps::Client
30
30
 
31
31
  def info(name)
32
32
  begin
33
- item = get("/apps/#{escape(name)}")
33
+ item = get("/apps/#{escape(name)}?extended=true")
34
34
  item.class == Hash && item['app'] ? item['app'] : item
35
35
  rescue RestClient::ResourceNotFound
36
36
  nil
@@ -97,12 +97,32 @@ class Jiveapps::Client
97
97
  delete("/ssh_keys/#{escape(name)}").to_s
98
98
  end
99
99
 
100
- def version
101
- get("/gem_version").to_s
100
+ ### OAuth Services
101
+
102
+ def oauth_services(app_name)
103
+ services = get("/apps/#{app_name}/oauth_services")
104
+
105
+ if services.class == Array
106
+ services.map { |item| item['oauth_service'] }
107
+ else
108
+ return []
109
+ end
110
+ end
111
+
112
+ def add_oauth_service(app_name, name, key, secret)
113
+ post("/apps/#{app_name}/oauth_services", {:oauth_service => {:name => name, :key => key, :secret => secret}})
114
+ end
115
+
116
+ def remove_oauth_service(app_name, name)
117
+ delete("/apps/#{app_name}/oauth_services/#{name}")
102
118
  end
103
119
 
104
120
  ### General
105
121
 
122
+ def version
123
+ get("/gem_version").to_s
124
+ end
125
+
106
126
  def on_warning(&blk)
107
127
  @warning_callback = blk
108
128
  end
@@ -195,4 +215,8 @@ class Jiveapps::Client
195
215
  end
196
216
  end
197
217
 
218
+ def git_host
219
+ host.gsub(/^(http|https):\/\//, '')
220
+ end
221
+
198
222
  end
@@ -25,6 +25,16 @@ module Jiveapps
25
25
  else
26
26
  error "Authentication failure"
27
27
  end
28
+ rescue RestClient::ResourceNotFound => e
29
+ error extract_not_found(e.http_body)
30
+ rescue RestClient::RequestFailed => e
31
+ error extract_error(e.http_body) unless e.http_code == 402
32
+ rescue RestClient::RequestTimeout
33
+ error "API request timed out. Please try again, or contact Jive via the community at https://developers.jivesoftware.com if this issue persists."
34
+ rescue CommandFailed => e
35
+ error e.message
36
+ rescue Interrupt => e
37
+ error "\n[canceled]"
28
38
  end
29
39
  end
30
40
 
@@ -55,12 +65,26 @@ module Jiveapps
55
65
  end
56
66
  end
57
67
 
68
+ def extract_not_found(body)
69
+ body =~ /^[\w\s]+ not found$/ ? body : "Resource not found"
70
+ end
71
+
72
+ def extract_error(body)
73
+ msg = parse_error_xml(body) || parse_error_json(body) || 'Internal server error'
74
+ msg.split("\n").map { |line| ' ! ' + line }.join("\n")
75
+ end
58
76
 
59
- ### Helpers
77
+ def parse_error_xml(body)
78
+ xml_errors = REXML::Document.new(body).elements.to_a("//errors/error")
79
+ msg = xml_errors.map { |a| a.text }.join(" / ")
80
+ return msg unless msg.empty?
81
+ rescue Exception
82
+ end
60
83
 
61
- def error(msg)
62
- STDERR.puts(msg)
63
- exit 1
84
+ def parse_error_json(body)
85
+ json = JSON.parse(body.to_s)
86
+ json['error']
87
+ rescue JSON::ParserError
64
88
  end
65
89
 
66
90
  end
@@ -24,17 +24,13 @@ module Jiveapps::Command
24
24
  end
25
25
 
26
26
  def info
27
- if app_name == nil
28
- display "No app specified."
29
- display "Run this command from app folder or set it by running: jiveapps info <app name>"
27
+ name = (args.first && !args.first =~ /^\-\-/) ? args.first : extract_app
28
+ app = jiveapps.info(name)
29
+ if app == nil
30
+ display "App not found."
30
31
  else
31
- app = jiveapps.info(app_name)
32
- if app == nil
33
- display "App not found."
34
- else
35
- display "=== #{app['name']}"
36
- display_app_info(app)
37
- end
32
+ display "=== #{app['name']}"
33
+ display_app_info(app)
38
34
  end
39
35
  end
40
36
 
@@ -152,6 +148,10 @@ module Jiveapps::Command
152
148
  display "Sandbox Dashboard URL: #{app['sandbox_dashboard_url']}"
153
149
  display "OAuth Consumer Key: #{app['oauth_consumer_key']}"
154
150
  display "OAuth Consumer Secret: #{app['oauth_consumer_secret']}"
151
+ if app['oauth_services'] && app['oauth_services'].length > 0
152
+ oauth_services = app['oauth_services'].map{ |o| o['oauth_service'] }
153
+ display_oauth_services(oauth_services, app['name'])
154
+ end
155
155
  end
156
156
 
157
157
  def app_name
@@ -3,17 +3,87 @@ module Jiveapps::Command
3
3
  include Jiveapps::Helpers
4
4
 
5
5
  attr_accessor :args
6
- def initialize(args)
6
+ attr_reader :autodetected_app
7
+ def initialize(args, jiveapps=nil)
7
8
  @args = args
8
- end
9
-
10
- def ask
11
- gets.strip
9
+ @jiveapps = jiveapps
10
+ @autodetected_app = false
12
11
  end
13
12
 
14
13
  def jiveapps
15
14
  @jiveapps ||= Jiveapps::Command.run_internal('auth:client', args)
16
15
  end
17
16
 
17
+ def extract_app(force=true)
18
+ app = extract_option('--app', false)
19
+ raise(CommandFailed, "You must specify an app name after --app") if app == false
20
+ unless app
21
+ app = extract_app_in_dir(Dir.pwd) ||
22
+ raise(CommandFailed, "No app specified.\nRun this command from app folder or set it adding --app <app name>") if force
23
+ @autodetected_app = true
24
+ end
25
+ app
26
+ end
27
+
28
+ def extract_app_in_dir(dir)
29
+ return unless remotes = git_remotes(dir)
30
+
31
+ if remote = extract_option('--remote')
32
+ remotes[remote]
33
+ elsif remote = extract_app_from_git_config
34
+ remotes[remote]
35
+ else
36
+ apps = remotes.values.uniq
37
+ case apps.size
38
+ when 0; return nil
39
+ when 1; return apps.first
40
+ else
41
+ current_dir_name = dir.split('/').last.downcase
42
+ apps.select { |a| a.downcase == current_dir_name }.first
43
+ end
44
+ end
45
+ end
46
+
47
+ def extract_app_from_git_config
48
+ remote = %x{ git config jiveapps.remote }.strip
49
+ remote == "" ? nil : remote
50
+ end
51
+
52
+ def git_remotes(base_dir)
53
+ git_config = "#{base_dir}/.git/config"
54
+ unless File.exists?(git_config)
55
+ parent = base_dir.split('/')[0..-2].join('/')
56
+ return git_remotes(parent) unless parent.empty?
57
+ else
58
+ remotes = {}
59
+ current_remote = nil
60
+ File.read(git_config).split(/\n/).each do |l|
61
+ current_remote = $1 if l.match(/\[remote \"([\w\d-]+)\"\]/)
62
+ app = (l.match(/url = git@#{jiveapps.git_host}:([\w\d-]+)\.git/) || [])[1]
63
+ if current_remote && app
64
+ remotes[current_remote.downcase] = app
65
+ current_remote = nil
66
+ end
67
+ end
68
+ return remotes
69
+ end
70
+ end
71
+
72
+ def extract_option(options, default=true)
73
+ values = options.is_a?(Array) ? options : [options]
74
+ return unless opt_index = args.select { |a| values.include? a }.first
75
+ opt_position = args.index(opt_index) + 1
76
+ if args.size > opt_position && opt_value = args[opt_position]
77
+ if opt_value.include?('--')
78
+ opt_value = nil
79
+ else
80
+ args.delete_at(opt_position)
81
+ end
82
+ end
83
+ opt_value ||= default
84
+ args.delete(opt_index)
85
+ block_given? ? yield(opt_value) : opt_value
86
+ end
87
+
18
88
  end
19
89
  end
@@ -12,13 +12,18 @@ The "jiveapps" program is a command line tool for building and hosting Jive App
12
12
  help # show this usage
13
13
 
14
14
  list # list your apps
15
- create <name> # create a new app
16
- install <name> # install an app on the sandbox (if you removed it, you can reinstall)
15
+ create <app_name> # create a new app
16
+ info [--app <app_name>] # displays information about an app
17
+ install [--app <app_name>] # install an app on the sandbox (if you removed it, you can reinstall)
17
18
 
18
19
  keys # show your user's public keys
19
20
  keys:add [<path to keyfile>] # add a public key. optionally include path
20
21
  keys:remove <keyname> # remove a key by name (user@host)
21
22
 
23
+ oauth # show the oauth services for this app
24
+ oauth:add <service_name> <key> <secret> # add an oauth service for this app
25
+ oauth:remove <service_name> # remove an oauth service for this app
26
+
22
27
  === Simple Workflow Example:
23
28
 
24
29
  $ jiveapps create myapp # create a new app named "myapp"
@@ -0,0 +1,41 @@
1
+ module Jiveapps::Command
2
+ class Oauth < Base
3
+
4
+ # Lists OAuth Services registered for this app
5
+ def list
6
+ app_name = extract_app
7
+
8
+ oauth_services = jiveapps.oauth_services(app_name)
9
+ display_oauth_services(oauth_services, app_name)
10
+ end
11
+ alias :index :list
12
+
13
+ # Register a new OAuth Service for use with this app
14
+ def add
15
+ usage = "\n Usage:\n $ jiveapps oauth:add <servicename> <key> <secret>"
16
+ app_name = extract_app
17
+ raise CommandFailed, "Missing 3 parameters: <servicename>, <key>, and <secret>#{usage}" unless servicename = args.shift
18
+ raise CommandFailed, "Missing 2 parameters: <key> and <secret>#{usage}" unless key = args.shift
19
+ raise CommandFailed, "Missing 1 parameter: <secret>#{usage}" unless secret = args.shift
20
+
21
+ display "=== Registering a new OAuth Service: \"#{servicename}\""
22
+ response = jiveapps.add_oauth_service(app_name, servicename, key, secret)
23
+ Jiveapps::Command.run_internal('oauth:list', ["--app", app_name])
24
+ end
25
+
26
+ # Remove an OAuth Service
27
+ def remove
28
+ usage = "\n Usage:\n $ jiveapps oauth:remove <servicename>"
29
+ app_name = extract_app
30
+ raise CommandFailed, "Missing 1 parameter: <servicename>#{usage}" unless servicename = args.shift
31
+
32
+ if confirm "Are you sure you wish to remove the OAuth service \"#{servicename}\"? (y/n)?"
33
+ display "=== Removing Oauth Service \"#{servicename}\""
34
+ response = jiveapps.remove_oauth_service(app_name, servicename)
35
+ Jiveapps::Command.run_internal('oauth:list', ["--app", app_name])
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -25,5 +25,62 @@ module Jiveapps
25
25
  STDERR.puts(msg)
26
26
  exit 1
27
27
  end
28
+
29
+ def confirm(message="Are you sure you wish to continue? (y/n)?")
30
+ display("#{message} ", false)
31
+ ask.downcase == 'y'
32
+ end
33
+
34
+ def confirm_command(app = app)
35
+ if extract_option('--force')
36
+ display("Warning: The --force switch is deprecated, and will be removed in a future release. Use --confirm #{app} instead.")
37
+ return true
38
+ end
39
+
40
+ raise(Jiveapps::Command::CommandFailed, "No app specified.\nRun this command from app folder or set it adding --app <app name>") unless app
41
+
42
+ confirmed_app = extract_option('--confirm', false)
43
+ if confirmed_app
44
+ unless confirmed_app == app
45
+ raise(Jiveapps::Command::CommandFailed, "Confirmed app #{confirmed_app} did not match the selected app #{app}.")
46
+ end
47
+ return true
48
+ else
49
+ display "\n ! Potentially Destructive Action"
50
+ display " ! To proceed, type \"#{app}\" or re-run this command with --confirm #{@app}"
51
+ display "> ", false
52
+ if ask.downcase != app
53
+ display " ! Input did not match #{app}. Aborted."
54
+ false
55
+ else
56
+ true
57
+ end
58
+ end
59
+ end
60
+
61
+ def ask
62
+ gets.strip
63
+ end
64
+
65
+ # Display Oauth Service list
66
+ # Example Output:
67
+ # === 2 OAuth services for app-name
68
+ # 1. "foo" Service
69
+ # Consumer Key: bar
70
+ # Consumer Secret: baz
71
+ # 2. "foo2" Service
72
+ # Consumer Key: bar
73
+ # Consumer Secret: baz
74
+ def display_oauth_services(oauth_services, app_name)
75
+ if oauth_services.empty?
76
+ display "No OAuth Services for #{app_name}"
77
+ else
78
+ display "=== #{oauth_services.size} OAuth Service#{'s' if oauth_services.size > 1} for #{app_name}"
79
+ oauth_services.each_with_index do |oauth_service, index|
80
+ display "#{index+1}. \"#{oauth_service['name']}\" Service\n Consumer Key: #{oauth_service['key']}\n Consumer Secret: #{oauth_service['secret']}"
81
+ end
82
+ end
83
+ end
84
+
28
85
  end
29
86
  end
@@ -1,3 +1,3 @@
1
1
  module Jiveapps
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
data/spec/client_spec.rb CHANGED
@@ -44,7 +44,7 @@ describe Jiveapps::Client do
44
44
  end
45
45
 
46
46
  it "info -> get app attributes" do
47
- stub_api_request(:get, "/apps/myapp").to_return(:body => <<-EOXML)
47
+ stub_api_request(:get, "/apps/myapp?extended=true").to_return(:body => <<-EOXML)
48
48
  {"app":{"name":"myapp","created_at":"2010-10-15T23:59:10Z","updated_at":"2010-10-15T23:59:10Z","id":1}}
49
49
  EOXML
50
50
 
@@ -39,17 +39,21 @@ module Jiveapps::Command
39
39
  end
40
40
 
41
41
  it "shows 'App not found.' when name specified and rest client does not return an app" do
42
- @cli.stub!(:args).and_return(['invalid_app'])
43
- @cli.jiveapps.should_receive(:info).with('invalid_app').and_return(nil)
42
+ @cli.jiveapps.should_receive(:info).with('myapp').and_return(nil)
44
43
  @cli.should_receive(:display).with('App not found.')
45
44
  @cli.info
46
45
  end
47
46
 
48
- it "shows 'No app specified.' when no name specified" do
47
+ it "shows app info using the --app syntax" do
48
+ @cli.stub!(:args).and_return(['--app', 'myapp'])
49
+ @cli.jiveapps.should_receive(:info).with('myapp').and_return({ :collaborators => [], :addons => []})
50
+ @cli.info
51
+ end
52
+
53
+ it "shows app info reading app from current git dir" do
49
54
  @cli.stub!(:args).and_return([])
50
- @cli.jiveapps.should_not_receive(:info)
51
- @cli.should_receive(:display).with('No app specified.')
52
- @cli.should_receive(:display).with('Run this command from app folder or set it by running: jiveapps info <app name>')
55
+ @cli.stub!(:extract_app_in_dir).and_return('myapp')
56
+ @cli.jiveapps.should_receive(:info).with('myapp').and_return({ :collaborators => [], :addons => []})
53
57
  @cli.info
54
58
  end
55
59
 
@@ -0,0 +1,134 @@
1
+ require 'spec_helper'
2
+
3
+ module Jiveapps::Command
4
+ describe Base do
5
+ before do
6
+ @args = [1, 2]
7
+ @base = Base.new(@args)
8
+ @base.stub!(:display)
9
+ @client = mock('jiveapps client', :host => 'jiveapps.com', :git_host => 'jiveapps.com')
10
+ end
11
+
12
+ it "initializes the jiveapps client with the Auth command" do
13
+ Jiveapps::Command.should_receive(:run_internal).with('auth:client', @args)
14
+ @base.jiveapps
15
+ end
16
+
17
+ context "detecting the app" do
18
+ before do
19
+ @base.stub!(:jiveapps).and_return(@client)
20
+ end
21
+
22
+ it "attempts to find the app via the --app argument" do
23
+ @base.stub!(:args).and_return(['--app', 'myapp'])
24
+ @base.extract_app.should == 'myapp'
25
+ end
26
+
27
+ it "read remotes from git config" do
28
+ File.stub!(:exists?).with('/home/dev/myapp/.git/config').and_return(true)
29
+ File.stub!(:read).with('/home/dev/myapp/.git/config').and_return("
30
+ [core]
31
+ repositoryformatversion = 0
32
+ filemode = true
33
+ bare = false
34
+ logallrefupdates = true
35
+ [remote \"staging\"]
36
+ url = git@jiveapps.com:myapp-staging.git
37
+ fetch = +refs/heads/*:refs/remotes/staging/*
38
+ [remote \"production\"]
39
+ url = git@jiveapps.com:myapp.git
40
+ fetch = +refs/heads/*:refs/remotes/production/*
41
+ [remote \"github\"]
42
+ url = git@github.com:myapp.git
43
+ fetch = +refs/heads/*:refs/remotes/github/*
44
+ ")
45
+ @base.git_remotes('/home/dev/myapp').should == { 'staging' => 'myapp-staging', 'production' => 'myapp' }
46
+ end
47
+
48
+ it "attempts to find the git config file in parent folders" do
49
+ File.should_receive(:exists?).with('/home/dev/myapp/app/models/.git/config').and_return(false)
50
+ File.should_receive(:exists?).with('/home/dev/myapp/app/.git/config').and_return(false)
51
+ File.should_receive(:exists?).with('/home/dev/myapp/.git/config').and_return(true)
52
+ File.should_receive(:read).with('/home/dev/myapp/.git/config').and_return('')
53
+ @base.git_remotes('/home/dev/myapp/app/models')
54
+ end
55
+
56
+ it "gets the app from remotes when there's only one app" do
57
+ @base.stub!(:git_remotes).and_return({ 'jiveapps' => 'myapp' })
58
+ @base.extract_app.should == 'myapp'
59
+ end
60
+
61
+ it "uses the remote named after the current folder name when there are multiple" do
62
+ @base.stub!(:git_remotes).and_return({ 'staging' => 'myapp-staging', 'production' => 'myapp' })
63
+ Dir.stub!(:pwd).and_return('/home/dev/myapp')
64
+ @base.extract_app.should == 'myapp'
65
+ end
66
+
67
+ it "accepts a --remote argument to choose the app from the remote name" do
68
+ @base.stub!(:git_remotes).and_return({ 'staging' => 'myapp-staging', 'production' => 'myapp' })
69
+ @base.stub!(:args).and_return(['--remote', 'staging'])
70
+ @base.extract_app.should == 'myapp-staging'
71
+ end
72
+
73
+ it "raises when cannot determine which app is it" do
74
+ @base.stub!(:git_remotes).and_return({ 'staging' => 'myapp-staging', 'production' => 'myapp' })
75
+ lambda { @base.extract_app }.should raise_error(Jiveapps::Command::CommandFailed)
76
+ end
77
+ end
78
+
79
+ context "option parsing" do
80
+ it "extracts options from args" do
81
+ @base.stub!(:args).and_return(%w( a b --something value c d ))
82
+ @base.extract_option('--something').should == 'value'
83
+ end
84
+
85
+ it "accepts options without value" do
86
+ @base.stub!(:args).and_return(%w( a b --something))
87
+ @base.extract_option('--something').should be_true
88
+ end
89
+
90
+ it "doesn't consider parameters as a value" do
91
+ @base.stub!(:args).and_return(%w( a b --something --something-else c d))
92
+ @base.extract_option('--something').should be_true
93
+ end
94
+
95
+ it "accepts a default value" do
96
+ @base.stub!(:args).and_return(%w( a b --something))
97
+ @base.extract_option('--something', 'default').should == 'default'
98
+ end
99
+
100
+ it "is not affected by multiple arguments with the same value" do
101
+ @base.stub!(:args).and_return(%w( --arg1 val --arg2 val ))
102
+ @base.extract_option('--arg1').should == 'val'
103
+ @base.args.should == ['--arg2', 'val']
104
+ end
105
+ end
106
+
107
+ describe "confirming" do
108
+ it "confirms the app via --confirm" do
109
+ @base.stub(:app).and_return("myapp")
110
+ @base.stub(:args).and_return(["--confirm", "myapp"])
111
+ @base.confirm_command.should be_true
112
+ end
113
+
114
+ it "does not confirms the app via --confirm on a mismatch" do
115
+ @base.stub(:app).and_return("myapp")
116
+ @base.stub(:args).and_return(["--confirm", "badapp"])
117
+ lambda { @base.confirm_command}.should raise_error CommandFailed
118
+ end
119
+
120
+ it "confirms the app interactively via ask" do
121
+ @base.stub(:app).and_return("myapp")
122
+ @base.stub(:ask).and_return("myapp")
123
+ @base.confirm_command.should be_true
124
+ end
125
+
126
+ it "fails if the interactive confirm doesn't match" do
127
+ @base.stub(:app).and_return("myapp")
128
+ @base.stub(:ask).and_return("badresponse")
129
+ @base.confirm_command.should be_false
130
+ end
131
+ end
132
+
133
+ end
134
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jiveapps
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease: false
4
+ hash: 15
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Scott Becker
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-07 00:00:00 -08:00
18
+ date: 2011-01-28 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -151,10 +151,12 @@ files:
151
151
  - lib/jiveapps/commands/base.rb
152
152
  - lib/jiveapps/commands/help.rb
153
153
  - lib/jiveapps/commands/keys.rb
154
+ - lib/jiveapps/commands/oauth.rb
154
155
  - lib/jiveapps/helpers.rb
155
156
  - lib/jiveapps/version.rb
156
157
  - spec/client_spec.rb
157
158
  - spec/commands/app_spec.rb
159
+ - spec/commands/base_spec.rb
158
160
  - spec/commands/keys_spec.rb
159
161
  - spec/spec_helper.rb
160
162
  has_rdoc: true
@@ -187,12 +189,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
189
  requirements: []
188
190
 
189
191
  rubyforge_project:
190
- rubygems_version: 1.3.7
192
+ rubygems_version: 1.4.2
191
193
  signing_key:
192
194
  specification_version: 3
193
195
  summary: The "jiveapps" gem is a set of command line tools for building and hosting Jive App front-ends.
194
196
  test_files:
195
197
  - spec/client_spec.rb
196
198
  - spec/commands/app_spec.rb
199
+ - spec/commands/base_spec.rb
197
200
  - spec/commands/keys_spec.rb
198
201
  - spec/spec_helper.rb