88miles 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +20 -0
- data/README.md +79 -0
- data/Rakefile +36 -0
- data/VERSION +1 -0
- data/bin/88miles +3 -0
- data/gigawatt.gemspec +89 -0
- data/lib/gigawatt/application.rb +8 -0
- data/lib/gigawatt/cache.rb +71 -0
- data/lib/gigawatt/commands/init.rb +51 -0
- data/lib/gigawatt/commands/log.rb +162 -0
- data/lib/gigawatt/commands/setup.rb +107 -0
- data/lib/gigawatt/commands/start.rb +75 -0
- data/lib/gigawatt/commands/status.rb +101 -0
- data/lib/gigawatt/commands/stop.rb +57 -0
- data/lib/gigawatt/commands/sync.rb +53 -0
- data/lib/gigawatt/oauth.rb +23 -0
- data/lib/gigawatt/options.rb +53 -0
- data/lib/gigawatt/project_file.rb +34 -0
- data/lib/gigawatt/settings.rb +41 -0
- data/lib/gigawatt.rb +29 -0
- data/test/helper.rb +18 -0
- data/test/test_gigawatt.rb +7 -0
- metadata +177 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
module Commands
|
3
|
+
class Setup
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def self.run!(settings)
|
7
|
+
options = Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
88 Miles Command line application - http://88miles.net
|
10
|
+
|
11
|
+
This command will request an access token, giving the command line utility access to your 88 Miles account.
|
12
|
+
|
13
|
+
To do this, you will be asked for your 88 Miles login and password. Please note that the login and password will not be saved.
|
14
|
+
|
15
|
+
Usage
|
16
|
+
88miles setup [options]
|
17
|
+
|
18
|
+
options:
|
19
|
+
EOS
|
20
|
+
opt :force, "Override existing settings", :default => false, :type => :boolean
|
21
|
+
end
|
22
|
+
|
23
|
+
instance = self.new(settings, options)
|
24
|
+
|
25
|
+
if instance.settings_exists?
|
26
|
+
puts "The settings file #{instance.settings.path} already exists. Use --force to overwrite"
|
27
|
+
return SETTINGS_FILE_EXISTS
|
28
|
+
end
|
29
|
+
|
30
|
+
instance.preamble
|
31
|
+
|
32
|
+
begin
|
33
|
+
instance.authenticate
|
34
|
+
rescue OAuth2::Error => e
|
35
|
+
puts "There was an issue authenticating your account. Please try again."
|
36
|
+
return INVALID_OAUTH_TOKEN_EXIT_CODE
|
37
|
+
end
|
38
|
+
instance.postamble
|
39
|
+
|
40
|
+
return OK_EXIT_CODE
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(settings, options)
|
44
|
+
@options = options
|
45
|
+
@settings = settings
|
46
|
+
end
|
47
|
+
|
48
|
+
def settings
|
49
|
+
@settings
|
50
|
+
end
|
51
|
+
|
52
|
+
def settings_exists?
|
53
|
+
return false if options[:force]
|
54
|
+
@settings.setup?
|
55
|
+
end
|
56
|
+
|
57
|
+
def preamble
|
58
|
+
say("88 Miles command line utility setup")
|
59
|
+
say("-----------------------------------")
|
60
|
+
say("To setup the 88 Miles command line utility, we need to authenticate you and request an access token.")
|
61
|
+
say("We will open a browser, where you will be asked to login and approve access to this app.")
|
62
|
+
end
|
63
|
+
|
64
|
+
def postamble
|
65
|
+
say("Thank you. We can now access your account. You can now initialize a directory by running <%= color('88miles init [directory]', BOLD) %>")
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_access_key(url)
|
69
|
+
uri = URI(url)
|
70
|
+
token = uri.fragment.split('&').map{ |kv| kv.split('=') }.delete_if{ |kv| kv[0] != 'access_token' }.first
|
71
|
+
return token[1] if token
|
72
|
+
return nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def authenticate
|
76
|
+
client = Gigawatt::OAuth.client
|
77
|
+
|
78
|
+
redirect_uri = Gigawatt::OAuth.redirect_uri
|
79
|
+
url = client.auth_code.authorize_url(:response_type => 'token', :redirect_uri => redirect_uri)
|
80
|
+
|
81
|
+
Launchy.open(url) do |exception|
|
82
|
+
say "Couldn't open a browser. Please paste the following URL into a browser"
|
83
|
+
say url
|
84
|
+
end
|
85
|
+
|
86
|
+
say("After you have completed the approval process, cut and paste the URL you are redirected to.")
|
87
|
+
access_key = get_access_key(ask("URL: ") do |url|
|
88
|
+
url.validate = /\A#{redirect_uri}#access_token=.+&state=\Z/
|
89
|
+
url.responses[:not_valid] = "That URL doesn't look right. It should look like: #{redirect_uri}#access_token=[some characters]&state="
|
90
|
+
end)
|
91
|
+
|
92
|
+
@settings.access_key = access_key
|
93
|
+
@access_key = OAuth.token(access_key)
|
94
|
+
|
95
|
+
cache = Gigawatt::Cache.new(@settings, @access_key)
|
96
|
+
|
97
|
+
cache.refresh!
|
98
|
+
|
99
|
+
@settings.companies = cache.companies
|
100
|
+
@settings.projects = cache.projects
|
101
|
+
|
102
|
+
@settings.write(:accesskey)
|
103
|
+
@access_key.token
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
module Commands
|
3
|
+
class Start
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def self.run!(settings)
|
7
|
+
options = Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
88 Miles Command line application - http://88miles.net
|
10
|
+
|
11
|
+
Punch into the project.
|
12
|
+
|
13
|
+
Usage
|
14
|
+
88miles start [options]
|
15
|
+
|
16
|
+
options:
|
17
|
+
EOS
|
18
|
+
|
19
|
+
|
20
|
+
opt :activity, "Select an activity", :type => :flag
|
21
|
+
end
|
22
|
+
|
23
|
+
instance = self.new(settings, options)
|
24
|
+
begin
|
25
|
+
return instance.punch_in
|
26
|
+
rescue OAuth2::Error => e
|
27
|
+
say "Access to your 88 Miles may have been revoked. Please run <%= color('88miles setup', BOLD) %> again."
|
28
|
+
return INVALID_OAUTH_TOKEN_EXIT_CODE
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(settings, options)
|
33
|
+
@settings = settings
|
34
|
+
@options = options
|
35
|
+
|
36
|
+
@access_key = OAuth.token(@settings.access_key)
|
37
|
+
@cache = Cache.new(settings, @access_key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def select_activity(project)
|
41
|
+
return nil unless options[:activity]
|
42
|
+
return nil unless project["activities"]
|
43
|
+
|
44
|
+
selected = nil
|
45
|
+
choose do |menu|
|
46
|
+
menu.prompt = "Pick an Activity"
|
47
|
+
project["activities"].each do |activity|
|
48
|
+
menu.choice("#{activity["name"]}") { selected = activity }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
selected
|
52
|
+
end
|
53
|
+
|
54
|
+
def punch_in
|
55
|
+
project = Gigawatt::ProjectFile.new.project
|
56
|
+
|
57
|
+
if project
|
58
|
+
activity = select_activity(project)
|
59
|
+
opts = {}
|
60
|
+
opts = { :body => { :activity_uuid => activity["uuid"] } } if activity
|
61
|
+
response = JSON.parse(@access_key.post("/api/1/projects/#{project["uuid"]}/punch_in.json", opts).body)
|
62
|
+
current = response["response"]
|
63
|
+
ProjectFile.write(current)
|
64
|
+
|
65
|
+
company = @cache.companies(true)[project["company_uuid"]]
|
66
|
+
say("Punched in to #{company["name"]}: #{project["name"]}")
|
67
|
+
return OK_EXIT_CODE
|
68
|
+
else
|
69
|
+
say("No project found. Did you remember to run <%= color('88miles init [directory]', BOLD) %>?")
|
70
|
+
return NO_PROJECT_EXIT_CODE
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
module Commands
|
3
|
+
class Status
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def self.run!(settings)
|
7
|
+
options = Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
88 Miles Command line application - http://88miles.net
|
10
|
+
|
11
|
+
Get status about the linked project
|
12
|
+
|
13
|
+
Usage:
|
14
|
+
88miles status [options]
|
15
|
+
|
16
|
+
options:
|
17
|
+
EOS
|
18
|
+
|
19
|
+
opt :sync, "Sync the data from the server first. Uses the cache if false", :type => :flag
|
20
|
+
opt :foreground, "Don't exit - just refresh the timer", :type => :flag
|
21
|
+
opt :time, "Only return the time", :type => :flag
|
22
|
+
end
|
23
|
+
|
24
|
+
instance = self.new(settings, options)
|
25
|
+
return instance.get_settings
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(settings, options)
|
29
|
+
@settings = settings
|
30
|
+
@options = options
|
31
|
+
|
32
|
+
@access_key = OAuth.token(@settings.access_key)
|
33
|
+
@cache = Cache.new(settings, @access_key)
|
34
|
+
|
35
|
+
@project = Gigawatt::ProjectFile.new.project
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_settings
|
39
|
+
unless @project
|
40
|
+
say("No project found.")
|
41
|
+
return NO_PROJECT_EXIT_CODE
|
42
|
+
end
|
43
|
+
|
44
|
+
if @options[:sync]
|
45
|
+
sync = Gigawatt::Commands::Sync.new(@settings, @options)
|
46
|
+
begin
|
47
|
+
sync.sync
|
48
|
+
sync.sync_current
|
49
|
+
rescue OAuth2::Error => e
|
50
|
+
say "Access to your 88 Miles may have been revoked. Please run <%= color('88miles setup', BOLD) %> again."
|
51
|
+
return INVALID_OAUTH_TOKEN_EXIT_CODE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if @options[:foreground]
|
56
|
+
while(1)
|
57
|
+
print_status
|
58
|
+
sleep(1)
|
59
|
+
end
|
60
|
+
print "\n"
|
61
|
+
else
|
62
|
+
print_status
|
63
|
+
print "\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
return OK_EXIT_CODE
|
67
|
+
end
|
68
|
+
|
69
|
+
def print_status
|
70
|
+
company = @cache.companies(true)[@project["company_uuid"]]
|
71
|
+
|
72
|
+
grand_total = @project["grand_total"]
|
73
|
+
grand_total += (Time.now.to_i - @project["started_at"]) if @project["running"]
|
74
|
+
overdue = grand_total > @project["time_limit"] if @project["time_limit"]
|
75
|
+
|
76
|
+
clock_string = to_clock_s(grand_total, true)
|
77
|
+
clock_string = " [#{HighLine::String.new(clock_string).red}]" if overdue
|
78
|
+
|
79
|
+
str = ""
|
80
|
+
if @options[:time]
|
81
|
+
str = clock_string
|
82
|
+
else
|
83
|
+
str += "#{company["name"]}: #{@project["name"]}"
|
84
|
+
str += " [#{clock_string}]"
|
85
|
+
str += " #{HighLine::String.new("Running").green}" if @project["running"]
|
86
|
+
end
|
87
|
+
|
88
|
+
print "\e[0K\r#{str}" if @options[:foreground]
|
89
|
+
print str unless @options[:foreground]
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_clock_s(time, show_seconds = false)
|
93
|
+
hour = (time.abs / 3600).floor
|
94
|
+
minute = (time.abs / 60 % 60).floor
|
95
|
+
seconds = (time.abs % 60).floor if show_seconds
|
96
|
+
|
97
|
+
return (time != 0 && (time / time.abs) == -1 ? "-" : "") + hour.to_s.rjust(2, '0') + ":" + minute.to_s.rjust(2, '0') + (show_seconds ? ":" + seconds.to_s.rjust(2, '0') : '')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
module Commands
|
3
|
+
class Stop
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def self.run!(settings)
|
7
|
+
options = Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
88 Miles Command line application - http://88miles.net
|
10
|
+
|
11
|
+
Punch out of the project.
|
12
|
+
|
13
|
+
Usage
|
14
|
+
88miles stop [options]
|
15
|
+
|
16
|
+
options:
|
17
|
+
EOS
|
18
|
+
opt :notes, "Save notes against the shift", :type => :string
|
19
|
+
opt :tags, "Allocate tags to the shift", :type => :string
|
20
|
+
end
|
21
|
+
|
22
|
+
instance = self.new(settings, options)
|
23
|
+
begin
|
24
|
+
return instance.punch_out
|
25
|
+
rescue OAuth2::Error => e
|
26
|
+
say "Access to your 88 Miles may have been revoked. Please run <%= color('88miles setup', BOLD) %> again."
|
27
|
+
return INVALID_OAUTH_TOKEN_EXIT_CODE
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(settings, options)
|
32
|
+
@settings = settings
|
33
|
+
@options = options
|
34
|
+
|
35
|
+
@access_key = OAuth.token(@settings.access_key)
|
36
|
+
@cache = Cache.new(settings, @access_key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def punch_out
|
40
|
+
project = Gigawatt::ProjectFile.new.project
|
41
|
+
|
42
|
+
if project
|
43
|
+
response = JSON.parse(@access_key.post("/api/1/projects/#{project["uuid"]}/punch_out.json", { :params => { :notes => options.notes.to_s } }).body)
|
44
|
+
current = response["response"]
|
45
|
+
ProjectFile.write(current)
|
46
|
+
|
47
|
+
company = @cache.companies(true)[project["company_uuid"]]
|
48
|
+
say("Punched out of #{company["name"]}: #{project["name"]}")
|
49
|
+
return OK_EXIT_CODE
|
50
|
+
else
|
51
|
+
say("No project found. Did you remember to run <%= color('88miles init [directory]', BOLD) %>?")
|
52
|
+
return NO_PROJECT_EXIT_CODE
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
module Commands
|
3
|
+
class Sync
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def self.run!(settings)
|
7
|
+
options = Trollop::options do
|
8
|
+
banner <<-EOS
|
9
|
+
88 Miles Command line application - http://88miles.net
|
10
|
+
|
11
|
+
88 Miles caches your company and project list to speed things up. Run this command if you add, edit or remove companies or projects
|
12
|
+
|
13
|
+
If run inside a directory with a linked project, the linked project will be updated too
|
14
|
+
|
15
|
+
Usage
|
16
|
+
88miles sync
|
17
|
+
EOS
|
18
|
+
end
|
19
|
+
|
20
|
+
instance = self.new(settings, options)
|
21
|
+
begin
|
22
|
+
instance.sync
|
23
|
+
instance.sync_current
|
24
|
+
rescue OAuth2::Error => e
|
25
|
+
say "Access to your 88 Miles may have been revoked. Please run <%= color('88miles setup', BOLD) %> again."
|
26
|
+
return INVALID_OAUTH_TOKEN_EXIT_CODE
|
27
|
+
end
|
28
|
+
|
29
|
+
return 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(settings, options)
|
33
|
+
@settings = settings
|
34
|
+
@options = options
|
35
|
+
|
36
|
+
@access_key = OAuth.token(@settings.access_key)
|
37
|
+
@cache = Cache.new(settings, @access_key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def sync
|
41
|
+
@cache.refresh!
|
42
|
+
end
|
43
|
+
|
44
|
+
def sync_current
|
45
|
+
project = Gigawatt::ProjectFile.new.project
|
46
|
+
if project
|
47
|
+
response = JSON.parse(@access_key.get("/api/1/projects/#{project["uuid"]}.json").body)
|
48
|
+
ProjectFile.write(response["response"])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
class OAuth
|
3
|
+
def self.client
|
4
|
+
if ENV['ENV'] == 'development'
|
5
|
+
client = OAuth2::Client.new('NjtVKz6Di3ccJjn2AGwZKhSxYBX4QHPJ5w1LrZOR', nil, :site => 'http://localhost:3000')
|
6
|
+
else
|
7
|
+
client = OAuth2::Client.new('hhWZrEF6YTlPUKrggiesnjXAFViLa8FBZNNUtr8L', nil, :site => 'https://88miles.net')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.token(token)
|
12
|
+
OAuth2::AccessToken.new(self.client, token)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.redirect_uri
|
16
|
+
if ENV['ENV'] == 'development'
|
17
|
+
"http://localhost:3000/oauth/authorized"
|
18
|
+
else
|
19
|
+
"https://88miles.net/oauth/authorized"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
class Options
|
3
|
+
SUB_COMMANDS = %w(setup init start stop sync status log)
|
4
|
+
|
5
|
+
def self.parse!
|
6
|
+
version_string = File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION')).strip
|
7
|
+
|
8
|
+
options = Trollop::options do
|
9
|
+
version "88miles #{version_string}"
|
10
|
+
stop_on SUB_COMMANDS
|
11
|
+
banner <<-EOS
|
12
|
+
88 Miles Command line application - http://88miles.net
|
13
|
+
|
14
|
+
Usage:
|
15
|
+
88miles [globaloptions] <subcommand> [options]
|
16
|
+
|
17
|
+
subcommands:
|
18
|
+
setup: Link your 88 Miles account to this program
|
19
|
+
init: Link a project to a directory
|
20
|
+
start: Punch in to the linked project
|
21
|
+
stop: Punch out of the linked project
|
22
|
+
sync: Refresh the local cache from the server
|
23
|
+
status: Show the project timer
|
24
|
+
log: Print out the project shifts
|
25
|
+
|
26
|
+
globaloptions:
|
27
|
+
EOS
|
28
|
+
opt :settings, "Path to store 88 Miles settings", :default => Settings.defaults[:path], :type => :string
|
29
|
+
end
|
30
|
+
|
31
|
+
settings = Settings.new(options)
|
32
|
+
cmd = ARGV.shift.strip
|
33
|
+
case cmd
|
34
|
+
when "setup"
|
35
|
+
Gigawatt::Commands::Setup.run!(settings)
|
36
|
+
when "init"
|
37
|
+
Gigawatt::Commands::Init.run!(settings)
|
38
|
+
when "start"
|
39
|
+
Gigawatt::Commands::Start.run!(settings)
|
40
|
+
when "stop"
|
41
|
+
Gigawatt::Commands::Stop.run!(settings)
|
42
|
+
when "sync"
|
43
|
+
Gigawatt::Commands::Sync.run!(settings)
|
44
|
+
when "status"
|
45
|
+
Gigawatt::Commands::Status.run!(settings)
|
46
|
+
when "log"
|
47
|
+
Gigawatt::Commands::Log.run!(settings)
|
48
|
+
else
|
49
|
+
Trollop::die "Unknown subcommand #{cmd.inspect}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
class ProjectFile
|
3
|
+
def find_the_dotfile(dir = Dir.pwd)
|
4
|
+
file = File.join(dir, ProjectFile.filename)
|
5
|
+
if File.exists?(file)
|
6
|
+
return File.join(file)
|
7
|
+
else
|
8
|
+
parts = dir.split(File::SEPARATOR)[0..-2]
|
9
|
+
if parts.length == 0
|
10
|
+
return nil
|
11
|
+
else
|
12
|
+
return find_the_dotfile(File.join(parts))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def project
|
18
|
+
dotfile = find_the_dotfile
|
19
|
+
if dotfile
|
20
|
+
YAML.load_file(dotfile)
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.write(project)
|
27
|
+
File.write(File.join(Dir.pwd, ProjectFile.filename), project.to_hash.to_yaml)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.filename
|
31
|
+
".88miles"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Gigawatt
|
2
|
+
class Settings
|
3
|
+
attr_accessor :access_key, :projects, :companies, :staff
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = Settings.defaults.merge(options)
|
7
|
+
read if setup?
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.defaults
|
11
|
+
{
|
12
|
+
:path => File.join(Dir.home, '.88miles')
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup?
|
17
|
+
File.exists?(path) && File.directory?(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def path
|
21
|
+
@options[:path]
|
22
|
+
end
|
23
|
+
|
24
|
+
def read
|
25
|
+
self.access_key = YAML.load_file(File.join(path, 'accesskey')) if File.exists?(File.join(path, 'accesskey'))
|
26
|
+
self.companies = YAML.load_file(File.join(path, 'companies')) if File.exists?(File.join(path, 'companies'))
|
27
|
+
self.projects = YAML.load_file(File.join(path, 'projects')) if File.exists?(File.join(path, 'projects'))
|
28
|
+
self.staff = YAML.load_file(File.join(path, 'staff')) if File.exists?(File.join(path, 'staff'))
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(type)
|
32
|
+
# Make the directory if it doesn't exist
|
33
|
+
FileUtils.mkdir_p(path) unless File.exists?(path)
|
34
|
+
File.write(File.join(path, 'accesskey'), self.access_key.to_yaml) if type == :accesskey
|
35
|
+
File.write(File.join(path, 'companies'), self.companies.to_yaml) if type == :companies
|
36
|
+
File.write(File.join(path, 'projects'), self.projects.to_yaml) if type == :projects
|
37
|
+
File.write(File.join(path, 'staff'), self.staff.to_yaml) if type == :staff
|
38
|
+
FileUtils.chmod 0700, path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/gigawatt.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'highline/import'
|
3
|
+
require 'oauth2'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'json'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'terminal-table'
|
8
|
+
require 'launchy'
|
9
|
+
|
10
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'cache')
|
11
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'settings')
|
12
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'project_file')
|
13
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'application')
|
14
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'oauth')
|
15
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'options')
|
16
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'setup')
|
17
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'init')
|
18
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'start')
|
19
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'stop')
|
20
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'sync')
|
21
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'status')
|
22
|
+
require File.join(File.dirname(__FILE__), 'gigawatt', 'commands', 'log')
|
23
|
+
|
24
|
+
module Gigawatt
|
25
|
+
NO_PROJECT_EXIT_CODE = 3
|
26
|
+
SETTINGS_FILE_EXISTS = 2
|
27
|
+
INVALID_OAUTH_TOKEN_EXIT_CODE = 1
|
28
|
+
OK_EXIT_CODE = 0
|
29
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'gigawatt'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|