codewars_cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 622cacf0166844f7f9de6053724b756a3e8cd2ce
4
+ data.tar.gz: 5da61b3297094e17efdf8979144eec32c3217b73
5
+ SHA512:
6
+ metadata.gz: a826ffa99620707ae31cd56884e09aa4dc39ef7d54e9868e80f8d2c555e6a2eeb55373965936d7815d8ed9919ca9fddae922925358045460c0fdd95b622d9310
7
+ data.tar.gz: d49f0d316b83921babb8d727ab0405a464a6711ccb8b5610ff97befceee541bb45e83a6731093931d57cc3054787ee00daf97386132e65f6d639a5ba862f6525
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
4
+ before_install: gem install bundler -v 1.10.6
5
+ script:
6
+ - rake
7
+ - rake features
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in codewars_cli.gemspec
4
+
5
+ gemspec
6
+
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 GustavoCaso
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,107 @@
1
+ ![Travis Build](https://travis-ci.org/GustavoCaso/codewars_cli.svg?branch=master)
2
+ # CodewarsCli
3
+
4
+ With this command you would be able to enjoy [Codewars](http://www.codewars.com/), a site where you can practice your coding skills
5
+
6
+ ## Installation
7
+
8
+ ```
9
+ gem install codewars_cli
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ The start working you would need an account in [Codewars](http://www.codewars.com/join), if you have it already great!.
15
+ To start using the CLI you will need setup up a few things first.
16
+
17
+ ##Comands
18
+
19
+ ### Configuration
20
+ There are a few commands you can use to configuration your CLI, the most important one is to setup your api_key, first you will need to get it from your account of [Codewars](https://www.codewars.com/users/edit).
21
+
22
+ To setup your api_key `codewars config api_key YOUR_API_KEY`.
23
+
24
+ There are other options you can configure **language** and **folder**.
25
+
26
+ The language is your favorite option for downloading. Also you can specify everytime you start a new session what language you want use.
27
+
28
+ To setup your language `codewars config language LANGUAGE`.
29
+
30
+ ### Valid Languages
31
+
32
+ ```
33
+ ruby
34
+ javascript
35
+ java
36
+ coffeescript
37
+ haskell
38
+ clojure
39
+ c
40
+ python
41
+ ```
42
+
43
+
44
+ The folder option is where all your description file will be downloaded.
45
+
46
+ The file structure will be: `~/YOUR_FOLDER/#{NAME_OF_THE_KATA}/#{LANGUAGE}`
47
+
48
+ To setup your language `codewars config folder FOLDER`.
49
+
50
+ Once you have finish the setup up, you can changed but you will have to pass a flag `update` to tell the application to overwrite it.
51
+
52
+ ##### Example
53
+
54
+ To overwrite your api_key `codewars config api_key YOUR_API_KEY --update`.
55
+
56
+ ### User
57
+ Display all the information related to a Codewars user in your Terminal.
58
+
59
+ `codewars user USERNAME_OR_ID` will display the information well formatted for your eyes.
60
+
61
+ ![User_dispay_info](https://cloud.githubusercontent.com/assets/4672858/12372466/8bb2e012-bc58-11e5-8fac-325108ebfdf6.png)
62
+
63
+ ### Next Kata
64
+ Start a new session of training and download all the information related to a new kata.
65
+ This command will create a `description.md` file with all the information of the Kata and some metadata that is need it for submiting the kata later.
66
+
67
+ Also it will create a `solution.{LANGUAGE_EXTENSION}` file where you should place your code in other to be uploaded when submitting the kata.
68
+
69
+ `codewars next_kata` [Valid languages](#valid-languages)
70
+
71
+ To specify a a different language just add a new param as the language you want to train.
72
+
73
+ `codewars next_kata javascript`
74
+
75
+ ### Submit Kata
76
+ When submitting a kata, the application will upload your code to the Codewars server and will wait for the server to respond with the result, depending on the respond, the kata could be **finalized** or keep working on it.
77
+
78
+ To submit use `codewars submit KATA_NAME`
79
+
80
+ By Default it will use you predefined language, but you can always specify a different one:
81
+
82
+ `codewars submit KATA_NAME --language=LANGUAGE` [Valid languages](#valid-languages)
83
+
84
+
85
+ In case the name is not correct it will display a formatted list with all your katas order by language to help you.
86
+
87
+ ### Finalize
88
+ This is the last step of the process.
89
+
90
+ To finish a kata type `codewars finalize KATA_NAME`
91
+
92
+ As well you can specify the language of the kata `codewars finalize KATA_NAME --language=LANGUAGE` [Valid languages](#valid-languages)
93
+
94
+ It will close the kata four you.
95
+
96
+
97
+
98
+
99
+ ## Contributing
100
+
101
+ Bug reports and pull requests are welcome on GitHub at https://github.com/GustavoCaso/codewars_cli. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
102
+
103
+
104
+ ## License
105
+
106
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
107
+
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require 'cucumber'
4
+ require 'cucumber/rake/task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ Cucumber::Rake::Task.new(:features) do |t|
8
+ t.cucumber_opts = "features --format pretty -x"
9
+ end
10
+
11
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby -U
2
+
3
+ Signal.trap('INT') { abort }
4
+
5
+ lib = File.expand_path('../../lib', __FILE__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+
8
+ require 'codewars_cli/runner'
9
+ CodewarsCli::Runner.new(ARGV.dup).execute!
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'codewars_cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "codewars_cli"
8
+ spec.version = CodewarsCli::VERSION
9
+ spec.authors = ["GustavoCaso"]
10
+ spec.email = ["gustavocaso@gmail.com"]
11
+
12
+ spec.summary = %q{CLI tool to interact with codewars in the comfort of your terminal}
13
+ spec.description = %q{CLI tool to interact with codewars in the comfort of your terminal,
14
+ allow you to fetch users information, kata, upload solutions and close it.
15
+ }
16
+ spec.homepage = "https://github.com/GustavoCaso/codewars_cli"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ spec.executables = Dir['bin/*'].map { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_runtime_dependency 'thor'
24
+ spec.add_runtime_dependency "codewars_client"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.10"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "aruba"
30
+ spec.add_development_dependency "pry"
31
+ spec.add_development_dependency 'webmock'
32
+ end
@@ -0,0 +1,17 @@
1
+ require 'thor'
2
+ require 'codewars_client'
3
+ require 'codewars_cli/file_parser_helpers'
4
+ require "codewars_cli/generic_helpers"
5
+ require "codewars_cli/presenter"
6
+ require 'codewars_cli/file_creator'
7
+ require 'codewars_cli/finalize'
8
+ require 'codewars_cli/deferred'
9
+ require "codewars_cli/submit_kata"
10
+ require "codewars_cli/kata"
11
+ require "codewars_cli/user"
12
+ require "codewars_cli/client"
13
+ require 'codewars_cli/language'
14
+ require "codewars_cli/configuration"
15
+ require "codewars_cli/config"
16
+ require "codewars_cli/cli"
17
+ require "codewars_cli/version"
@@ -0,0 +1,29 @@
1
+ module CodewarsCli
2
+ class Cli < Thor
3
+ desc 'config SUBCOMMAND ...ARGS', 'Write options in the configuration file'
4
+ subcommand 'config', Config
5
+
6
+ desc 'user USERNAME_OR_ID', 'return user information'
7
+ def user(username_or_id)
8
+ User.fetch(username_or_id).print_description
9
+ end
10
+
11
+ desc 'next_kata', 'start a new session training session and create markdown page with kata information'
12
+ option :language, banner: " ruby | c | javascript | java | coffescript | haskell | clojure"
13
+ def next_kata
14
+ Kata.fetch(options[:language]).create_file
15
+ end
16
+
17
+ desc 'submit_kata', 'upload solution to codewars'
18
+ option :language, banner: 'The language of the kata if not provided will get the deafult one'
19
+ def submit_kata(kata_name)
20
+ SubmitKata.find(kata_name, options[:language]).upload_kata
21
+ end
22
+
23
+ desc 'finalize', 'finalize kata'
24
+ option :language, banner: 'The language of the kata if not provided will get the deafult one'
25
+ def finalize(kata_name)
26
+ Finalize.find(kata_name, options[:language])
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ module CodewarsCli
2
+ module Client
3
+ def self.connection
4
+ CodewarsClient.api_key = Configuration.api_key
5
+ CodewarsClient
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ module CodewarsCli
2
+ module Concerns
3
+ module AttributesMethods
4
+ def attributes
5
+ _build_attributes(self)
6
+ end
7
+
8
+ private
9
+
10
+ def _build_attributes(object)
11
+ object.instance_variables.inject({}) do |hash, key|
12
+ hash[key.to_s.gsub('@', '').to_sym] = object.instance_variable_get(key)
13
+ hash
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ module CodewarsCli
2
+ class Config < Thor
3
+ desc 'api_key KEY', 'Set the global configuration for api_key'
4
+ method_options update: :boolean
5
+ def api_key(api_key)
6
+ Configuration.write(api_key, :api_key, options)
7
+ end
8
+
9
+ desc 'language LANGUAGE', 'Set the global configuration for language'
10
+ long_desc <<-LONGDESC
11
+ `language LANGUAGE` will store the prefer language for trainnig katas.
12
+
13
+ Available options are:\n
14
+ - Ruby\n
15
+ - Javascript\n
16
+ - Java\n
17
+ - Coffescript\n
18
+ - Haskell\n
19
+ - C#\n
20
+ - Python\n
21
+ - Clojure\n
22
+ LONGDESC
23
+ method_options update: :boolean
24
+ def language(language)
25
+ Configuration.write(language, :language, options)
26
+ end
27
+
28
+ desc 'folder FOLDER', 'Set the global configuration for folder where all the kata information will be stored'
29
+ long_desc <<-LONGDESC
30
+ `folder FOLDER` will store the prefer location for file information.
31
+
32
+ It will create a folder for each language that you train,
33
+ containing the markdown file with all the information about the kata,
34
+ and the file to complete the kata
35
+ LONGDESC
36
+ method_options update: :boolean
37
+ def folder(folder)
38
+ Configuration.write(folder, :folder, options)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,55 @@
1
+ require 'yaml'
2
+ module CodewarsCli
3
+ module Configuration
4
+ include GenericHelpers
5
+ CONFIG_FILE = '.codewars.rc.yml'
6
+ CONFIG_CONTENTS = {
7
+ api_key: '',
8
+ language: '',
9
+ folder: '',
10
+ }
11
+
12
+ def self.write(value, key, options)
13
+ create_config_file unless File.exists? config_file
14
+ update_value(value, key) && return if options['update'] && !send(key).empty?
15
+ if !send(key).empty?
16
+ info "Do you want to overwrite #{key} provide --update option"
17
+ else
18
+ info "Updating config file with #{key}: #{value}"
19
+ update_value(value, key)
20
+ end
21
+ end
22
+
23
+ def self.update_value(value, key)
24
+ content = config_data
25
+ content.send(:[]=, key, value)
26
+ File.open(config_file, 'w') do |f|
27
+ f.write(content.to_yaml)
28
+ end
29
+ end
30
+
31
+ def self.create_config_file
32
+ File.open(config_file, 'w+') { |f| f.write(CONFIG_CONTENTS.to_yaml) }
33
+ end
34
+
35
+ def self.api_key
36
+ config_data[:api_key] if config_data
37
+ end
38
+
39
+ def self.language
40
+ config_data[:language] if config_data
41
+ end
42
+
43
+ def self.folder
44
+ config_data[:folder] if config_data
45
+ end
46
+
47
+ def self.config_file
48
+ File.join(ENV['HOME'], CONFIG_FILE)
49
+ end
50
+
51
+ def self.config_data
52
+ YAML::load_file(config_file) if File.exists? config_file
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,57 @@
1
+ module CodewarsCli
2
+ class Deferred
3
+ include GenericHelpers
4
+ REQUEST_TIMES = 10
5
+ attr_reader :kata_name, :language, :response, :client
6
+ def initialize(kata_name, language, response, client)
7
+ @kata_name = kata_name
8
+ @language = language
9
+ @response = response
10
+ @client = client
11
+ _read_deferred do
12
+ info('Your solution has been uploaded waiting for results')
13
+ _handle_deferred_response(_handle_deferred)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def _read_deferred
20
+ if response.success
21
+ yield
22
+ else
23
+ error('There has been an error uploading the kata please try agin later')
24
+ error("Reason: #{response.reason}")
25
+ exit(1)
26
+ end
27
+ end
28
+
29
+ def _handle_deferred_response(result)
30
+ _display_info_for_unsubmitted_result if result.nil? || !result.success
31
+
32
+ if result.valid
33
+ info 'The solution has passed all tests on the server.'
34
+ info 'If you are happy with your solution please type'
35
+ info "codewars finalize #{kata_name} --language=#{language}", :blue
36
+ else
37
+ error 'The solution has not passed tests on the server. Response:'
38
+ error(result.reason)
39
+ exit(1)
40
+ end
41
+ end
42
+
43
+ def _display_info_for_unsubmitted_result
44
+ error("Can't get a result of tests on the server. Try it again.")
45
+ exit(1)
46
+ end
47
+
48
+ def _handle_deferred
49
+ REQUEST_TIMES.times do
50
+ result = client.deferred_response(dmid: response.dmid)
51
+ return result if result.success
52
+ sleep 1
53
+ end
54
+ nil
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,68 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+
4
+ module CodewarsCli
5
+ class FileCreator
6
+ include GenericHelpers
7
+ DESCRIPTION_FILE_NAME = 'description.md'
8
+ def self.create(kata_info, language)
9
+ folder_path = Configuration.folder
10
+ fail Thor::Error, "ERROR: You must config the folder\nSOLUTION: Set up with `config folder FOLDER_LOCATION`" if folder_path.empty?
11
+ new(kata_info, language, folder_path).create_file
12
+ end
13
+
14
+ attr_reader :data, :language, :folder_path
15
+ def initialize(data, language, folder_path)
16
+ @data = extend_object(data)
17
+ @language = language
18
+ @folder_path = folder_path
19
+ end
20
+
21
+ def create_file
22
+ _create_missing_dirs unless File.exists?(_destination_path)
23
+ _fill_template_with_kata_info
24
+ end
25
+
26
+ private
27
+
28
+ def _create_missing_dirs
29
+ FileUtils.mkdir_p(_destination_path)
30
+ end
31
+
32
+ def _fill_template_with_kata_info
33
+ b = _create_binding
34
+ template = File.read(File.expand_path('../templates/description.erb', __FILE__))
35
+ content = ERB.new(template).result(b)
36
+ _create_markdown_file(content)
37
+ end
38
+
39
+ def _create_binding
40
+ b = binding
41
+ (data.attributes.merge({language: language})).each do |k,v|
42
+ b.local_variable_set(k.to_sym, v)
43
+ end
44
+ b
45
+ end
46
+
47
+ def _create_markdown_file(content)
48
+ Dir.chdir(_destination_path) do
49
+ info("Creating Kata descrition file")
50
+ File.open(DESCRIPTION_FILE_NAME,'w') { |f| f.write content }
51
+ info("Creating Kata solution file")
52
+ File.open(_solution_file_name, 'w+')
53
+ end
54
+ end
55
+
56
+ def _solution_file_name
57
+ "solution.#{_language_extension}"
58
+ end
59
+
60
+ def _language_extension
61
+ CodewarsCli::Language::EXTENSIONS[language]
62
+ end
63
+
64
+ def _destination_path
65
+ File.join(ENV['HOME'],folder_path,data.slug,language)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,33 @@
1
+ require 'ostruct'
2
+
3
+ module CodewarsCli
4
+ module FileParserHelpers
5
+ def _parse_description_file(kata_name, language)
6
+ Dir.chdir(_kata_path(kata_name, language)) do
7
+ description_content = File.read(FileCreator::DESCRIPTION_FILE_NAME)
8
+ project_id = _fetch_info(description_content, 'Project ID')
9
+ solution_id = _fetch_info(description_content, 'Solution ID')
10
+ OpenStruct.new(project_id: project_id, solution_id: solution_id)
11
+ end
12
+ end
13
+
14
+ def _fetch_info(content, string)
15
+ regex = %r(#{string}: (.*))
16
+ if match = content.match(regex)
17
+ match[1]
18
+ else
19
+ error("The #{string} is missing from your description.md")
20
+ exit(1)
21
+ end
22
+ end
23
+
24
+ def _kata_path(kata_name, language)
25
+ path = File.join(ENV['HOME'], Configuration.folder, kata_name, language)
26
+ unless File.exist?(path)
27
+ presenter.display_katas_info(kata_name, language)
28
+ exit(1)
29
+ end
30
+ path
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module CodewarsCli
2
+ class Finalize
3
+ include GenericHelpers
4
+ include FileParserHelpers
5
+ def self.find(kata_name, language)
6
+ check_for_api_key
7
+ new(kata_name, language).finalize
8
+ end
9
+
10
+ attr_reader :kata_name, :language
11
+
12
+ def initialize(kata_name, language)
13
+ @kata_name = kata_name
14
+ @language = language || Configuration.language
15
+ end
16
+
17
+ def finalize
18
+ response = client.finalize(kata: _parse_description_file(kata_name, language))
19
+ if response.success
20
+ info('Your Kata has been uploaded and finish')
21
+ else
22
+ error("There has been an error finalizing your kata #{response.reason}")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ require 'codewars_cli/concerns/attributes_methods'
2
+ module CodewarsCli
3
+ module GenericHelpers
4
+ def self.included(base)
5
+ base.extend(self)
6
+ end
7
+
8
+ def check_for_api_key
9
+ fail Thor::Error ,"ERROR: You must config the api_key\nSOLUTION: Set up with `config api_key KEY`" if Configuration.api_key.empty?
10
+ end
11
+
12
+ def client
13
+ @client ||= Client.connection
14
+ end
15
+
16
+ def extend_object(object)
17
+ object.extend(Concerns::AttributesMethods)
18
+ object
19
+ end
20
+
21
+ def info(msg, color=:green)
22
+ presenter.info(msg, color)
23
+ end
24
+
25
+ def error(msg)
26
+ presenter.error(msg)
27
+ end
28
+
29
+ def presenter
30
+ @presenter ||= Presenter.new
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ module CodewarsCli
2
+ class Kata
3
+ include GenericHelpers
4
+ def self.fetch(language)
5
+ check_for_api_key
6
+ if language
7
+ new(language)
8
+ else
9
+ default_language = Configuration.language
10
+ fail Thor::Error, "ERROR: You must config the language for this command\nSOLUTION: Set up with `config language LANGUAGE`" if default_language.empty?
11
+ new(default_language)
12
+ end
13
+ end
14
+
15
+ attr_reader :language
16
+ def initialize(language)
17
+ @language = language
18
+ end
19
+
20
+ def get_kata
21
+ client.next_kata(language: language)
22
+ end
23
+
24
+ def create_file
25
+ FileCreator.create(get_kata, language)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ module CodewarsCli
2
+ module Language
3
+ EXTENSIONS = {
4
+ 'ruby' => 'rb',
5
+ 'javascript' => 'js',
6
+ 'clojure' => 'clj',
7
+ 'coffescript' => 'coffee',
8
+ 'c' => 'cs',
9
+ 'haskell' => 'hs',
10
+ 'java' => 'java',
11
+ 'python' => 'py',
12
+ }
13
+ end
14
+ end
@@ -0,0 +1,81 @@
1
+ module CodewarsCli
2
+ class Presenter < Thor
3
+ include GenericHelpers
4
+ no_commands do
5
+ def display_user_info(object)
6
+ return error(_user_error_message(object)) unless object.status == 200
7
+ info("Displaying information about #{object.username}", :magenta)
8
+ object = extend_object(object)
9
+ attr = object.attributes
10
+ languague_attributes = attr.delete(:languages)
11
+ attr.each do |k,v|
12
+ _print_attributes(k,v)
13
+ end
14
+ print_table(_build_column_info(languague_attributes))
15
+ end
16
+
17
+ def display_katas_info(kata_name, language)
18
+ error("There is no kata with that name '#{kata_name}' and language '#{language}'")
19
+ info('To help here is a list of all your katas order by language', :magenta)
20
+ _katas_info.each do |language, katas|
21
+ _print_attributes(language, katas.join(','))
22
+ end
23
+ end
24
+
25
+ def info(message, color)
26
+ say set_color(message, color)
27
+ end
28
+
29
+ def error(message)
30
+ say set_color(message, :red)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def _katas_info
37
+ Dir.chdir(_katas_folder) do
38
+ Dir.glob('**/*').select do |fn|
39
+ File.directory?(fn) && fn.include?('/')
40
+ end.map{|arr| arr.split('/')}.inject({}) do |hash, arr|
41
+ hash[arr.last.to_sym] = []
42
+ hash[arr.last.to_sym] << arr.first
43
+ hash
44
+ end
45
+ end
46
+ end
47
+
48
+ def _katas_folder
49
+ File.join(ENV['HOME'], Configuration.folder)
50
+ end
51
+
52
+ def _user_error_message(object)
53
+ "ERROR: Fetching Information\nREASON: #{object.reason.upcase}"
54
+ end
55
+
56
+ def _build_column_info(info)
57
+ info.inject([_set_headers]) do |arr, (key,value)|
58
+ arr << [
59
+ set_color(key, :yellow),
60
+ value.values.map{|v| set_color(v, :blue)}
61
+ ].flatten
62
+ arr
63
+ end
64
+ end
65
+
66
+ def _set_headers
67
+ ['languages', 'rank', 'name', 'color', 'score'].map {|h| set_color(h, :green)}
68
+ end
69
+
70
+ def _print_attributes(key, value, indent = false )
71
+ if value.is_a? Hash
72
+ say set_color("#{key}:", :yellow) + "\n"
73
+ value.each { |k,v| _print_attributes(k,v, true) }
74
+ else
75
+ line = set_color("#{key}: ", :green) + set_color("#{value}", :blue) + "\n"
76
+ line = " #{line}" if indent
77
+ say line
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,55 @@
1
+ require 'codewars_cli'
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 CodewarsCli
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
+ def run_cli
31
+ exit_code = begin
32
+ $stderr = @stderr
33
+ $stdin = @stdin
34
+ $stdout = @stdout
35
+
36
+ CodewarsCli::Cli.start(@argv)
37
+
38
+ 0
39
+ rescue StandardError => e
40
+ b = e.backtrace
41
+ @stderr.puts("#{b.shift}: #{e.message} (#{e.class})")
42
+ @stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
43
+ 1
44
+ rescue SystemExit => e
45
+ e.status
46
+ ensure
47
+ $stderr = STDERR
48
+ $stdin = STDIN
49
+ $stdout = STDOUT
50
+ end
51
+
52
+ @kernel.exit(exit_code)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,45 @@
1
+ module CodewarsCli
2
+ class SubmitKata
3
+ include GenericHelpers
4
+ include FileParserHelpers
5
+ def self.find(kata_name, language)
6
+ check_for_api_key
7
+ if kata_name
8
+ new(kata_name, language)
9
+ else
10
+ error("ERROR: You must provide the name of the kata")
11
+ exit(1)
12
+ end
13
+ end
14
+
15
+ attr_reader :kata_name, :language
16
+
17
+ def initialize(kata_name, language)
18
+ @kata_name = kata_name
19
+ @language = language || Configuration.language
20
+ end
21
+
22
+ def upload_kata
23
+ code = _get_kata_solution_code(kata_name, language)
24
+ response = client.attemp_solution(kata: _parse_description_file(kata_name, language), code: code)
25
+ Deferred.new(kata_name, language, response, client)
26
+ end
27
+
28
+ private
29
+
30
+ def _get_kata_solution_code(kata_name, language)
31
+ Dir.chdir(_kata_path(kata_name, language)) do
32
+ File.read(_solution_file)
33
+ end
34
+ end
35
+
36
+ def _solution_file
37
+ "solution.#{_language_extension}"
38
+ end
39
+
40
+ def _language_extension
41
+ CodewarsCli::Language::EXTENSIONS[language]
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,34 @@
1
+ # Meta Information
2
+ Project ID: <%= project_id %>
3
+
4
+ Solution ID: <%= solution_id %>
5
+
6
+ # Kata Description
7
+
8
+ Name: <%= name %>
9
+
10
+ Author: <%= author %>
11
+
12
+ Rank: <%= rank %>
13
+
14
+ Slug: <%= slug %>
15
+
16
+ Tags: <%= tags.join(', ') %>
17
+
18
+ ## Task
19
+
20
+ <%= description %>
21
+
22
+ ## Code
23
+
24
+ ```<%= language %>
25
+ <%= setup %>
26
+ ```
27
+ <% unless example_fixture.empty? %>
28
+ ## Test Example
29
+
30
+ ```<%= language %>
31
+ <%= example_fixture %>
32
+ ```
33
+ <% end %>
34
+
@@ -0,0 +1,22 @@
1
+ module CodewarsCli
2
+ class User
3
+ include GenericHelpers
4
+ def self.fetch(username_or_id)
5
+ check_for_api_key
6
+ new(username_or_id)
7
+ end
8
+
9
+ attr_reader :username_or_id
10
+ def initialize(username_or_id)
11
+ @username_or_id = username_or_id
12
+ end
13
+
14
+ def get_user
15
+ client.user(username_or_id: username_or_id)
16
+ end
17
+
18
+ def print_description
19
+ presenter.display_user_info(get_user)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module CodewarsCli
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: codewars_cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - GustavoCaso
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: codewars_client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
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: aruba
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: pry
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: webmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: "CLI tool to interact with codewars in the comfort of your terminal,\n
126
+ \ allow you to fetch users information, kata, upload solutions
127
+ and close it.\n "
128
+ email:
129
+ - gustavocaso@gmail.com
130
+ executables:
131
+ - codewars
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".gitignore"
136
+ - ".rspec"
137
+ - ".travis.yml"
138
+ - CODE_OF_CONDUCT.md
139
+ - Gemfile
140
+ - LICENSE.txt
141
+ - README.md
142
+ - Rakefile
143
+ - bin/codewars
144
+ - codewars_cli.gemspec
145
+ - lib/codewars_cli.rb
146
+ - lib/codewars_cli/cli.rb
147
+ - lib/codewars_cli/client.rb
148
+ - lib/codewars_cli/concerns/attributes_methods.rb
149
+ - lib/codewars_cli/config.rb
150
+ - lib/codewars_cli/configuration.rb
151
+ - lib/codewars_cli/deferred.rb
152
+ - lib/codewars_cli/file_creator.rb
153
+ - lib/codewars_cli/file_parser_helpers.rb
154
+ - lib/codewars_cli/finalize.rb
155
+ - lib/codewars_cli/generic_helpers.rb
156
+ - lib/codewars_cli/kata.rb
157
+ - lib/codewars_cli/language.rb
158
+ - lib/codewars_cli/presenter.rb
159
+ - lib/codewars_cli/runner.rb
160
+ - lib/codewars_cli/submit_kata.rb
161
+ - lib/codewars_cli/templates/description.erb
162
+ - lib/codewars_cli/user.rb
163
+ - lib/codewars_cli/version.rb
164
+ homepage: https://github.com/GustavoCaso/codewars_cli
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.6
185
+ signing_key:
186
+ specification_version: 4
187
+ summary: CLI tool to interact with codewars in the comfort of your terminal
188
+ test_files: []