codewars 0.1.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/LICENSE +21 -0
- data/README.md +49 -0
- data/bin/codewars +9 -0
- data/codewars.gemspec +31 -0
- data/lib/codewars.rb +14 -0
- data/lib/codewars/attempt.rb +60 -0
- data/lib/codewars/cli.rb +25 -0
- data/lib/codewars/config.rb +15 -0
- data/lib/codewars/configuration.rb +28 -0
- data/lib/codewars/description.rb +39 -0
- data/lib/codewars/description_template.erb +34 -0
- data/lib/codewars/finalize.rb +31 -0
- data/lib/codewars/language_extensions.rb +18 -0
- data/lib/codewars/runner.rb +56 -0
- data/lib/codewars/train_next.rb +29 -0
- data/lib/codewars/train_specific.rb +56 -0
- data/lib/codewars/version.rb +3 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e4dddc1a09377085643f16eea71fce41a4a9d31
|
4
|
+
data.tar.gz: 3cd42b90f917e19b5fa4bb38fe278b218d723daa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6695455d2851b69dcaceda15efb5c9b78d35c3c482c4f1da7ed05e97aa6571b30ee0148787836a06ba8dc0796e359b5320b526e8170b0cf0d6353491e995d5c5
|
7
|
+
data.tar.gz: 107cb38b4d340d68e81f3d141c71cc82a99b7b38b30eaaf6f5dfc10111c2537b31efc5ec639a619297474fa166e8ed5a637cdce48dc8f350d14523558bb77168
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Evgeny Morozov
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Codewars command-line tool
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Execute `gem install codewars`
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Execute `codewars help` to see all available commands.
|
10
|
+
|
11
|
+
1. Set an api-key from the codewars website `codewars config key your-secret-key`
|
12
|
+
2. Set a language you want to use `codewars config language ruby|javascript|etc`
|
13
|
+
3. Choose a kata which you want to solve `codewars train`
|
14
|
+
4. Start solving the kata `codewars train name-of-kata`
|
15
|
+
5. Go to created folder `cd name-of-kata/language/`
|
16
|
+
6. Look at description.md (use a Markdown viewer)
|
17
|
+
7. According to the description of the kata change or create tests using your favorite test framework
|
18
|
+
8. Change the solution.* file so the tests become green
|
19
|
+
9. Upload the solution and wait for a response of tests on the server `codewars attempt`
|
20
|
+
10. If there are no mistakes finalize the previously attempted solution `codewars finalize`
|
21
|
+
11. Look at results of other people, rest and pick up another kata or the same kata but using another language
|
22
|
+
|
23
|
+
## Development
|
24
|
+
|
25
|
+
### TO-DO
|
26
|
+
|
27
|
+
- [ ] Refactor anything you can
|
28
|
+
- [ ] Add travis, coveralls, etc
|
29
|
+
- [ ] Change the name of commands: attempt and finalize (join them to one command?)
|
30
|
+
- [ ] Rename 'config' command? Maybe to 'set'?
|
31
|
+
- [ ] Add options to commands that can be added: --strategy=something, --language=something, etc.
|
32
|
+
- [ ] Make 100% coverage in simplecov
|
33
|
+
- [ ] Write RSpec module tests
|
34
|
+
- [ ] Divide description.md to task.md + info.yml?
|
35
|
+
- [ ] Refactor features so stubbing (mocking) become more obvious
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
Bug reports, pull requests and ideas are welcome!
|
40
|
+
|
41
|
+
Steps to make a pull request:
|
42
|
+
|
43
|
+
1. Fork it ( https://github.com/evmorov/codewars/fork )
|
44
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
45
|
+
3. Make changes
|
46
|
+
4. Add tests for it
|
47
|
+
5. Commit your changes (`git commit -am 'Add some feature'`)
|
48
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
49
|
+
7. Create a new Pull Request
|
data/bin/codewars
ADDED
data/codewars.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'codewars/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'codewars'
|
8
|
+
spec.version = Codewars::VERSION
|
9
|
+
spec.authors = ['Evgeny Morozov']
|
10
|
+
spec.email = ['evmorov@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'A command-line tool for Codewars'
|
13
|
+
spec.homepage = 'https://github.com/evmorov/codewars'
|
14
|
+
|
15
|
+
spec.files = %w(LICENSE README.md codewars.gemspec) + Dir['bin/*'] +
|
16
|
+
Dir['lib/**/*.rb'] + Dir['lib/**/*.erb']
|
17
|
+
spec.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
spec.licenses = ['MIT']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'webmock', '~> 1.21'
|
24
|
+
spec.add_development_dependency 'aruba', '~> 0.11'
|
25
|
+
spec.add_development_dependency 'pry-byebug'
|
26
|
+
spec.add_development_dependency 'simplecov'
|
27
|
+
spec.add_development_dependency 'rubocop'
|
28
|
+
|
29
|
+
spec.add_dependency 'codewars_api', '~> 0.2'
|
30
|
+
spec.add_dependency 'thor', '~> 0.19'
|
31
|
+
end
|
data/lib/codewars.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
CODEWARS_URL = 'http://www.codewars.com'
|
2
|
+
|
3
|
+
require 'codewars_api'
|
4
|
+
require 'thor'
|
5
|
+
require 'codewars/version'
|
6
|
+
require 'codewars/configuration'
|
7
|
+
require 'codewars/config'
|
8
|
+
require 'codewars/language_extensions'
|
9
|
+
require 'codewars/description'
|
10
|
+
require 'codewars/train_specific'
|
11
|
+
require 'codewars/train_next'
|
12
|
+
require 'codewars/attempt'
|
13
|
+
require 'codewars/finalize'
|
14
|
+
require 'codewars/cli'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Codewars
|
2
|
+
class Attempt < Thor
|
3
|
+
def initialize
|
4
|
+
api_key = Configuration.option('api_key')
|
5
|
+
fail Thor::Error, 'You should set an api-key to use this command' unless api_key
|
6
|
+
|
7
|
+
desc = Description.new
|
8
|
+
project_id = desc.take_value_from_file(/Project ID: (\w+)/, 'Project ID')
|
9
|
+
solution_id = desc.take_value_from_file(/Solution ID: (\w+)/, 'Solution ID')
|
10
|
+
solution = read_solution_file
|
11
|
+
|
12
|
+
client = CodewarsApi::Client.new(api_key: api_key)
|
13
|
+
attempt = client.attempt_solution(
|
14
|
+
project_id: project_id,
|
15
|
+
solution_id: solution_id,
|
16
|
+
code: solution
|
17
|
+
)
|
18
|
+
|
19
|
+
say 'Your solution has been uploaded. Waiting for a result of tests on the server.'
|
20
|
+
|
21
|
+
deferred_response = deferred_response(client, attempt)
|
22
|
+
handle_deferred_response(deferred_response)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def read_solution_file
|
28
|
+
file_name = 'solution.*'
|
29
|
+
solution_filename = Dir.glob(file_name).first
|
30
|
+
unless solution_filename
|
31
|
+
fail Thor::Error, "The file '#{file_name}' has not been found in the current directory."
|
32
|
+
end
|
33
|
+
File.read File.expand_path(solution_filename)
|
34
|
+
end
|
35
|
+
|
36
|
+
def deferred_response(client, attempt)
|
37
|
+
seconds = ENV['CHECK_TIMEOUT'] || 10
|
38
|
+
seconds.to_i.times do
|
39
|
+
deferred_response = client.deferred_response(dmid: attempt.dmid)
|
40
|
+
return deferred_response if deferred_response.success
|
41
|
+
sleep 1
|
42
|
+
end
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def handle_deferred_response(deferred_response)
|
47
|
+
if deferred_response.nil? || !deferred_response.success
|
48
|
+
fail Thor::Error, "Can't get a result of tests on the server. Try it again."
|
49
|
+
end
|
50
|
+
|
51
|
+
if deferred_response.valid
|
52
|
+
say 'The solution has passed all tests on the server.'
|
53
|
+
say 'Type to finalize the solution: ' + set_color('codewars finalize', :blue, true)
|
54
|
+
else
|
55
|
+
error 'The solution has not passed tests on the server. Response:'
|
56
|
+
fail Thor::Error, set_color(deferred_response.reason, :red)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/codewars/cli.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Codewars
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'config SUBCOMMAND ...ARGS', 'Write options to the configuration file'
|
4
|
+
subcommand 'config', Config
|
5
|
+
|
6
|
+
desc 'train', 'Train a next kata'
|
7
|
+
def train(id_or_slug = nil)
|
8
|
+
if id_or_slug
|
9
|
+
TrainSpecific.new(id_or_slug)
|
10
|
+
else
|
11
|
+
TrainNext.new
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'attempt', 'Send a solution and get a result'
|
16
|
+
def attempt
|
17
|
+
Attempt.new
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'finalize', 'Finalize the previously attempted solution'
|
21
|
+
def finalize
|
22
|
+
Finalize.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Codewars
|
2
|
+
class Config < Thor
|
3
|
+
desc 'key YOUR_SECRET_KEY', 'Your api key'
|
4
|
+
def key(secret_key)
|
5
|
+
Configuration.write_option_to_config('api_key', secret_key)
|
6
|
+
say "You've successefully added the api-key to the configuration file"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'language DEFAULT_LANGUAGE', 'A default language to use'
|
10
|
+
def language(default_language)
|
11
|
+
Configuration.write_option_to_config('language', default_language)
|
12
|
+
say "You've successefully added the default language to the configuration file"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Codewars
|
4
|
+
class Configuration
|
5
|
+
CONFIG_NAME = '.codewarsrc'
|
6
|
+
|
7
|
+
def self.write_option_to_config(option, value)
|
8
|
+
config_hash = config
|
9
|
+
config_hash[option] = value
|
10
|
+
|
11
|
+
config_str = ''
|
12
|
+
config_hash.each { |k, v| config_str += "#{k}: #{v}\n" }
|
13
|
+
File.write(config_path, config_str)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.config
|
17
|
+
File.exist?(config_path) ? YAML.load_file(config_path) : {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config_path
|
21
|
+
"#{ENV['HOME']}/#{CONFIG_NAME}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.option(option)
|
25
|
+
config[option]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Codewars
|
2
|
+
class Description < Thor::Shell::Basic
|
3
|
+
DESCRIPTION_FILE_NAME = 'description.md'
|
4
|
+
|
5
|
+
def take_value_from_file(regex_with_group, param_key)
|
6
|
+
@data ||= read_file(DESCRIPTION_FILE_NAME)
|
7
|
+
param = @data.match(regex_with_group)
|
8
|
+
unless param
|
9
|
+
fail Thor::Error, "'#{param_key}' has not been found in the 'description.md' file."
|
10
|
+
end
|
11
|
+
param[1]
|
12
|
+
end
|
13
|
+
|
14
|
+
def print_kata_desc(kata)
|
15
|
+
print_parameter('Name', kata.name)
|
16
|
+
print_parameter('Link', "#{CODEWARS_URL}#{kata.href}")
|
17
|
+
print_parameter('Description', kata.description)
|
18
|
+
print_parameter('Tags', kata.tags.join(', ')) if kata.tags
|
19
|
+
print_parameter('Rank', kata.rank.to_s) if kata.rank
|
20
|
+
say ''
|
21
|
+
print_parameter('Type to start this kata',
|
22
|
+
"codewars train #{kata.slug}", :blue, true)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def read_file(file_name)
|
28
|
+
desc_path = File.expand_path(file_name)
|
29
|
+
unless File.exist? desc_path
|
30
|
+
fail Thor::Error, "The file '#{file_name}' has not been found in the current directory."
|
31
|
+
end
|
32
|
+
File.read(desc_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def print_parameter(parameter, value, value_color = nil, value_bold = false)
|
36
|
+
say set_color("#{parameter}: ", :green) + set_color(value, value_color, value_bold)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
## Description of the kata
|
2
|
+
|
3
|
+
Name: <%= kata.name %>
|
4
|
+
|
5
|
+
URL: <%= codewars_url %>/kata/<%= kata.slug %>
|
6
|
+
|
7
|
+
Author: <%= kata.author %>
|
8
|
+
|
9
|
+
Rank: <%= kata.rank %>
|
10
|
+
|
11
|
+
Slug: <%= kata.slug %>
|
12
|
+
|
13
|
+
Project ID: <%= kata.project_id %>
|
14
|
+
|
15
|
+
Solution ID: <%= kata.solution_id %>
|
16
|
+
|
17
|
+
Tags: <%= kata.tags.join(', ') %>
|
18
|
+
|
19
|
+
### Task
|
20
|
+
|
21
|
+
<%= kata.description %>
|
22
|
+
|
23
|
+
### Code
|
24
|
+
|
25
|
+
```<%= language %>
|
26
|
+
<%= kata.code_setup %>
|
27
|
+
```
|
28
|
+
<% unless kata.tests_setup.to_s.empty? %>
|
29
|
+
### Test
|
30
|
+
|
31
|
+
```<%= language %>
|
32
|
+
<%= kata.tests_setup %>
|
33
|
+
```
|
34
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Codewars
|
2
|
+
class Finalize < Thor
|
3
|
+
def initialize
|
4
|
+
api_key = Configuration.option('api_key')
|
5
|
+
fail Thor::Error, 'You should set an api-key to use this command' unless api_key
|
6
|
+
|
7
|
+
desc = Description.new
|
8
|
+
slug = desc.take_value_from_file(/Slug: ([a-zA-Z_-]+)/, 'Slug')
|
9
|
+
project_id = desc.take_value_from_file(/Project ID: (\w+)/, 'Project ID')
|
10
|
+
solution_id = desc.take_value_from_file(/Solution ID: (\w+)/, 'Solution ID')
|
11
|
+
|
12
|
+
client = CodewarsApi::Client.new(api_key: api_key)
|
13
|
+
result = client.finalize_solution(
|
14
|
+
project_id: project_id,
|
15
|
+
solution_id: solution_id
|
16
|
+
)
|
17
|
+
handle_result(result, slug)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def handle_result(result, slug)
|
23
|
+
if result.success
|
24
|
+
say 'Your solution has been finalized.'
|
25
|
+
say "Other solutions can be found here: #{CODEWARS_URL}/kata/#{slug}/solutions/"
|
26
|
+
else
|
27
|
+
fail Thor::Error, 'Something went wrong. Try to sumbit the solution again.'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Codewars
|
2
|
+
class LanguageExtensions
|
3
|
+
MAPPING = {
|
4
|
+
'ruby' => 'rb',
|
5
|
+
'coffeescript' => 'coffee',
|
6
|
+
'javascript' => 'js',
|
7
|
+
'python' => 'py',
|
8
|
+
'haskell' => 'hs',
|
9
|
+
'csharp' => 'cs',
|
10
|
+
'closure' => 'clj'
|
11
|
+
}
|
12
|
+
|
13
|
+
def self.get(language)
|
14
|
+
extension = MAPPING[language]
|
15
|
+
extension ? extension : language
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'codewars'
|
2
|
+
|
3
|
+
# to use Webmock we need the Runner class
|
4
|
+
# https://github.com/cucumber/aruba#testing-ruby-cli-programs-without-spawning-a-new-ruby-process
|
5
|
+
module Codewars
|
6
|
+
class Runner
|
7
|
+
def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
|
8
|
+
init_pry
|
9
|
+
@argv = argv
|
10
|
+
@stdin = stdin
|
11
|
+
@stdout = stdout
|
12
|
+
@stderr = stderr
|
13
|
+
@kernel = kernel
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute!
|
17
|
+
exit_code = run_cli
|
18
|
+
@kernel.exit(exit_code)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def init_pry
|
24
|
+
require 'pry'
|
25
|
+
Pry.config.output = STDOUT # without this Pry does't work properly
|
26
|
+
rescue LoadError
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# rubocop:disable Metrics/MethodLength
|
31
|
+
def run_cli
|
32
|
+
exit_code = begin
|
33
|
+
$stderr = @stderr
|
34
|
+
$stdin = @stdin
|
35
|
+
$stdout = @stdout
|
36
|
+
|
37
|
+
Codewars::CLI.start(@argv)
|
38
|
+
|
39
|
+
0
|
40
|
+
rescue StandardError => e
|
41
|
+
b = e.backtrace
|
42
|
+
@stderr.puts("#{b.shift}: #{e.message} (#{e.class})")
|
43
|
+
@stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
|
44
|
+
1
|
45
|
+
rescue SystemExit => e
|
46
|
+
e.status
|
47
|
+
ensure
|
48
|
+
$stderr = STDERR
|
49
|
+
$stdin = STDIN
|
50
|
+
$stdout = STDOUT
|
51
|
+
end
|
52
|
+
|
53
|
+
@kernel.exit(exit_code)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Codewars
|
2
|
+
class TrainNext < Thor::Shell::Basic
|
3
|
+
def initialize
|
4
|
+
message = []
|
5
|
+
api_key = Configuration.option('api_key')
|
6
|
+
message.push 'You should set an api-key to use this command' unless api_key
|
7
|
+
language = Configuration.option('language')
|
8
|
+
message.push 'You should set an default language to use this command' unless language
|
9
|
+
fail Thor::Error, message.join("\n") unless message.empty?
|
10
|
+
|
11
|
+
client = CodewarsApi::Client.new(api_key: api_key)
|
12
|
+
kata = client.train_next_kata(
|
13
|
+
language: language,
|
14
|
+
peek: 'true',
|
15
|
+
strategy: 'default'
|
16
|
+
)
|
17
|
+
handle_next_kata(kata)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def handle_next_kata(kata)
|
23
|
+
if !kata.success && (kata.reason.eql? 'unauthorized')
|
24
|
+
fail Thor::Error, 'Wrong api key'
|
25
|
+
end
|
26
|
+
Description.new.print_kata_desc(kata)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Codewars
|
4
|
+
class TrainSpecific < Thor
|
5
|
+
def initialize(id_or_slug)
|
6
|
+
message = []
|
7
|
+
api_key = Configuration.option('api_key')
|
8
|
+
message.push 'You should set an api-key to use this command' unless api_key
|
9
|
+
language = Configuration.option('language')
|
10
|
+
message.push 'You should set an default language to use this command' unless language
|
11
|
+
fail Thor::Error, message.join("\n") unless message.empty?
|
12
|
+
|
13
|
+
say "Starting the '#{id_or_slug}' kata."
|
14
|
+
|
15
|
+
client = CodewarsApi::Client.new(api_key: api_key)
|
16
|
+
kata = client.train_specific_kata(
|
17
|
+
language: language,
|
18
|
+
id_or_slug: id_or_slug
|
19
|
+
)
|
20
|
+
handle_specific_kata(kata, language)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def handle_specific_kata(kata, language)
|
26
|
+
slug = kata.slug
|
27
|
+
write_kata(slug, language, 'description.md', description(kata, language))
|
28
|
+
exten = LanguageExtensions.get(language)
|
29
|
+
unless kata.tests_setup.to_s.empty?
|
30
|
+
write_kata(slug, language, "test.#{exten}", kata.tests_setup)
|
31
|
+
end
|
32
|
+
write_kata(slug, language, "solution.#{exten}", kata.code_setup)
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_kata(slug, language, file_name, content)
|
36
|
+
dir_to_write = File.expand_path(slug)
|
37
|
+
Dir.mkdir dir_to_write unless File.directory?(dir_to_write)
|
38
|
+
Dir.mkdir "#{dir_to_write}/#{language}" unless File.directory?("#{dir_to_write}/#{language}")
|
39
|
+
file_path = File.expand_path("#{dir_to_write}/#{language}/#{file_name}")
|
40
|
+
relative_path = "./#{slug}/#{language}/#{file_name}"
|
41
|
+
fail Thor::Error, "'#{relative_path}' already exists." if File.exist? file_path
|
42
|
+
|
43
|
+
File.write(file_path, content)
|
44
|
+
say "'#{relative_path}' has been created."
|
45
|
+
end
|
46
|
+
|
47
|
+
def description(kata, language)
|
48
|
+
b = binding
|
49
|
+
b.local_variable_set(:kata, kata)
|
50
|
+
b.local_variable_set(:language, language)
|
51
|
+
b.local_variable_set(:codewars_url, CODEWARS_URL)
|
52
|
+
template_path = File.expand_path("#{File.dirname(__FILE__)}/description_template.erb")
|
53
|
+
ERB.new(File.read template_path).result(b)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: codewars
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Evgeny Morozov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: webmock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.21'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.21'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: aruba
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: codewars_api
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.2'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: thor
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.19'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.19'
|
139
|
+
description:
|
140
|
+
email:
|
141
|
+
- evmorov@gmail.com
|
142
|
+
executables:
|
143
|
+
- codewars
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- LICENSE
|
148
|
+
- README.md
|
149
|
+
- bin/codewars
|
150
|
+
- codewars.gemspec
|
151
|
+
- lib/codewars.rb
|
152
|
+
- lib/codewars/attempt.rb
|
153
|
+
- lib/codewars/cli.rb
|
154
|
+
- lib/codewars/config.rb
|
155
|
+
- lib/codewars/configuration.rb
|
156
|
+
- lib/codewars/description.rb
|
157
|
+
- lib/codewars/description_template.erb
|
158
|
+
- lib/codewars/finalize.rb
|
159
|
+
- lib/codewars/language_extensions.rb
|
160
|
+
- lib/codewars/runner.rb
|
161
|
+
- lib/codewars/train_next.rb
|
162
|
+
- lib/codewars/train_specific.rb
|
163
|
+
- lib/codewars/version.rb
|
164
|
+
homepage: https://github.com/evmorov/codewars
|
165
|
+
licenses:
|
166
|
+
- MIT
|
167
|
+
metadata: {}
|
168
|
+
post_install_message:
|
169
|
+
rdoc_options: []
|
170
|
+
require_paths:
|
171
|
+
- lib
|
172
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
177
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
requirements: []
|
183
|
+
rubyforge_project:
|
184
|
+
rubygems_version: 2.4.5
|
185
|
+
signing_key:
|
186
|
+
specification_version: 4
|
187
|
+
summary: A command-line tool for Codewars
|
188
|
+
test_files: []
|
189
|
+
has_rdoc:
|