transcriptic 0.1.3 → 0.2.0
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.
- checksums.yaml +7 -0
- data/bin/transcriptic +2 -4
- data/lib/thor/monkies.rb +3 -0
- data/lib/thor/monkies/shell.rb +3 -0
- data/lib/transcriptic.rb +86 -2
- data/lib/transcriptic/auth.rb +2 -63
- data/lib/transcriptic/base_generator.rb +25 -0
- data/lib/transcriptic/cli.rb +199 -8
- data/lib/transcriptic/client.rb +45 -38
- data/lib/transcriptic/commands/project.rb +37 -0
- data/lib/transcriptic/core_ext.rb +3 -0
- data/lib/transcriptic/core_ext/file.rb +7 -0
- data/lib/transcriptic/core_ext/file_utils.rb +15 -0
- data/lib/transcriptic/core_ext/pathname.rb +13 -0
- data/lib/transcriptic/core_ext/string.rb +8 -0
- data/lib/transcriptic/dependencies_generator.rb +13 -0
- data/lib/transcriptic/errors.rb +32 -0
- data/lib/transcriptic/labfile.rb +73 -0
- data/lib/transcriptic/project_generator.rb +56 -0
- data/lib/transcriptic/sbt.rb +58 -0
- data/lib/transcriptic/templates/LICENSE.erb +20 -0
- data/lib/transcriptic/templates/Labfile.erb +12 -0
- data/lib/transcriptic/templates/README.erb +3 -0
- data/lib/transcriptic/templates/app/Main.erb +11 -0
- data/lib/transcriptic/templates/project/Build.erb +59 -0
- data/lib/transcriptic/templates/project/Dependencies.erb +10 -0
- data/lib/transcriptic/templates/project/build.properties +1 -0
- data/lib/transcriptic/templates/project/plugins.sbt +5 -0
- data/lib/transcriptic/templates/sbt +1 -0
- data/lib/transcriptic/{helpers.rb → ui.rb} +124 -109
- data/lib/transcriptic/version.rb +2 -1
- data/lib/vendor/{transcriptic/okjson.rb → okjson.rb} +0 -0
- metadata +203 -46
- data/lib/transcriptic/command.rb +0 -233
- data/lib/transcriptic/command/base.rb +0 -157
- data/lib/transcriptic/command/console.rb +0 -10
- data/lib/transcriptic/command/data.rb +0 -29
- data/lib/transcriptic/command/help.rb +0 -124
- data/lib/transcriptic/command/login.rb +0 -35
- data/lib/transcriptic/command/run.rb +0 -108
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ee17a7a6a96eb5b4e97c7162815443cfca424bec
|
4
|
+
data.tar.gz: addfe85a94f4b2856ef5f7ac2ac1f72435801ed9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 350b2fdd82bd58ed2fe9427560a5b89b0fc9fcb70a55d1198c9882c06cf833321a2213f7d6d06d09da6ec00386a23af7b87a8a1d20fbe0b9cd8cd277eac3756d
|
7
|
+
data.tar.gz: bcd5b9f30c299b61098115c54a017963bb2cccf921bddf121336e21c19405f21a6d110f9fb797a134bce9931f601694d2618ea9e047a31ee5190847d73d65602
|
data/bin/transcriptic
CHANGED
@@ -3,10 +3,8 @@
|
|
3
3
|
# resolve bin path, ignoring symlinks
|
4
4
|
require "pathname"
|
5
5
|
bin_file = Pathname.new(__FILE__).realpath
|
6
|
-
|
7
|
-
# add self to libpath
|
8
6
|
$:.unshift File.expand_path("../../lib", bin_file)
|
9
7
|
|
10
8
|
# start up the CLI
|
11
|
-
require "transcriptic
|
12
|
-
Transcriptic::CLI.start(
|
9
|
+
require "transcriptic"
|
10
|
+
Transcriptic::CLI::Base.start(ARGV)
|
data/lib/thor/monkies.rb
ADDED
data/lib/transcriptic.rb
CHANGED
@@ -1,3 +1,87 @@
|
|
1
|
-
|
1
|
+
require 'digest'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'hashie'
|
4
|
+
require 'json'
|
5
|
+
require 'pathname'
|
6
|
+
require 'solve'
|
7
|
+
require 'thor'
|
8
|
+
require 'tmpdir'
|
9
|
+
require 'uri'
|
10
|
+
require 'zlib'
|
11
|
+
require 'celluloid'
|
12
|
+
require 'active_support/core_ext'
|
13
|
+
require 'chozo/core_ext'
|
14
|
+
require 'rexml/document'
|
15
|
+
require 'rest-client'
|
16
|
+
require 'uri'
|
17
|
+
require 'net/http'
|
18
|
+
require 'time'
|
2
19
|
|
3
|
-
require
|
20
|
+
require 'vendor/okjson'
|
21
|
+
|
22
|
+
require 'transcriptic/version'
|
23
|
+
require 'transcriptic/core_ext'
|
24
|
+
require 'transcriptic/errors'
|
25
|
+
require 'thor/monkies'
|
26
|
+
|
27
|
+
module Transcriptic
|
28
|
+
class << self
|
29
|
+
attr_accessor :ui
|
30
|
+
|
31
|
+
def root
|
32
|
+
@root ||= Pathname.new(File.expand_path('../', File.dirname(__FILE__)))
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_labfile(path = Dir.pwd)
|
36
|
+
path = Pathname.new(path)
|
37
|
+
path.ascend do |potential_root|
|
38
|
+
if potential_root.entries.collect(&:to_s).include?('Labfile')
|
39
|
+
return potential_root.join('Labfile')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def home_directory
|
45
|
+
running_on_windows? ? ENV['USERPROFILE'].gsub("\\","/") : ENV['HOME']
|
46
|
+
end
|
47
|
+
|
48
|
+
def running_on_windows?
|
49
|
+
RUBY_PLATFORM =~ /mswin32|mingw32/
|
50
|
+
end
|
51
|
+
|
52
|
+
def running_on_a_mac?
|
53
|
+
RUBY_PLATFORM =~ /-darwin\d/
|
54
|
+
end
|
55
|
+
|
56
|
+
def transcriptic_path
|
57
|
+
ENV['TRANSCRIPTIC_PATH'] || File.expand_path('~/.transcriptic')
|
58
|
+
end
|
59
|
+
|
60
|
+
def ui
|
61
|
+
@ui ||= Thor::Base.shell.new
|
62
|
+
end
|
63
|
+
|
64
|
+
def logger
|
65
|
+
Celluloid.logger
|
66
|
+
end
|
67
|
+
|
68
|
+
def tmp_dir
|
69
|
+
File.join(transcriptic_path, 'tmp')
|
70
|
+
end
|
71
|
+
|
72
|
+
def mktmpdir
|
73
|
+
FileUtils.mkdir_p(tmp_dir)
|
74
|
+
Dir.mktmpdir(nil, tmp_dir)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
require 'transcriptic/auth'
|
82
|
+
require 'transcriptic/labfile'
|
83
|
+
require 'transcriptic/project_generator'
|
84
|
+
require 'transcriptic/dependencies_generator'
|
85
|
+
require 'transcriptic/client'
|
86
|
+
require 'transcriptic/sbt'
|
87
|
+
require 'transcriptic/cli'
|
data/lib/transcriptic/auth.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require "transcriptic"
|
2
|
-
require "transcriptic/client"
|
3
|
-
require "transcriptic/helpers"
|
4
|
-
|
5
1
|
class Transcriptic::Auth
|
6
2
|
class << self
|
7
3
|
attr_accessor :credentials
|
@@ -28,8 +24,6 @@ class Transcriptic::Auth
|
|
28
24
|
@client = nil
|
29
25
|
end
|
30
26
|
|
31
|
-
include Transcriptic::Helpers
|
32
|
-
|
33
27
|
# just a stub; will raise if not authenticated
|
34
28
|
def check
|
35
29
|
client.list
|
@@ -59,9 +53,9 @@ class Transcriptic::Auth
|
|
59
53
|
|
60
54
|
def credentials_file
|
61
55
|
if host == default_host
|
62
|
-
"#{home_directory}/.transcriptic/credentials"
|
56
|
+
"#{Transcriptic.home_directory}/.transcriptic/credentials"
|
63
57
|
else
|
64
|
-
"#{home_directory}/.transcriptic/credentials.#{host}"
|
58
|
+
"#{Transcriptic.home_directory}/.transcriptic/credentials.#{host}"
|
65
59
|
end
|
66
60
|
end
|
67
61
|
|
@@ -138,61 +132,6 @@ class Transcriptic::Auth
|
|
138
132
|
delete_credentials
|
139
133
|
raise e
|
140
134
|
end
|
141
|
-
check_for_associated_ssh_key unless Transcriptic::Command.current_command == "keys:add"
|
142
|
-
end
|
143
|
-
|
144
|
-
def check_for_associated_ssh_key
|
145
|
-
return unless client.get_keys.length.zero?
|
146
|
-
associate_or_generate_ssh_key
|
147
|
-
end
|
148
|
-
|
149
|
-
def associate_or_generate_ssh_key
|
150
|
-
public_keys = available_ssh_public_keys.sort
|
151
|
-
|
152
|
-
case public_keys.length
|
153
|
-
when 0 then
|
154
|
-
display "Could not find an existing public key."
|
155
|
-
display "Would you like to generate one? [Yn] ", false
|
156
|
-
unless ask.strip.downcase == "n"
|
157
|
-
display "Generating new SSH public key."
|
158
|
-
generate_ssh_key("id_rsa")
|
159
|
-
associate_key("#{home_directory}/.ssh/id_rsa.pub")
|
160
|
-
end
|
161
|
-
when 1 then
|
162
|
-
display "Found existing public key: #{public_keys.first}"
|
163
|
-
associate_key(public_keys.first)
|
164
|
-
else
|
165
|
-
display "Found the following SSH public keys:"
|
166
|
-
public_keys.each_with_index do |key, index|
|
167
|
-
display "#{index+1}) #{File.basename(key)}"
|
168
|
-
end
|
169
|
-
display "Which would you like to use with your Transcriptic account? ", false
|
170
|
-
chosen = public_keys[ask.to_i-1] rescue error("Invalid choice")
|
171
|
-
associate_key(chosen)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
def generate_ssh_key(keyfile)
|
176
|
-
ssh_dir = File.join(home_directory, ".ssh")
|
177
|
-
unless File.exists?(ssh_dir)
|
178
|
-
FileUtils.mkdir_p ssh_dir
|
179
|
-
File.chmod(0700, ssh_dir)
|
180
|
-
end
|
181
|
-
`ssh-keygen -t rsa -N "" -f \"#{home_directory}/.ssh/#{keyfile}\" 2>&1`
|
182
|
-
end
|
183
|
-
|
184
|
-
def associate_key(key)
|
185
|
-
display "Uploading ssh public key #{key}"
|
186
|
-
client.add_key(File.read(key)).inspect
|
187
|
-
end
|
188
|
-
|
189
|
-
def available_ssh_public_keys
|
190
|
-
keys = [
|
191
|
-
"#{home_directory}/.ssh/id_rsa.pub",
|
192
|
-
"#{home_directory}/.ssh/id_dsa.pub"
|
193
|
-
]
|
194
|
-
keys.concat(Dir["#{home_directory}/.ssh/*.pub"])
|
195
|
-
keys.select { |d| File.exists?(d) }.uniq
|
196
135
|
end
|
197
136
|
|
198
137
|
def retry_login?
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
|
3
|
+
module Transcriptic
|
4
|
+
class BaseGenerator < Thor::Group
|
5
|
+
class << self
|
6
|
+
def source_root
|
7
|
+
Transcriptic.root.join('lib/transcriptic/templates')
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
shell = Transcriptic.ui
|
12
|
+
|
13
|
+
argument :path,
|
14
|
+
type: :string,
|
15
|
+
required: true
|
16
|
+
|
17
|
+
include Thor::Actions
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def target
|
22
|
+
@target ||= Pathname.new(File.expand_path(path))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/transcriptic/cli.rb
CHANGED
@@ -1,12 +1,203 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Transcriptic
|
2
|
+
module CLI
|
3
|
+
class Base < Thor
|
4
|
+
include Transcriptic::UI
|
3
5
|
|
4
|
-
class
|
6
|
+
class << self
|
7
|
+
def dispatch(meth, given_args, given_opts, config)
|
8
|
+
unless (given_args & ['-h', '--help']).empty?
|
9
|
+
if given_args.length == 1
|
10
|
+
# transcriptic --help
|
11
|
+
super
|
12
|
+
else
|
13
|
+
command = given_args.first
|
14
|
+
super(meth, ['help', command].compact, nil, config)
|
15
|
+
end
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
5
21
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
22
|
+
def initialize(*args)
|
23
|
+
super(*args)
|
24
|
+
|
25
|
+
Transcriptic.logger.level = ::Logger::INFO
|
26
|
+
|
27
|
+
if @options[:debug]
|
28
|
+
Transcriptic.logger.level = ::Logger::DEBUG
|
29
|
+
end
|
30
|
+
|
31
|
+
if @options[:quiet]
|
32
|
+
Transcriptic.ui.mute!
|
33
|
+
end
|
34
|
+
|
35
|
+
@options = options.dup # unfreeze frozen options Hash from Thor
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "login", "Log in with your Transcriptic account"
|
39
|
+
def login
|
40
|
+
Transcriptic::Auth.login
|
41
|
+
say "Authentication successful."
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "logout", "Clear local authentication credentials"
|
45
|
+
def logout
|
46
|
+
Transcriptic::Auth.logout
|
47
|
+
say "Local credentials cleared."
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "token", "Display your API token"
|
51
|
+
def token
|
52
|
+
say Transcriptic::Auth.api_key
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "new NAME", "Generate a new project"
|
56
|
+
method_option :package,
|
57
|
+
type: :string,
|
58
|
+
desc: "Package name (example: edu.stanford.professorname.projectname)"
|
59
|
+
method_option :email,
|
60
|
+
type: :string,
|
61
|
+
desc: 'Email address of project author'
|
62
|
+
method_option :author,
|
63
|
+
type: :string,
|
64
|
+
desc: 'Name of project author'
|
65
|
+
method_option :description,
|
66
|
+
type: :string,
|
67
|
+
desc: 'Brief one-line description of the project'
|
68
|
+
def new(name)
|
69
|
+
Transcriptic::ProjectGenerator.new([File.join(Dir.pwd, name), name], options).invoke_all
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "logs RUNID", "Get log data from a run"
|
73
|
+
def logs(run_id)
|
74
|
+
transcriptic.read_logs(run_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
desc "status RUNID", "Show status for a given run ID"
|
78
|
+
def status(run_id)
|
79
|
+
ret = transcriptic.status(run_id)
|
80
|
+
if ret.nil?
|
81
|
+
error "#{run_id} not found for #{transcriptic.user}"
|
82
|
+
end
|
83
|
+
say(ret.inspect)
|
84
|
+
end
|
11
85
|
|
86
|
+
desc "list", "List your in-flight run IDs"
|
87
|
+
def list
|
88
|
+
ret = transcriptic.list
|
89
|
+
if ret.empty?
|
90
|
+
say "No runs for #{transcriptic.user}"
|
91
|
+
return
|
92
|
+
end
|
93
|
+
say("Runs:")
|
94
|
+
ret.each do |run|
|
95
|
+
say " #{run.name}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
desc "update", "Update the project's dependencies"
|
100
|
+
def update
|
101
|
+
require_labfile!
|
102
|
+
output_with_arrow "Updating dependencies..."
|
103
|
+
labfile = Transcriptic::Labfile.from_file(Transcriptic.find_labfile)
|
104
|
+
Transcriptic::DependenciesGenerator.new([Dir.pwd, labfile.dependencies], options).invoke_all
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "compile", "Compile the project"
|
108
|
+
def compile
|
109
|
+
require_labfile!
|
110
|
+
update
|
111
|
+
Transcriptic::SBT.compile
|
112
|
+
end
|
113
|
+
|
114
|
+
desc "analyze OBJECTPATH", "Analyze a protocol. Object path is of the form edu.foo.bar where bar is the name of your Protocol object."
|
115
|
+
method_options :raw => :boolean, :iterations => :integer
|
116
|
+
def analyze(object_path)
|
117
|
+
raw = options.raw ? "--raw" : ""
|
118
|
+
iterations = options.iterations ? options.iterations : 5
|
119
|
+
require_labfile!
|
120
|
+
update
|
121
|
+
Transcriptic::SBT.stage
|
122
|
+
data = `target/start #{object_path} --verify #{raw} --iterations #{iterations}`
|
123
|
+
if not options.raw
|
124
|
+
json = json_decode(data)
|
125
|
+
output_with_arrow "Verification successful for #{object_path}"
|
126
|
+
output_with_indent "Expected cost: $#{json["price_avg"]}, maximum observed cost: $#{json["price_max"]}"
|
127
|
+
else
|
128
|
+
say data
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
desc "publish", "Packages up the current project and uploads it to the Autoprotocol central repository"
|
133
|
+
def publish
|
134
|
+
labfile = require_labfile!
|
135
|
+
if compile
|
136
|
+
dependencies = labfile.dependencies.map {|d| "#{d[:group]}.#{d[:name]}/#{d[:version]}" }.join(", ")
|
137
|
+
output_with_arrow "Preparing to publish..."
|
138
|
+
output_with_arrow "Project name: #{labfile.options[:name]}, Author: #{labfile.options[:author]}, Email: #{labfile.options[:email]}"
|
139
|
+
if labfile.options[:description]
|
140
|
+
output_with_arrow "Description: #{labfile.options[:description]}"
|
141
|
+
else
|
142
|
+
display format_with_bang("Warning: No description provided.")
|
143
|
+
end
|
144
|
+
if labfile.dependencies.length > 0
|
145
|
+
output_with_arrow "Dependencies: #{dependencies}}"
|
146
|
+
end
|
147
|
+
confirm(format_with_bang("Are you sure you want to publish version #{labfile.options[:version]} of this project? (y/N)"))
|
148
|
+
output_with_arrow "Not yet available!"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
desc "launch OBJECTPATH", "Packages up the current project, uploads it to Transcriptic, and starts the protocol object at OBJECTPATH running."
|
153
|
+
def launch(object_path)
|
154
|
+
require_labfile!
|
155
|
+
output_with_arrow "Not yet available!"
|
156
|
+
return
|
157
|
+
|
158
|
+
fd = create_protocol_fd_for_path(path)
|
159
|
+
if 1 == fd
|
160
|
+
Transcriptic.ui.error_with_failure "Couldn't packaged protocol filename or directory!"
|
161
|
+
end
|
162
|
+
if args.empty?
|
163
|
+
project_id = "default"
|
164
|
+
else
|
165
|
+
project_id = args.shift
|
166
|
+
end
|
167
|
+
run = action("Uploading `#{path}`") {
|
168
|
+
transcriptic.create_run(fd, project_id)
|
169
|
+
}
|
170
|
+
|
171
|
+
if run["success"]
|
172
|
+
Transcriptic.ui.output_with_arrow "Protocol received: #{run["protocol_format"]} detected"
|
173
|
+
Transcriptic.ui.output_with_arrow "Protocol received: #{run["nsteps"]} steps, expected cost: #{run["exp_cost"]}, total possible cost: #{run["max_cost"]}"
|
174
|
+
Transcriptic.ui.output_with_arrow "Protocol received: expected runtime: #{run["exp_time"]}, total possible runtime: #{run["max_time"]}"
|
175
|
+
if Transcriptic.ui.confirm_quote
|
176
|
+
Transcriptic.ui.display
|
177
|
+
Transcriptic.ui.action("Launching") {
|
178
|
+
transcriptic.launch_run(run["run_id"])
|
179
|
+
}
|
180
|
+
Transcriptic.ui.output_with_arrow "Protocol run launched. ID: #{run["run_id"]}"
|
181
|
+
Transcriptic.ui.output_with_arrow "Monitor at: https://secure.transcriptic.com/#{run["organization_id"]}/#{run["project_id"]}/runs/#{run["run_id"]}"
|
182
|
+
end
|
183
|
+
else
|
184
|
+
Transcriptic.ui.error_with_failure "Error creating protocol run."
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
def transcriptic
|
190
|
+
Transcriptic::Auth.client
|
191
|
+
end
|
192
|
+
|
193
|
+
def require_labfile!
|
194
|
+
labfile = Transcriptic.find_labfile
|
195
|
+
if labfile.nil?
|
196
|
+
error("Can't find Labfile! You must run this command from within an autoprotocol project directory.")
|
197
|
+
end
|
198
|
+
Transcriptic::Labfile.from_file(labfile)
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
12
203
|
end
|