at_coder_friends 0.3.3 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 5c01f28420d768fccb30960702213d768caeaefd54cb9686cb0bafb3591ba44d
4
- data.tar.gz: 35acd1fb67232149a831394b4afa34f5eb1ade9e2ea3658d03d0ec191566975b
2
+ SHA1:
3
+ metadata.gz: f97a6bf516dc7443c791b4e2ace991b34eaa47d5
4
+ data.tar.gz: d48834719bdceceb66cd4f1476c54e7b1c5602af
5
5
  SHA512:
6
- metadata.gz: 6015841608385002fea3d1ff31f738f92719ce7fca2d9331e68c44aef8605ba31047194a6e4a53229062110dd2cd55067932baa0c1e44e2628041e5bc72468e4
7
- data.tar.gz: 8a96a65f43b823666914b86eeba623bf0ae15074406c1ad432d55163c9e8b5d88625e7d08046a1db5d8b0698738bb0fcb5c9b7060a9b5a7232202242f2774ea1
6
+ metadata.gz: b4ef816ece17840560b7b9bd39ac4ef56ae346fd859a3b1d737dd9a759faecf77a80244fdd56c97a7aa4542f3bdb65e4346f10239c1cd63e7163038cebc95271
7
+ data.tar.gz: 044e53c76ac9789c2a049a3476141e0d81d103b0d66599bb18e13c0c0b66ec64c65b7fb6062e7ec761d6ba0c536f00d234aa060514eb833e69fc6b922692401e
@@ -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
@@ -1,5 +1,18 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.16.1
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
@@ -1,26 +1,26 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- at_coder_friends (0.3.3)
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.6.0)
12
- public_suffix (>= 2.0.2, < 4.0)
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.1)
17
+ docile (1.3.2)
18
18
  domain_name (0.5.20190701)
19
19
  unf (>= 0.0.5, < 1.0.0)
20
- hashdiff (0.3.8)
20
+ hashdiff (1.0.0)
21
21
  http-cookie (1.0.3)
22
22
  domain_name (~> 0.5)
23
- json (2.1.0)
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 (3.0.3)
46
- rake (10.5.0)
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.4)
61
- simplecov (0.16.1)
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.5.1)
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 (~> 1.16)
82
- rake (~> 10.0)
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
- 1.17.3
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 Contest Page
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 Convention
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 and test runner supports only ruby and C++.
97
+ - Source generator supports only ruby and C++.
91
98
 
92
- ## For Sublime Text User
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('../lib', __FILE__)
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', '~> 1.16'
37
- spec.add_development_dependency 'rake', '~> 10.0'
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'
@@ -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
+ ```
@@ -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 = find_file_upwards(DOTFILE, target_dir)
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
- raise ConfigNotFoundError,
23
- "Configuration file not found: #{start_dir}"
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,8 +5,8 @@ module AtCoderFriends
5
5
  class JudgeTestRunner < TestRunner
6
6
  include PathUtil
7
7
 
8
- def initialize(path)
9
- super(path)
8
+ def initialize(path, config)
9
+ super(path, config)
10
10
  @cases_dir = cases_dir(@dir)
11
11
  @smp_dir = smp_dir(@dir)
12
12
  end
@@ -5,8 +5,8 @@ module AtCoderFriends
5
5
  class SampleTestRunner < TestRunner
6
6
  include PathUtil
7
7
 
8
- def initialize(path)
9
- super(path)
8
+ def initialize(path, config)
9
+ super(path, config)
10
10
  @smp_dir = smp_dir(@dir)
11
11
  end
12
12
 
@@ -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 !ec
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
- # rubocop:disable Metrics/MethodLength
41
- def edit_cmd
42
- case @ext
43
- when 'java'
44
- "java -cp #{@dir} Main"
45
- when 'rb'
46
- "ruby #{@dir}/#{@base}.rb"
47
- when 'cs'
48
- case which_os
49
- when :windows
50
- "#{@dir}/#{@base}.exe"
51
- else
52
- "mono #{@dir}/#{@base}.exe"
53
- end
54
- else # c, cxx
55
- case which_os
56
- when :windows
57
- "#{@dir}/#{@base}.exe"
58
- else
59
- "#{@dir}/#{@base}"
60
- end
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
- @os ||= begin
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AtCoderFriends
4
- VERSION = '0.3.3'
4
+ VERSION = '0.4.0'
5
5
  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.3.3
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-01 00:00:00.000000000 Z
11
+ date: 2019-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: mechanize
14
+ name: launchy
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
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: '2.0'
26
+ version: 2.4.3
27
27
  - !ruby/object:Gem::Dependency
28
- name: launchy
28
+ name: mechanize
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.4.3
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.4.3
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: '1.16'
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: '1.16'
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: '10.0'
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: '10.0'
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/.at_coder_friends.yml.sample
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
- rubygems_version: 3.0.6
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
@@ -1,2 +0,0 @@
1
- user: <user>
2
- password: <password>