tmc-client 0.0.1 → 0.0.2
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/.gitignore +2 -1
- data/.travis.yml +3 -2
- data/Gemfile +2 -8
- data/README.md +31 -0
- data/lib/tmc-client/client.rb +45 -23
- data/specs/config.yml +3 -0
- data/specs/download_spec.rb +9 -0
- data/specs/list_spec.rb +4 -0
- data/specs/submit_spec.rb +9 -0
- data/specs/update_spec.rb +9 -0
- data/tmc-client.gemspec +8 -9
- metadata +9 -26
- data/Gemfile.lock +0 -44
- data/Readme.md +0 -0
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
TMC-Client
|
2
|
+
==========
|
3
|
+
|
4
|
+
[](https://travis-ci.org/TMCee/tmc-client)
|
5
|
+
[](https://codeclimate.com/github/TMCee/tmc-client)
|
6
|
+
|
7
|
+
TMC-Client is a command line interface for operating with the [TMC-server](http://github.com/testmycode/tmc-server). This client can be used to submit, download, and update exercises.
|
8
|
+
|
9
|
+
Installation
|
10
|
+
------------
|
11
|
+
You may install tmc-client using rubygems `gem install tmc-client`
|
12
|
+
|
13
|
+
|
14
|
+
Commands
|
15
|
+
--------
|
16
|
+
* `tmc list`, short for `tmc list courses`, lists all available courses for the configured TMC-server
|
17
|
+
* `tmc init <coursename>` will initialize a folder for your course to your working directory
|
18
|
+
* `tmc list exercises` lists all available exercises for the current working course (working dir)
|
19
|
+
* `tmc download <exercisename>` will download all files of the specified exercise to the current course directory
|
20
|
+
* `tmc download all` will download all exercises to the working course directory
|
21
|
+
* `tmc submit` or `tmc submit <path-of-the-exercise>` will submit the specified exercise or the current working exercise to the server, and the client will wait for a response from the server. If you do not wish to wait for the response, provide the additional argument `--silent` or `-s` or `--quiet` or `-q`.
|
22
|
+
* `tmc status` or `tmc status <path-of-the-exercise>` will inquire the server about the status of the exercise, and display a short result summary.
|
23
|
+
* `tmc update` or `tmc update <path-of-the-exercise>` will download updates to the specified or working exercise. This will not replace any source files without asking the user first.
|
24
|
+
* `tmc solution` or `tmc solution <path-of-the-exercise>` will download model solutions to the specified or working exercise if they are available. Again, the user will be asked for permission per file before replacement.
|
25
|
+
* `tmc auth` can be used to manually trigger authentication
|
26
|
+
* `tmc get url` displays the server url in use
|
27
|
+
* `tmc set url <url>` configures a new server url for TMC-Client, which is persisted for later use.
|
28
|
+
|
29
|
+
Configuration
|
30
|
+
-------------
|
31
|
+
All configuration is done via commandline interface. If no server url is given it's asked on startup.
|
data/lib/tmc-client/client.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'highline/import'
|
3
|
-
|
3
|
+
require 'pry'
|
4
4
|
require 'json'
|
5
5
|
require 'faraday'
|
6
6
|
require 'yaml'
|
7
|
-
require 'pry'
|
8
7
|
require 'fileutils'
|
9
8
|
require 'tempfile'
|
10
9
|
require 'pp'
|
10
|
+
require 'zip/zip'
|
11
11
|
require_relative 'my_config'
|
12
12
|
|
13
13
|
class Client
|
@@ -16,21 +16,7 @@ class Client
|
|
16
16
|
@config = MyConfig.new
|
17
17
|
@output = output
|
18
18
|
@input = input
|
19
|
-
|
20
|
-
@config.server_url ||= request_server_url
|
21
|
-
rescue
|
22
|
-
request_server_url
|
23
|
-
end
|
24
|
-
init_connection()
|
25
|
-
if @config.auth
|
26
|
-
begin
|
27
|
-
@courses = JSON.parse get_courses_json
|
28
|
-
rescue => e
|
29
|
-
auth
|
30
|
-
end
|
31
|
-
else
|
32
|
-
output.puts "No username/password. run tmc auth"
|
33
|
-
end
|
19
|
+
setup_client
|
34
20
|
end
|
35
21
|
|
36
22
|
# stupid name - this should create connection, but not fetch courses.json!
|
@@ -156,7 +142,6 @@ class Client
|
|
156
142
|
output.print "Would you like to download all available exercises? Yn"
|
157
143
|
if ["", "y", "Y"].include? @input.gets.strip.chomp
|
158
144
|
Dir.chdir(course_name) do
|
159
|
-
course = @courses['courses'].select { |course| course['name'] == course_name }.first
|
160
145
|
download_new_exercises
|
161
146
|
end
|
162
147
|
end
|
@@ -201,7 +186,10 @@ class Client
|
|
201
186
|
Dir.mktmpdir do |tmpdir|
|
202
187
|
Dir.chdir tmpdir do
|
203
188
|
File.open("tmp.zip", 'wb') {|file| file.write(zip.body)}
|
204
|
-
|
189
|
+
#`unzip -n tmp.zip && rm tmp.zip`
|
190
|
+
full_path = File.join(Dir.pwd, 'tmp.zip')
|
191
|
+
unzip_file(full_path, Dir.pwd, exercise_dir_name)
|
192
|
+
`rm tmp.zip`
|
205
193
|
files = Dir.glob('**/*')
|
206
194
|
all_selected = false
|
207
195
|
files.each do |file|
|
@@ -222,8 +210,6 @@ class Client
|
|
222
210
|
rescue ArgumentError => e
|
223
211
|
output.puts "An error occurred #{e}"
|
224
212
|
end
|
225
|
-
elsif input == "b"
|
226
|
-
binding.pry
|
227
213
|
else
|
228
214
|
output.puts "Skipping file #{file}"
|
229
215
|
end
|
@@ -243,7 +229,10 @@ class Client
|
|
243
229
|
Dir.mktmpdir do |tmpdir|
|
244
230
|
Dir.chdir tmpdir do
|
245
231
|
File.open("tmp.zip", 'wb') {|file| file.write(zip.body)}
|
246
|
-
`unzip -n tmp.zip && rm tmp.zip`
|
232
|
+
# `unzip -n tmp.zip && rm tmp.zip`
|
233
|
+
full_path = File.join(Dir.pwd, 'tmp.zip')
|
234
|
+
unzip_file(full_path, Dir.pwd, exercise_dir_name)
|
235
|
+
`rm tmp.zip`
|
247
236
|
files = Dir.glob('**/*')
|
248
237
|
|
249
238
|
files.each do |file|
|
@@ -294,7 +283,21 @@ class Client
|
|
294
283
|
raise "Exercise already downloaded" if File.exists? exercise['name']
|
295
284
|
zip = fetch_zip(exercise['zip_url'])
|
296
285
|
File.open("tmp.zip", 'wb') {|file| file.write(zip.body)}
|
297
|
-
|
286
|
+
full_path = File.join(Dir.pwd, 'tmp.zip')
|
287
|
+
unzip_file(full_path, Dir.pwd, exercise_dir_name)
|
288
|
+
#`unzip -n tmp.zip && rm tmp.zip`
|
289
|
+
`rm tmp.zip`
|
290
|
+
end
|
291
|
+
|
292
|
+
def unzip_file (file, destination, exercise_dir_name)
|
293
|
+
Zip::ZipFile.open(file) do |zip_file|
|
294
|
+
zip_file.each do |f|
|
295
|
+
merged_path = f.name.sub(exercise_dir_name.gsub("-", "/"), "")
|
296
|
+
f_path=File.join(destination, exercise_dir_name, merged_path)
|
297
|
+
FileUtils.mkdir_p(File.dirname(f_path))
|
298
|
+
zip_file.extract(f, f_path) unless File.exist?(f_path)
|
299
|
+
end
|
300
|
+
end
|
298
301
|
end
|
299
302
|
|
300
303
|
# Filepath can be either relative or absolute
|
@@ -383,4 +386,23 @@ class Client
|
|
383
386
|
update_automatically_detected_project_from_zip(exercise['zip_url'], exercise_dir_name, course_dir_name, exercise, course)
|
384
387
|
end
|
385
388
|
end
|
389
|
+
|
390
|
+
protected
|
391
|
+
def setup_client
|
392
|
+
begin
|
393
|
+
@config.server_url ||= request_server_url
|
394
|
+
rescue
|
395
|
+
request_server_url
|
396
|
+
end
|
397
|
+
init_connection()
|
398
|
+
if @config.auth
|
399
|
+
begin
|
400
|
+
@courses = JSON.parse get_courses_json
|
401
|
+
rescue => e
|
402
|
+
auth
|
403
|
+
end
|
404
|
+
else
|
405
|
+
output.puts "No username/password. run tmc auth"
|
406
|
+
end
|
407
|
+
end
|
386
408
|
end
|
data/specs/config.yml
ADDED
data/specs/download_spec.rb
CHANGED
@@ -2,11 +2,20 @@ require_relative '../lib/tmc-client/client.rb'
|
|
2
2
|
require 'rspec'
|
3
3
|
require 'mocha/setup'
|
4
4
|
|
5
|
+
Client.class_eval do
|
6
|
+
def setup_client
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
5
10
|
describe Client do
|
6
11
|
subject do
|
7
12
|
c = Client.new
|
8
13
|
end
|
9
14
|
|
15
|
+
before(:each) do
|
16
|
+
subject.config = MyConfig.new
|
17
|
+
end
|
18
|
+
|
10
19
|
it "should be able to download a zip" do
|
11
20
|
received_zip_data = mock("faraday_object")
|
12
21
|
received_zip_data.expects(:body).returns(File.read(File.join(File.dirname(File.expand_path(__FILE__)), "ex.zip")))
|
data/specs/list_spec.rb
CHANGED
@@ -7,6 +7,10 @@ describe Client do
|
|
7
7
|
Client.new
|
8
8
|
end
|
9
9
|
|
10
|
+
before(:each) do
|
11
|
+
subject.config = MyConfig.new
|
12
|
+
end
|
13
|
+
|
10
14
|
it "should print all course names when listing courses" do
|
11
15
|
subject.courses = {"courses" => [{ "name" => "test_course1"}, {"name" => "test_course2" }] }
|
12
16
|
output = mock("output")
|
data/specs/submit_spec.rb
CHANGED
@@ -2,11 +2,20 @@ require_relative '../lib/tmc-client/client.rb'
|
|
2
2
|
require 'rspec'
|
3
3
|
require 'mocha'
|
4
4
|
|
5
|
+
Client.class_eval do
|
6
|
+
def setup_client
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
5
10
|
describe Client do
|
6
11
|
subject do
|
7
12
|
Client.new
|
8
13
|
end
|
9
14
|
|
15
|
+
before(:each) do
|
16
|
+
subject.config = MyConfig.new
|
17
|
+
end
|
18
|
+
|
10
19
|
its(:current_directory_name) { should == `pwd`.split("/").last.chomp }
|
11
20
|
its(:previous_directory_name) { should == `pwd`.split("/")[-2].chomp }
|
12
21
|
|
data/specs/update_spec.rb
CHANGED
@@ -2,11 +2,20 @@ require_relative '../lib/tmc-client/client.rb'
|
|
2
2
|
require 'rspec'
|
3
3
|
require 'mocha/setup'
|
4
4
|
|
5
|
+
Client.class_eval do
|
6
|
+
def setup_client
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
5
10
|
describe Client do
|
6
11
|
subject do
|
7
12
|
c = Client.new
|
8
13
|
end
|
9
14
|
|
15
|
+
before(:each) do
|
16
|
+
subject.config = MyConfig.new
|
17
|
+
end
|
18
|
+
|
10
19
|
after(:each) do
|
11
20
|
`rm -r update_universal_ex`
|
12
21
|
`rm -r update_ex`
|
data/tmc-client.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
|
3
|
-
|
2
|
+
s.name = 'tmc-client'
|
3
|
+
s.version = '0.0.2'
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
s.summary = 'TestMyCode Commandline client'
|
6
|
+
s.authors = ['Jarmo Isotalo', 'Tony Kovanen']
|
7
|
+
s.homepage = "https://github.com/TMCee/tmc-client/"
|
8
8
|
s.files = `git ls-files`.split("\n")
|
9
9
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
10
10
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -12,13 +12,12 @@ Gem::Specification.new do |s|
|
|
12
12
|
|
13
13
|
s.add_dependency "json"
|
14
14
|
s.add_dependency "faraday"
|
15
|
-
s.add_dependency "pry"
|
16
15
|
s.add_dependency "fileutils"
|
17
16
|
s.add_dependency "mocha"
|
18
17
|
s.add_dependency "highline"
|
19
18
|
s.add_dependency "rake"
|
20
|
-
s.add_dependency "
|
19
|
+
s.add_dependency "rubyzip"
|
21
20
|
|
22
|
-
s.add_development_dependency "rspec"
|
21
|
+
s.add_development_dependency "rspec"
|
23
22
|
|
24
|
-
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tmc-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-05-
|
13
|
+
date: 2013-05-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: json
|
@@ -44,22 +44,6 @@ dependencies:
|
|
44
44
|
- - ! '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: pry
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
type: :runtime
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
|
-
requirements:
|
60
|
-
- - ! '>='
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
63
47
|
- !ruby/object:Gem::Dependency
|
64
48
|
name: fileutils
|
65
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -125,7 +109,7 @@ dependencies:
|
|
125
109
|
- !ruby/object:Gem::Version
|
126
110
|
version: '0'
|
127
111
|
- !ruby/object:Gem::Dependency
|
128
|
-
name:
|
112
|
+
name: rubyzip
|
129
113
|
requirement: !ruby/object:Gem::Requirement
|
130
114
|
none: false
|
131
115
|
requirements:
|
@@ -145,17 +129,17 @@ dependencies:
|
|
145
129
|
requirement: !ruby/object:Gem::Requirement
|
146
130
|
none: false
|
147
131
|
requirements:
|
148
|
-
- -
|
132
|
+
- - ! '>='
|
149
133
|
- !ruby/object:Gem::Version
|
150
|
-
version: '
|
134
|
+
version: '0'
|
151
135
|
type: :development
|
152
136
|
prerelease: false
|
153
137
|
version_requirements: !ruby/object:Gem::Requirement
|
154
138
|
none: false
|
155
139
|
requirements:
|
156
|
-
- -
|
140
|
+
- - ! '>='
|
157
141
|
- !ruby/object:Gem::Version
|
158
|
-
version: '
|
142
|
+
version: '0'
|
159
143
|
description:
|
160
144
|
email:
|
161
145
|
executables:
|
@@ -166,8 +150,7 @@ files:
|
|
166
150
|
- .gitignore
|
167
151
|
- .travis.yml
|
168
152
|
- Gemfile
|
169
|
-
-
|
170
|
-
- Readme.md
|
153
|
+
- README.md
|
171
154
|
- bin/tmc-client
|
172
155
|
- lib/tmc-client.rb
|
173
156
|
- lib/tmc-client/client.rb
|
@@ -175,6 +158,7 @@ files:
|
|
175
158
|
- lib/tmc-client/config.yml
|
176
159
|
- lib/tmc-client/my_config.rb
|
177
160
|
- lib/tmc-client/old-client.rb
|
161
|
+
- specs/config.yml
|
178
162
|
- specs/download_spec.rb
|
179
163
|
- specs/ex.zip
|
180
164
|
- specs/list_spec.rb
|
@@ -183,7 +167,6 @@ files:
|
|
183
167
|
- specs/update_spec.rb
|
184
168
|
- specs/update_universal_ex.zip
|
185
169
|
- tmc
|
186
|
-
- tmc-client-0.0.1.gem
|
187
170
|
- tmc-client.gemspec
|
188
171
|
homepage: https://github.com/TMCee/tmc-client/
|
189
172
|
licenses: []
|
data/Gemfile.lock
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: https://rubygems.org/
|
3
|
-
specs:
|
4
|
-
coderay (1.0.9)
|
5
|
-
diff-lcs (1.1.3)
|
6
|
-
faraday (0.8.7)
|
7
|
-
multipart-post (~> 1.1)
|
8
|
-
fileutils (0.7)
|
9
|
-
rmagick (>= 2.13.1)
|
10
|
-
highline (1.6.18)
|
11
|
-
json (1.7.7)
|
12
|
-
metaclass (0.0.1)
|
13
|
-
method_source (0.8.1)
|
14
|
-
mocha (0.13.3)
|
15
|
-
metaclass (~> 0.0.1)
|
16
|
-
multipart-post (1.2.0)
|
17
|
-
pry (0.9.12)
|
18
|
-
coderay (~> 1.0.5)
|
19
|
-
method_source (~> 0.8)
|
20
|
-
slop (~> 3.4)
|
21
|
-
rake (10.0.4)
|
22
|
-
rmagick (2.13.2)
|
23
|
-
rspec (2.12.0)
|
24
|
-
rspec-core (~> 2.12.0)
|
25
|
-
rspec-expectations (~> 2.12.0)
|
26
|
-
rspec-mocks (~> 2.12.0)
|
27
|
-
rspec-core (2.12.2)
|
28
|
-
rspec-expectations (2.12.1)
|
29
|
-
diff-lcs (~> 1.1.3)
|
30
|
-
rspec-mocks (2.12.2)
|
31
|
-
slop (3.4.4)
|
32
|
-
|
33
|
-
PLATFORMS
|
34
|
-
ruby
|
35
|
-
|
36
|
-
DEPENDENCIES
|
37
|
-
faraday
|
38
|
-
fileutils
|
39
|
-
highline
|
40
|
-
json
|
41
|
-
mocha
|
42
|
-
pry
|
43
|
-
rake
|
44
|
-
rspec
|
data/Readme.md
DELETED
File without changes
|