at_coder_friends 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +4 -0
- data/.travis.yml +15 -2
- data/Gemfile.lock +15 -15
- data/README.md +60 -8
- data/at_coder_friends.gemspec +4 -4
- data/config/default.yml +88 -0
- data/docs/CONFIGURATION.md +239 -0
- data/lib/at_coder_friends/cli.rb +8 -4
- data/lib/at_coder_friends/config_loader.rb +34 -4
- data/lib/at_coder_friends/cxx_generator.rb +0 -4
- data/lib/at_coder_friends/format_parser.rb +2 -0
- data/lib/at_coder_friends/judge_test_runner.rb +2 -2
- data/lib/at_coder_friends/sample_test_runner.rb +2 -2
- data/lib/at_coder_friends/scraping_agent.rb +72 -10
- data/lib/at_coder_friends/test_runner.rb +45 -27
- data/lib/at_coder_friends/verifier.rb +3 -0
- data/lib/at_coder_friends/version.rb +1 -1
- metadata +16 -14
- data/config/.at_coder_friends.yml.sample +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f97a6bf516dc7443c791b4e2ace991b34eaa47d5
|
4
|
+
data.tar.gz: d48834719bdceceb66cd4f1476c54e7b1c5602af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4ef816ece17840560b7b9bd39ac4ef56ae346fd859a3b1d737dd9a759faecf77a80244fdd56c97a7aa4542f3bdb65e4346f10239c1cd63e7163038cebc95271
|
7
|
+
data.tar.gz: 044e53c76ac9789c2a049a3476141e0d81d103b0d66599bb18e13c0c0b66ec64c65b7fb6062e7ec761d6ba0c536f00d234aa060514eb833e69fc6b922692401e
|
data/.rubocop.yml
CHANGED
@@ -17,6 +17,7 @@ Metrics/BlockLength:
|
|
17
17
|
- 'Rakefile'
|
18
18
|
- '**/*.rake'
|
19
19
|
- 'spec/**/*.rb'
|
20
|
+
- '**/*.gemspec'
|
20
21
|
|
21
22
|
Metrics/MethodLength:
|
22
23
|
Exclude:
|
@@ -25,3 +26,6 @@ Metrics/MethodLength:
|
|
25
26
|
Metrics/ModuleLength:
|
26
27
|
Exclude:
|
27
28
|
- 'spec/**/*.rb'
|
29
|
+
|
30
|
+
Naming/UncommunicativeMethodParamName:
|
31
|
+
MinNameLength: 1
|
data/.travis.yml
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.3.
|
5
|
-
|
4
|
+
- 2.3.8
|
5
|
+
env:
|
6
|
+
global:
|
7
|
+
- CC_TEST_REPORTER_ID=cb942bcc168feb78c43c506364d5344c5ec9a46a0b68dc66acb581e77c981ff1
|
8
|
+
- COVERAGE=true
|
9
|
+
before_install:
|
10
|
+
- gem install bundler -v '2.0.2'
|
11
|
+
before_script:
|
12
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
13
|
+
- chmod +x ./cc-test-reporter
|
14
|
+
- ./cc-test-reporter before-build
|
15
|
+
script:
|
16
|
+
- bundle exec rake spec
|
17
|
+
after_script:
|
18
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile.lock
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
at_coder_friends (0.
|
4
|
+
at_coder_friends (0.4.0)
|
5
5
|
launchy (~> 2.4.3)
|
6
6
|
mechanize (~> 2.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
addressable (2.
|
12
|
-
public_suffix (>= 2.0.2, <
|
11
|
+
addressable (2.7.0)
|
12
|
+
public_suffix (>= 2.0.2, < 5.0)
|
13
13
|
connection_pool (2.2.2)
|
14
14
|
crack (0.4.3)
|
15
15
|
safe_yaml (~> 1.0.0)
|
16
16
|
diff-lcs (1.3)
|
17
|
-
docile (1.3.
|
17
|
+
docile (1.3.2)
|
18
18
|
domain_name (0.5.20190701)
|
19
19
|
unf (>= 0.0.5, < 1.0.0)
|
20
|
-
hashdiff (0.
|
20
|
+
hashdiff (1.0.0)
|
21
21
|
http-cookie (1.0.3)
|
22
22
|
domain_name (~> 0.5)
|
23
|
-
json (2.
|
23
|
+
json (2.2.0)
|
24
24
|
launchy (2.4.3)
|
25
25
|
addressable (~> 2.3)
|
26
26
|
mechanize (2.7.6)
|
@@ -42,8 +42,8 @@ GEM
|
|
42
42
|
nokogiri (1.10.4)
|
43
43
|
mini_portile2 (~> 2.4.0)
|
44
44
|
ntlm-http (0.1.1)
|
45
|
-
public_suffix (
|
46
|
-
rake (
|
45
|
+
public_suffix (4.0.1)
|
46
|
+
rake (12.3.3)
|
47
47
|
rspec (3.8.0)
|
48
48
|
rspec-core (~> 3.8.0)
|
49
49
|
rspec-expectations (~> 3.8.0)
|
@@ -57,8 +57,8 @@ GEM
|
|
57
57
|
diff-lcs (>= 1.2.0, < 2.0)
|
58
58
|
rspec-support (~> 3.8.0)
|
59
59
|
rspec-support (3.8.0)
|
60
|
-
safe_yaml (1.0.
|
61
|
-
simplecov (0.
|
60
|
+
safe_yaml (1.0.5)
|
61
|
+
simplecov (0.17.0)
|
62
62
|
docile (~> 1.1)
|
63
63
|
json (>= 1.8, < 3)
|
64
64
|
simplecov-html (~> 0.10.0)
|
@@ -66,10 +66,10 @@ GEM
|
|
66
66
|
unf (0.1.4)
|
67
67
|
unf_ext
|
68
68
|
unf_ext (0.0.7.6)
|
69
|
-
webmock (3.
|
69
|
+
webmock (3.7.3)
|
70
70
|
addressable (>= 2.3.6)
|
71
71
|
crack (>= 0.3.2)
|
72
|
-
hashdiff
|
72
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
73
73
|
webrobots (0.1.2)
|
74
74
|
|
75
75
|
PLATFORMS
|
@@ -78,11 +78,11 @@ PLATFORMS
|
|
78
78
|
|
79
79
|
DEPENDENCIES
|
80
80
|
at_coder_friends!
|
81
|
-
bundler (~>
|
82
|
-
rake (~>
|
81
|
+
bundler (~> 2.0)
|
82
|
+
rake (~> 12.3)
|
83
83
|
rspec (~> 3.0)
|
84
84
|
simplecov (~> 0.10)
|
85
85
|
webmock (~> 3.0)
|
86
86
|
|
87
87
|
BUNDLED WITH
|
88
|
-
|
88
|
+
2.0.2
|
data/README.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/at_coder_friends.svg)](https://badge.fury.io/rb/at_coder_friends)
|
2
|
+
[![Build Status](https://travis-ci.org/nejiko96/at_coder_friends.svg?branch=master)](https://travis-ci.org/nejiko96/at_coder_friends)
|
3
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/dcd1ce08d11703be2f00/maintainability)](https://codeclimate.com/github/nejiko96/at_coder_friends/maintainability)
|
4
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/dcd1ce08d11703be2f00/test_coverage)](https://codeclimate.com/github/nejiko96/at_coder_friends/test_coverage)
|
5
|
+
|
1
6
|
# AtCoderFriends
|
2
7
|
|
3
8
|
## Description
|
@@ -39,6 +44,8 @@ user: <user>
|
|
39
44
|
password: <password>
|
40
45
|
```
|
41
46
|
|
47
|
+
See [CONFIGURATION.md](docs/CONFIGURATION.md) for details.
|
48
|
+
|
42
49
|
## Usage
|
43
50
|
|
44
51
|
### Setup
|
@@ -49,7 +56,7 @@ at_coder_friends setup /path/to/contest
|
|
49
56
|
|
50
57
|
Creates contest folder, and generates example data and source skeletons into the folder.
|
51
58
|
|
52
|
-
### Open
|
59
|
+
### Open contest page
|
53
60
|
|
54
61
|
```
|
55
62
|
at_coder_friends open-contest /path/to/contest/source_file
|
@@ -75,26 +82,71 @@ at_coder_friends test-all /path/to/contest/source_file
|
|
75
82
|
at_coder_friends submit /path/to/contest/source_file
|
76
83
|
```
|
77
84
|
|
78
|
-
### Naming
|
85
|
+
### Naming convention
|
79
86
|
|
80
|
-
- Contest folder name will be used in the contest site URL.
|
87
|
+
- Contest folder name will be used in the contest site URL.
|
81
88
|
For example, if ```arc001``` folder is specified, AtCoderFriends will use ```https://atcoder.jp/contests/arc001/```.
|
82
|
-
- Source file should be named ```[problem ID].[language specific extension]```(e.g. ```A.rb```),
|
89
|
+
- Source file should be named ```[problem ID].[language specific extension]```(e.g. ```A.rb```),
|
83
90
|
in order to let AtCoderFriends find test cases or fill the submission form.
|
84
|
-
- Suffixes (start with underscore) may be added to the file name (e.g. ```A_v2.rb```),
|
91
|
+
- Suffixes (start with underscore) may be added to the file name (e.g. ```A_v2.rb```),
|
85
92
|
so that you can try multiple codes for one problem.
|
86
93
|
|
87
94
|
### Notes
|
88
95
|
|
89
96
|
- Compilation is not supported.
|
90
|
-
- Source generator
|
97
|
+
- Source generator supports only ruby and C++.
|
91
98
|
|
92
|
-
## For Sublime Text
|
99
|
+
## For Sublime Text user
|
93
100
|
|
94
101
|
It is convenient to use AtCoderFriends from Sublime Text plugin.
|
95
102
|
|
96
103
|
- [sublime_at_coder_friends](https://github.com/nejiko96/sublime_at_coder_friends)
|
97
104
|
|
105
|
+
## For Visual Studio Code user
|
106
|
+
|
107
|
+
- Run **Configure Tasks** from the global Terminal menu.
|
108
|
+
- Select the **Create tasks.json file from template** entry.
|
109
|
+
- Select **Others** from the list.
|
110
|
+
- Add following tasks to ```tasks.json```.
|
111
|
+
|
112
|
+
```JSON
|
113
|
+
{
|
114
|
+
"version": "2.0.0",
|
115
|
+
"tasks": [
|
116
|
+
{
|
117
|
+
"label": "af test-one",
|
118
|
+
"type": "shell",
|
119
|
+
"command": "at_coder_friends",
|
120
|
+
"args": [
|
121
|
+
"test-one",
|
122
|
+
"${file}"
|
123
|
+
],
|
124
|
+
"group": "none",
|
125
|
+
},
|
126
|
+
{
|
127
|
+
"label": "af test-all",
|
128
|
+
"type": "shell",
|
129
|
+
"command": "at_coder_friends",
|
130
|
+
"args": [
|
131
|
+
"test-all",
|
132
|
+
"${file}"
|
133
|
+
],
|
134
|
+
"group": "none"
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"label": "af submit",
|
138
|
+
"type": "shell",
|
139
|
+
"command": "at_coder_friends",
|
140
|
+
"args": [
|
141
|
+
"submit",
|
142
|
+
"${file}"
|
143
|
+
],
|
144
|
+
"group": "none",
|
145
|
+
}
|
146
|
+
]
|
147
|
+
}
|
148
|
+
```
|
149
|
+
|
98
150
|
## Development
|
99
151
|
|
100
152
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -102,7 +154,7 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
102
154
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
103
155
|
|
104
156
|
<!--
|
105
|
-
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
157
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
106
158
|
-->
|
107
159
|
|
108
160
|
## Contributing
|
data/at_coder_friends.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
require 'at_coder_friends/version'
|
6
6
|
|
@@ -30,11 +30,11 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
spec.required_ruby_version = '>= 2.3.0'
|
32
32
|
|
33
|
-
spec.add_dependency 'mechanize', '~> 2.0'
|
34
33
|
spec.add_dependency 'launchy', '~> 2.4.3'
|
34
|
+
spec.add_dependency 'mechanize', '~> 2.0'
|
35
35
|
|
36
|
-
spec.add_development_dependency 'bundler', '~>
|
37
|
-
spec.add_development_dependency 'rake', '~>
|
36
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
37
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
38
38
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
39
39
|
spec.add_development_dependency 'simplecov', '~> 0.10'
|
40
40
|
spec.add_development_dependency 'webmock', '~> 3.0'
|
data/config/default.yml
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
user: ~
|
2
|
+
password: ~
|
3
|
+
ext_settings:
|
4
|
+
'awk':
|
5
|
+
submit_lang: '3506' # Awk (mawk)
|
6
|
+
'bf':
|
7
|
+
submit_lang: '3507' # Brainfuck
|
8
|
+
'c':
|
9
|
+
submit_lang: '3002' # C (GCC)
|
10
|
+
test_cmd:
|
11
|
+
default: '"{dir}/{base}"'
|
12
|
+
windows: '"{dir}/{base}.exe"'
|
13
|
+
'cbl':
|
14
|
+
submit_lang: '3526' # COBOL - Free
|
15
|
+
'clj':
|
16
|
+
submit_lang: '3007' # Clojure
|
17
|
+
'cr':
|
18
|
+
submit_lang: '3511' # Crystal
|
19
|
+
'cs':
|
20
|
+
submit_lang: '3006' # C# (Mono)
|
21
|
+
test_cmd:
|
22
|
+
default: 'mono "{dir}/{base}.exe"'
|
23
|
+
windows: '"{dir}/{base}.exe"'
|
24
|
+
'cxx':
|
25
|
+
submit_lang: '3003' # C++14 (GCC)
|
26
|
+
test_cmd:
|
27
|
+
default: '"{dir}/{base}"'
|
28
|
+
windows: '"{dir}/{base}.exe"'
|
29
|
+
'd':
|
30
|
+
submit_lang: '3009' # D (DMD64)
|
31
|
+
'f90':
|
32
|
+
submit_lang: '3012' # Fortran (gfortran)
|
33
|
+
'fs':
|
34
|
+
submit_lang: '3512' # F# (Mono)
|
35
|
+
'go':
|
36
|
+
submit_lang: '3013' # Go
|
37
|
+
'hs':
|
38
|
+
submit_lang: '3014' # Haskell (GHC)
|
39
|
+
'java':
|
40
|
+
submit_lang: '3016' # Java8 (OpenJDK)
|
41
|
+
test_cmd:
|
42
|
+
default: 'java -cp "{dir}" Main'
|
43
|
+
'jl':
|
44
|
+
submit_lang: '3518' # Julia
|
45
|
+
'js':
|
46
|
+
submit_lang: '3017' # JavaScript (node.js)
|
47
|
+
'kt':
|
48
|
+
submit_lang: '3523' # Kotlin
|
49
|
+
'lisp':
|
50
|
+
submit_lang: '3008' # Common Lisp
|
51
|
+
'lua':
|
52
|
+
submit_lang: '3515' # LuaJIT
|
53
|
+
'm':
|
54
|
+
submit_lang: '3519' # Octave
|
55
|
+
'ml':
|
56
|
+
submit_lang: '3018' # OCaml
|
57
|
+
'nim':
|
58
|
+
submit_lang: '3520' # Nim
|
59
|
+
'pas':
|
60
|
+
submit_lang: '3019' # Pascal (FPC)
|
61
|
+
'php':
|
62
|
+
submit_lang: '3524' # PHP7
|
63
|
+
'pl':
|
64
|
+
submit_lang: '3020' # Perl
|
65
|
+
'py':
|
66
|
+
submit_lang: '3023' # Python3
|
67
|
+
'rb':
|
68
|
+
submit_lang: '3024' # Ruby
|
69
|
+
test_cmd:
|
70
|
+
default: 'ruby "{dir}/{base}.rb"'
|
71
|
+
'rs':
|
72
|
+
submit_lang: '3504' # Rust
|
73
|
+
'scala':
|
74
|
+
submit_lang: '3025' # Scala
|
75
|
+
'scm':
|
76
|
+
submit_lang: '3026' # Scheme (Gauche)
|
77
|
+
'sed':
|
78
|
+
submit_lang: '3505' # Sed (GNU sed)
|
79
|
+
'sh':
|
80
|
+
submit_lang: '3001' # Bash (GNU bash)
|
81
|
+
'swift':
|
82
|
+
submit_lang: '3503' # Swift
|
83
|
+
'ts':
|
84
|
+
submit_lang: '3521' # TypeScript
|
85
|
+
'txt':
|
86
|
+
submit_lang: '3027' # Text (cat)
|
87
|
+
'vb':
|
88
|
+
submit_lang: '3028' # Visual Basic (Mono)
|
@@ -0,0 +1,239 @@
|
|
1
|
+
# Configuration details
|
2
|
+
|
3
|
+
## Configuration file
|
4
|
+
|
5
|
+
AtCoderFriends の動作に関する設定は
|
6
|
+
設定ファイル 「.at_coder_friends.yml」 に記述します。
|
7
|
+
このファイルは作業ディレクトリ(またはその上位ディレクトリ)に配置します。
|
8
|
+
|
9
|
+
## Default settings
|
10
|
+
|
11
|
+
デフォルトは以下のような設定になっています。
|
12
|
+
「.at_coder_friends.yml」が見つかると、その内容がデフォルト設定にマージされるので、
|
13
|
+
新しい設定項目の追加や、既存の設定項目の上書きが可能です。
|
14
|
+
|
15
|
+
```YAML
|
16
|
+
user: ~
|
17
|
+
password: ~
|
18
|
+
ext_settings:
|
19
|
+
'awk':
|
20
|
+
submit_lang: '3506' # Awk (mawk)
|
21
|
+
'bf':
|
22
|
+
submit_lang: '3507' # Brainfuck
|
23
|
+
'c':
|
24
|
+
submit_lang: '3002' # C (GCC)
|
25
|
+
test_cmd:
|
26
|
+
default: '"{dir}/{base}"'
|
27
|
+
windows: '"{dir}/{base}.exe"'
|
28
|
+
'cbl':
|
29
|
+
submit_lang: '3526' # COBOL - Free
|
30
|
+
'clj':
|
31
|
+
submit_lang: '3007' # Clojure
|
32
|
+
'cr':
|
33
|
+
submit_lang: '3511' # Crystal
|
34
|
+
'cs':
|
35
|
+
submit_lang: '3006' # C# (Mono)
|
36
|
+
test_cmd:
|
37
|
+
default: 'mono "{dir}/{base}.exe"'
|
38
|
+
windows: '"{dir}/{base}.exe"'
|
39
|
+
'cxx':
|
40
|
+
submit_lang: '3003' # C++14 (GCC)
|
41
|
+
test_cmd:
|
42
|
+
default: '"{dir}/{base}"'
|
43
|
+
windows: '"{dir}/{base}.exe"'
|
44
|
+
'd':
|
45
|
+
submit_lang: '3009' # D (DMD64)
|
46
|
+
'f90':
|
47
|
+
submit_lang: '3012' # Fortran (gfortran)
|
48
|
+
'fs':
|
49
|
+
submit_lang: '3512' # F# (Mono)
|
50
|
+
'go':
|
51
|
+
submit_lang: '3013' # Go
|
52
|
+
'hs':
|
53
|
+
submit_lang: '3014' # Haskell (GHC)
|
54
|
+
'java':
|
55
|
+
submit_lang: '3016' # Java8 (OpenJDK)
|
56
|
+
test_cmd:
|
57
|
+
default: 'java -cp "{dir}" Main'
|
58
|
+
'jl':
|
59
|
+
submit_lang: '3518' # Julia
|
60
|
+
'js':
|
61
|
+
submit_lang: '3017' # JavaScript (node.js)
|
62
|
+
'kt':
|
63
|
+
submit_lang: '3523' # Kotlin
|
64
|
+
'lisp':
|
65
|
+
submit_lang: '3008' # Common Lisp
|
66
|
+
'lua':
|
67
|
+
submit_lang: '3515' # LuaJIT
|
68
|
+
'm':
|
69
|
+
submit_lang: '3519' # Octave
|
70
|
+
'ml':
|
71
|
+
submit_lang: '3018' # OCaml
|
72
|
+
'nim':
|
73
|
+
submit_lang: '3520' # Nim
|
74
|
+
'pas':
|
75
|
+
submit_lang: '3019' # Pascal (FPC)
|
76
|
+
'php':
|
77
|
+
submit_lang: '3524' # PHP7
|
78
|
+
'pl':
|
79
|
+
submit_lang: '3020' # Perl
|
80
|
+
'py':
|
81
|
+
submit_lang: '3023' # Python3
|
82
|
+
'rb':
|
83
|
+
submit_lang: '3024' # Ruby
|
84
|
+
test_cmd:
|
85
|
+
default: 'ruby "{dir}/{base}.rb"'
|
86
|
+
'rs':
|
87
|
+
submit_lang: '3504' # Rust
|
88
|
+
'scala':
|
89
|
+
submit_lang: '3025' # Scala
|
90
|
+
'scm':
|
91
|
+
submit_lang: '3026' # Scheme (Gauche)
|
92
|
+
'sed':
|
93
|
+
submit_lang: '3505' # Sed (GNU sed)
|
94
|
+
'sh':
|
95
|
+
submit_lang: '3001' # Bash (GNU bash)
|
96
|
+
'swift':
|
97
|
+
submit_lang: '3503' # Swift
|
98
|
+
'ts':
|
99
|
+
submit_lang: '3521' # TypeScript
|
100
|
+
'txt':
|
101
|
+
submit_lang: '3027' # Text (cat)
|
102
|
+
'vb':
|
103
|
+
submit_lang: '3028' # Visual Basic (Mono)
|
104
|
+
```
|
105
|
+
|
106
|
+
## Configuration options
|
107
|
+
|
108
|
+
- user
|
109
|
+
AtCoderのログインユーザーID
|
110
|
+
|
111
|
+
- password
|
112
|
+
AtCoderのログインパスワード
|
113
|
+
|
114
|
+
- ext_settings
|
115
|
+
拡張子ごとの設定
|
116
|
+
|
117
|
+
- _'ext'_
|
118
|
+
対象となる拡張子
|
119
|
+
|
120
|
+
- submit_lang
|
121
|
+
提出言語の言語ID
|
122
|
+
|
123
|
+
- test_cmd
|
124
|
+
テストで使用する実行コマンドの設定
|
125
|
+
未設定の場合はAtCoderの「コードテスト」ページでテストをします
|
126
|
+
|
127
|
+
- default
|
128
|
+
デフォルトの実行コマンド
|
129
|
+
|
130
|
+
- wndows
|
131
|
+
Windows専用実行コマンド(あれば設定)
|
132
|
+
|
133
|
+
- macosx
|
134
|
+
MacOS専用実行コマンド(あれば設定)
|
135
|
+
|
136
|
+
- linux
|
137
|
+
Linux専用実行コマンド(あれば設定)
|
138
|
+
|
139
|
+
### Language ID list (2019/09/16)
|
140
|
+
|
141
|
+
| Language ID | Description |
|
142
|
+
|---|---|
|
143
|
+
|3003|C++14 (GCC 5.4.1)|
|
144
|
+
|3001|Bash (GNU bash v4.3.11)|
|
145
|
+
|3002|C (GCC 5.4.1)|
|
146
|
+
|3004|C (Clang 3.8.0)|
|
147
|
+
|3005|C++14 (Clang 3.8.0)|
|
148
|
+
|3006|C# (Mono 4.6.2.0)|
|
149
|
+
|3007|Clojure (1.8.0)|
|
150
|
+
|3008|Common Lisp (SBCL 1.1.14)|
|
151
|
+
|3009|D (DMD64 v2.070.1)|
|
152
|
+
|3010|D (LDC 0.17.0)|
|
153
|
+
|3011|D (GDC 4.9.4)|
|
154
|
+
|3012|Fortran (gfortran v4.8.4)|
|
155
|
+
|3013|Go (1.6)|
|
156
|
+
|3014|Haskell (GHC 7.10.3)|
|
157
|
+
|3015|Java7 (OpenJDK 1.7.0)|
|
158
|
+
|3016|Java8 (OpenJDK 1.8.0)|
|
159
|
+
|3017|JavaScript (node.js v5.12)|
|
160
|
+
|3018|OCaml (4.02.3)|
|
161
|
+
|3019|Pascal (FPC 2.6.2)|
|
162
|
+
|3020|Perl (v5.18.2)|
|
163
|
+
|3021|PHP (5.6.30)|
|
164
|
+
|3022|Python2 (2.7.6)|
|
165
|
+
|3023|Python3 (3.4.3)|
|
166
|
+
|3024|Ruby (2.3.3)|
|
167
|
+
|3025|Scala (2.11.7)|
|
168
|
+
|3026|Scheme (Gauche 0.9.3.3)|
|
169
|
+
|3027|Text (cat)|
|
170
|
+
|3028|Visual Basic (Mono 4.0.1)|
|
171
|
+
|3029|C++ (GCC 5.4.1)|
|
172
|
+
|3030|C++ (Clang 3.8.0)|
|
173
|
+
|3501|Objective-C (GCC 5.3.0)|
|
174
|
+
|3502|Objective-C (Clang3.8.0)|
|
175
|
+
|3503|Swift (swift-2.2-RELEASE)|
|
176
|
+
|3504|Rust (1.15.1)|
|
177
|
+
|3505|Sed (GNU sed 4.2.2)|
|
178
|
+
|3506|Awk (mawk 1.3.3)|
|
179
|
+
|3507|Brainfuck (bf 20041219)|
|
180
|
+
|3508|Standard ML (MLton 20100608)|
|
181
|
+
|3509|PyPy2 (5.6.0)|
|
182
|
+
|3510|PyPy3 (2.4.0)|
|
183
|
+
|3511|Crystal (0.20.5)|
|
184
|
+
|3512|F# (Mono 4.0)|
|
185
|
+
|3513|Unlambda (0.1.3)|
|
186
|
+
|3514|Lua (5.3.2)|
|
187
|
+
|3515|LuaJIT (2.0.4)|
|
188
|
+
|3516|MoonScript (0.5.0)|
|
189
|
+
|3517|Ceylon (1.2.1)|
|
190
|
+
|3518|Julia (0.5.0)|
|
191
|
+
|3519|Octave (4.0.2)|
|
192
|
+
|3520|Nim (0.13.0)|
|
193
|
+
|3521|TypeScript (2.1.6)|
|
194
|
+
|3522|Perl6 (rakudo-star 2016.01)|
|
195
|
+
|3523|Kotlin (1.0.0)|
|
196
|
+
|3524|PHP7 (7.0.15)|
|
197
|
+
|3525|COBOL - Fixed (OpenCOBOL 1.1.0)|
|
198
|
+
|3526|COBOL - Free (OpenCOBOL 1.1.0)|
|
199
|
+
|
200
|
+
### Variables available in test_cmd
|
201
|
+
|
202
|
+
test_cmd の文字列中の以下のパターンは、
|
203
|
+
テスト対象のソースファイルの情報に置換された後、実行されます。
|
204
|
+
|
205
|
+
|パターン|設定値|
|
206
|
+
|---|---|
|
207
|
+
|{dir}|ソースファイルの置かれているディレクトリ|
|
208
|
+
|{base}|ソースファイルの拡張子を除いたファイル名|
|
209
|
+
|
210
|
+
## Examples of overwriting settings
|
211
|
+
|
212
|
+
- .pyをローカル環境のPythonでテスト
|
213
|
+
```YAML
|
214
|
+
ext_settings:
|
215
|
+
'py':
|
216
|
+
test_cmd:
|
217
|
+
default: 'python "{dir}/{base}.py"'
|
218
|
+
```
|
219
|
+
|
220
|
+
- .rb を「コードテスト」ページでテスト
|
221
|
+
```YAML
|
222
|
+
ext_settings:
|
223
|
+
'rb':
|
224
|
+
test_cmd: ~
|
225
|
+
```
|
226
|
+
|
227
|
+
- .pl6(Perl6)の設定を追加
|
228
|
+
```YAML
|
229
|
+
ext_settings:
|
230
|
+
'pl6':
|
231
|
+
submit_lang: '3522' # Perl6
|
232
|
+
```
|
233
|
+
|
234
|
+
- .cxxの提出言語をC++14(Clang)に変更
|
235
|
+
```YAML
|
236
|
+
ext_settings:
|
237
|
+
'cxx':
|
238
|
+
submit_lang: '3005' # C++14(Clang)
|
239
|
+
```
|
data/lib/at_coder_friends/cli.rb
CHANGED
@@ -25,6 +25,7 @@ module AtCoderFriends
|
|
25
25
|
parse_options!(args)
|
26
26
|
handle_exiting_option
|
27
27
|
raise ParamError, 'command or path is not specified.' if args.size < 2
|
28
|
+
|
28
29
|
@config = ConfigLoader.load_config(args[1])
|
29
30
|
exec_command(*args)
|
30
31
|
STATUS_SUCCESS
|
@@ -55,6 +56,7 @@ module AtCoderFriends
|
|
55
56
|
|
56
57
|
def handle_exiting_option
|
57
58
|
return unless EXITING_OPTIONS.any? { |o| @options.key? o }
|
59
|
+
|
58
60
|
puts AtCoderFriends::VERSION if @options[:version]
|
59
61
|
exit STATUS_SUCCESS
|
60
62
|
end
|
@@ -83,6 +85,7 @@ module AtCoderFriends
|
|
83
85
|
def setup(path)
|
84
86
|
raise AppError, "#{path} is not empty." \
|
85
87
|
if Dir.exist?(path) && !Dir["#{path}/*"].empty?
|
88
|
+
|
86
89
|
agent = ScrapingAgent.new(contest_name(path), @config)
|
87
90
|
parser = FormatParser.new
|
88
91
|
rb_gen = RubyGenerator.new
|
@@ -98,28 +101,29 @@ module AtCoderFriends
|
|
98
101
|
|
99
102
|
def test_one(path, id)
|
100
103
|
id ||= 1
|
101
|
-
SampleTestRunner.new(path).test_one(id)
|
104
|
+
SampleTestRunner.new(path, @config).test_one(id)
|
102
105
|
end
|
103
106
|
|
104
107
|
def test_all(path)
|
105
|
-
SampleTestRunner.new(path).test_all
|
108
|
+
SampleTestRunner.new(path, @config).test_all
|
106
109
|
Verifier.new(path).verify
|
107
110
|
end
|
108
111
|
|
109
112
|
def submit(path)
|
110
113
|
vf = Verifier.new(path)
|
111
114
|
raise AppError, "#{vf.file} has not been tested." unless vf.verified?
|
115
|
+
|
112
116
|
ScrapingAgent.new(contest_name(path), @config).submit(path)
|
113
117
|
vf.unverify
|
114
118
|
end
|
115
119
|
|
116
120
|
def judge_one(path, id)
|
117
121
|
id ||= ''
|
118
|
-
JudgeTestRunner.new(path).judge_one(id)
|
122
|
+
JudgeTestRunner.new(path, @config).judge_one(id)
|
119
123
|
end
|
120
124
|
|
121
125
|
def judge_all(path)
|
122
|
-
JudgeTestRunner.new(path).judge_all
|
126
|
+
JudgeTestRunner.new(path, @config).judge_all
|
123
127
|
end
|
124
128
|
|
125
129
|
def open_contest(path)
|
@@ -7,11 +7,24 @@ module AtCoderFriends
|
|
7
7
|
# loads configuration file from the specified directory.
|
8
8
|
class ConfigLoader
|
9
9
|
DOTFILE = '.at_coder_friends.yml'
|
10
|
+
ACF_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
|
11
|
+
DEFAULT_FILE = File.join(ACF_HOME, 'config', 'default.yml')
|
10
12
|
|
11
13
|
class << self
|
12
14
|
def load_config(target_dir)
|
13
|
-
path =
|
14
|
-
load_yaml(path)
|
15
|
+
path = config_file_for(target_dir)
|
16
|
+
config = load_yaml(path)
|
17
|
+
return config if path == DEFAULT_FILE
|
18
|
+
|
19
|
+
merge_with_default(config)
|
20
|
+
end
|
21
|
+
|
22
|
+
def config_file_for(target_dir)
|
23
|
+
find_project_dotfile(target_dir) || DEFAULT_FILE
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_project_dotfile(target_dir)
|
27
|
+
find_file_upwards(DOTFILE, target_dir)
|
15
28
|
end
|
16
29
|
|
17
30
|
def find_file_upwards(filename, start_dir)
|
@@ -19,8 +32,25 @@ module AtCoderFriends
|
|
19
32
|
file = dir + filename
|
20
33
|
return file.to_s if file.exist?
|
21
34
|
end
|
22
|
-
|
23
|
-
|
35
|
+
end
|
36
|
+
|
37
|
+
def merge_with_default(config)
|
38
|
+
merge(default_config, config)
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_config
|
42
|
+
load_yaml(DEFAULT_FILE)
|
43
|
+
end
|
44
|
+
|
45
|
+
def merge(base_hash, derived_hash)
|
46
|
+
res = base_hash.merge(derived_hash) do |_, base_val, derived_val|
|
47
|
+
if base_val.is_a?(Hash) && derived_val.is_a?(Hash)
|
48
|
+
merge(base_val, derived_val)
|
49
|
+
else
|
50
|
+
derived_val
|
51
|
+
end
|
52
|
+
end
|
53
|
+
res
|
24
54
|
end
|
25
55
|
|
26
56
|
def load_yaml(path)
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module AtCoderFriends
|
4
4
|
# generates C++ source code from definition
|
5
5
|
class CxxGenerator
|
6
|
-
# rubocop:disable Style/FormatStringToken
|
7
6
|
TEMPLATE = <<~TEXT
|
8
7
|
#include <cstdio>
|
9
8
|
|
@@ -31,7 +30,6 @@ module AtCoderFriends
|
|
31
30
|
return 0;
|
32
31
|
}
|
33
32
|
TEXT
|
34
|
-
# rubocop:enable Style/FormatStringToken
|
35
33
|
|
36
34
|
SCANF_FMTS = [
|
37
35
|
'scanf("%<fmt>s", %<addr>s);',
|
@@ -39,9 +37,7 @@ module AtCoderFriends
|
|
39
37
|
'REP(i, %<sz1>s) REP(j, %<sz2>s) scanf("%<fmt>s", %<addr>s);'
|
40
38
|
].freeze
|
41
39
|
|
42
|
-
# rubocop:disable Style/FormatStringToken
|
43
40
|
FMT_FMTS = { number: '%d', string: '%s', char: '%s' }.freeze
|
44
|
-
# rubocop:enable Style/FormatStringToken
|
45
41
|
|
46
42
|
ADDR_FMTS = {
|
47
43
|
single: {
|
@@ -85,6 +85,7 @@ module AtCoderFriends
|
|
85
85
|
defs = parse_fmt(lines)
|
86
86
|
smpx = max_smp(smps)
|
87
87
|
return defs unless smpx
|
88
|
+
|
88
89
|
match_smp!(defs, smpx)
|
89
90
|
end
|
90
91
|
|
@@ -140,6 +141,7 @@ module AtCoderFriends
|
|
140
141
|
inpdefs.each_with_index do |inpdef, i|
|
141
142
|
break if i > lines.size
|
142
143
|
next if inpdef.item != :number
|
144
|
+
|
143
145
|
inpdef.item = :string if lines[i].split[0] =~ /[^\-0-9]/
|
144
146
|
break if %i[varray matrix].include?(inpdef.container)
|
145
147
|
end
|
@@ -5,6 +5,7 @@ require 'mechanize'
|
|
5
5
|
require 'logger'
|
6
6
|
require 'English'
|
7
7
|
require 'launchy'
|
8
|
+
require 'json'
|
8
9
|
|
9
10
|
module AtCoderFriends
|
10
11
|
# scrapes AtCoder contest site and
|
@@ -12,15 +13,8 @@ module AtCoderFriends
|
|
12
13
|
# - submits sources
|
13
14
|
class ScrapingAgent
|
14
15
|
include PathUtil
|
15
|
-
|
16
16
|
BASE_URL = 'https://atcoder.jp/'
|
17
17
|
XPATH_SECTION = '//h3[.="%<title>s"]/following-sibling::section'
|
18
|
-
LANG_TBL = {
|
19
|
-
'cxx' => '3003',
|
20
|
-
'cs' => '3006',
|
21
|
-
'java' => '3016',
|
22
|
-
'rb' => '3024'
|
23
|
-
}.freeze
|
24
18
|
|
25
19
|
attr_reader :contest, :config, :agent
|
26
20
|
|
@@ -74,7 +68,18 @@ module AtCoderFriends
|
|
74
68
|
post_src(q, ext, src)
|
75
69
|
end
|
76
70
|
|
71
|
+
def code_test(path, infile)
|
72
|
+
path, _dir, _prg, _base, ext, _q = split_prg_path(path)
|
73
|
+
src = File.read(path, encoding: Encoding::UTF_8)
|
74
|
+
data = File.read(infile)
|
75
|
+
login
|
76
|
+
code_test_loop(ext, src, data)
|
77
|
+
end
|
78
|
+
|
77
79
|
def login
|
80
|
+
return unless config['user'] && !config['user'].empty?
|
81
|
+
return unless config['password'] && !config['password'].empty?
|
82
|
+
|
78
83
|
page = agent.get(common_url('login'))
|
79
84
|
form = page.forms[1]
|
80
85
|
form.field_with(name: 'username').value = config['user']
|
@@ -132,19 +137,76 @@ module AtCoderFriends
|
|
132
137
|
end
|
133
138
|
|
134
139
|
def post_src(q, ext, src)
|
135
|
-
lang_id = LANG_TBL[ext.downcase]
|
136
|
-
raise AppError, ".#{ext} is not available." unless lang_id
|
137
140
|
page = agent.get(contest_url('submit'))
|
138
141
|
form = page.forms[1]
|
139
142
|
form.field_with(name: 'data.TaskScreenName') do |sel|
|
140
143
|
option = sel.options.find { |op| op.text.start_with?(q) }
|
141
144
|
option&.select || (raise AppError, "unknown problem:#{q}.")
|
142
145
|
end
|
143
|
-
form.add_field!('data.LanguageId', lang_id)
|
146
|
+
form.add_field!('data.LanguageId', lang_id(ext))
|
144
147
|
form.field_with(name: 'sourceCode').value = src
|
145
148
|
form.submit
|
146
149
|
end
|
147
150
|
|
151
|
+
def code_test_loop(ext, src, data)
|
152
|
+
page = agent.get(contest_url('custom_test'))
|
153
|
+
script = page.search('script').text
|
154
|
+
csrf_token = script.scan(/var csrfToken = "(.*)"/)[0][0]
|
155
|
+
payload = {
|
156
|
+
'data.LanguageId' => lang_id(ext),
|
157
|
+
'sourceCode' => src,
|
158
|
+
'input' => data,
|
159
|
+
'csrf_token' => csrf_token
|
160
|
+
}
|
161
|
+
|
162
|
+
page = agent.post(contest_url('custom_test/submit/json'), payload)
|
163
|
+
msg = page.body
|
164
|
+
raise AppError, msg unless msg.empty?
|
165
|
+
|
166
|
+
100.times do
|
167
|
+
page = agent.get(contest_url('custom_test/json?reload=true'))
|
168
|
+
data = JSON.parse(page.body)
|
169
|
+
return nil unless data.is_a?(Hash) && data['Result']
|
170
|
+
return data if data.dig('Result', 'Status') == 3
|
171
|
+
return data unless data['Interval']
|
172
|
+
|
173
|
+
sleep 1.0 * data['Interval'] / 1000
|
174
|
+
end
|
175
|
+
|
176
|
+
nil
|
177
|
+
end
|
178
|
+
|
179
|
+
def lang_list
|
180
|
+
@lang_list ||= begin
|
181
|
+
page = agent.get(contest_url('custom_test'))
|
182
|
+
form = page.forms[1]
|
183
|
+
sel = form.field_with(name: 'data.LanguageId')
|
184
|
+
sel && sel
|
185
|
+
.options
|
186
|
+
.reject { |opt| opt.value.empty? }
|
187
|
+
.map do |opt|
|
188
|
+
{ v: opt.value, t: opt.text }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def lang_list_txt
|
194
|
+
lang_list
|
195
|
+
&.map { |opt| "#{opt[:v]} - #{opt[:t]}" }
|
196
|
+
&.join("\n")
|
197
|
+
end
|
198
|
+
|
199
|
+
def lang_id(ext)
|
200
|
+
config.dig('ext_settings', ext, 'submit_lang') || (
|
201
|
+
msg = <<~MSG
|
202
|
+
submit_lang for .#{ext} is not specified.
|
203
|
+
Available languages:
|
204
|
+
#{lang_list_txt || '(failed to fetch)'}
|
205
|
+
MSG
|
206
|
+
raise AppError, msg
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
148
210
|
def open_contest
|
149
211
|
Launchy.open(contest_url(''))
|
150
212
|
end
|
@@ -7,26 +7,29 @@ module AtCoderFriends
|
|
7
7
|
class TestRunner
|
8
8
|
include PathUtil
|
9
9
|
|
10
|
-
def initialize(path)
|
10
|
+
def initialize(path, config)
|
11
|
+
@contest = contest_name(path)
|
11
12
|
@path, @dir, @prg, @base, @ext, @q = split_prg_path(path)
|
13
|
+
@config = config
|
12
14
|
end
|
13
15
|
|
14
16
|
# rubocop:disable Metrics/MethodLength
|
15
17
|
def run_test(id, infile, outfile, expfile)
|
16
18
|
return false unless File.exist?(infile) && File.exist?(expfile)
|
17
19
|
|
18
|
-
puts "==== #{id} ===="
|
19
|
-
ec = system("#{edit_cmd} < #{infile} > #{outfile}")
|
20
|
+
puts "==== #{id} (#{test_loc}) ===="
|
20
21
|
|
22
|
+
success = send(test_mtd, infile, outfile)
|
21
23
|
input, result, expected =
|
22
24
|
[infile, outfile, expfile].map { |file| File.read(file) }
|
25
|
+
|
23
26
|
puts '-- input --'
|
24
27
|
print input
|
25
28
|
puts '-- expected --'
|
26
29
|
print expected
|
27
30
|
puts '-- result --'
|
28
31
|
print result
|
29
|
-
if !
|
32
|
+
if !success
|
30
33
|
puts '!!!!! RE !!!!!'
|
31
34
|
elsif result != expected
|
32
35
|
puts '!!!!! WA !!!!!'
|
@@ -37,33 +40,48 @@ module AtCoderFriends
|
|
37
40
|
end
|
38
41
|
# rubocop:enable Metrics/MethodLength
|
39
42
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
43
|
+
def test_loc
|
44
|
+
test_cmd ? 'local' : 'remote'
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_mtd
|
48
|
+
test_cmd ? :local_test : :remote_test
|
49
|
+
end
|
50
|
+
|
51
|
+
def local_test(infile, outfile)
|
52
|
+
system("#{test_cmd} < #{infile} > #{outfile}")
|
53
|
+
end
|
54
|
+
|
55
|
+
def remote_test(infile, outfile)
|
56
|
+
agent = ScrapingAgent.new(@contest, @config)
|
57
|
+
res = agent.code_test(@path, infile)
|
58
|
+
unless res && res['Result']
|
59
|
+
File.write(outfile, 'Remote test failed.')
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
puts "Exit code: #{res.dig('Result', 'ExitCode')}"
|
63
|
+
puts "Time: #{res.dig('Result', 'TimeConsumption')}ms"
|
64
|
+
puts "Memory: #{res.dig('Result', 'MemoryConsumption')}KB"
|
65
|
+
if res.dig('Result', 'ExitCode') != 0
|
66
|
+
File.write(outfile, res['Stderr'])
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
File.write(outfile, res['Stdout'])
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_cmd
|
74
|
+
@test_cmd ||= begin
|
75
|
+
cmds = @config.dig('ext_settings', @ext, 'test_cmd')
|
76
|
+
cmd = cmds && (cmds[which_os.to_s] || cmds['default'])
|
77
|
+
return nil unless cmd
|
78
|
+
|
79
|
+
cmd.gsub('{dir}', @dir).gsub('{base}', @base)
|
61
80
|
end
|
62
81
|
end
|
63
|
-
# rubocop:enable Metrics/MethodLength
|
64
82
|
|
65
83
|
def which_os
|
66
|
-
@
|
84
|
+
@which_os ||= begin
|
67
85
|
case RbConfig::CONFIG['host_os']
|
68
86
|
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
69
87
|
:windows
|
@@ -15,18 +15,21 @@ module AtCoderFriends
|
|
15
15
|
|
16
16
|
def verify
|
17
17
|
return unless File.exist?(path)
|
18
|
+
|
18
19
|
FileUtils.makedirs(vdir) unless Dir.exist?(vdir)
|
19
20
|
FileUtils.touch(vpath)
|
20
21
|
end
|
21
22
|
|
22
23
|
def unverify
|
23
24
|
return unless File.exist?(vpath)
|
25
|
+
|
24
26
|
File.delete(vpath)
|
25
27
|
end
|
26
28
|
|
27
29
|
def verified?
|
28
30
|
return false unless File.exist?(vpath)
|
29
31
|
return false if File.mtime(vpath) < File.mtime(path)
|
32
|
+
|
30
33
|
true
|
31
34
|
end
|
32
35
|
end
|
metadata
CHANGED
@@ -1,71 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: at_coder_friends
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nejiko96
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: launchy
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.4.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.4.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: mechanize
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: '2.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '12.3'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '12.3'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,7 +135,8 @@ files:
|
|
135
135
|
- at_coder_friends.gemspec
|
136
136
|
- bin/console
|
137
137
|
- bin/setup
|
138
|
-
- config
|
138
|
+
- config/default.yml
|
139
|
+
- docs/CONFIGURATION.md
|
139
140
|
- exe/at_coder_friends
|
140
141
|
- lib/at_coder_friends.rb
|
141
142
|
- lib/at_coder_friends/cli.rb
|
@@ -172,7 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
173
|
- !ruby/object:Gem::Version
|
173
174
|
version: '0'
|
174
175
|
requirements: []
|
175
|
-
|
176
|
+
rubyforge_project:
|
177
|
+
rubygems_version: 2.5.2.3
|
176
178
|
signing_key:
|
177
179
|
specification_version: 4
|
178
180
|
summary: AtCoder support tool
|