green_day 0.9.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53785392f34ac5d93be96ca0132fef875d4b733a389e2f7d6e1a82bd1880b15a
4
- data.tar.gz: 1bf1044369856380a00ac3c9009d86282011b94c3e05fe6f59d529093c5733f7
3
+ metadata.gz: 7a382b709216ac2a7d03cbfd4ffe96a8922d3057306129182c47598202e89db5
4
+ data.tar.gz: 16a3e1f16df20721da2c285c066f5d3546beb83e01158bc5c60f91bd06532cfb
5
5
  SHA512:
6
- metadata.gz: 7d03782bc7b38addeb0c458b58b0ef863ab0f5f8f3e1af0e835522e51a3908fd19dbd4433d1e8c6e37d4a58a99f77a8e3b33866816d7d9d0e059ec2a95f060f6
7
- data.tar.gz: 746dba21f2edf01245e1e33f7717bd9f513feaa2ed92629f9ebb58c1106752baab462eafc45916e769bf25a0f46c4030aa755b7ba69b653e2bf52188f5427081
6
+ metadata.gz: 2f2c9365890badf1c788e73a1e8eb38e25bf15188cbfbd4adcab43fd701fcb5e706d64a10057ed14d070ea45da944be9ec6d5f980cb8fe8fab1e9b53dbc6c9ee
7
+ data.tar.gz: 80c5a108f8909d61f2f8d35718d6f2020da1dd5c233f1c17195680cb41a17895397e454dcc9c8e349a34d39168c2b3aa278c39fdccef84756bec20003215b5c4
data/README.md CHANGED
@@ -21,17 +21,17 @@ Or install it yourself as:
21
21
  login(this command stores your cookie as `.cookie-store` in current directory)
22
22
 
23
23
  $ bundle exec green_day login
24
-
24
+
25
25
  If you want to delete session, remove `.cookie-store`
26
-
26
+
27
27
  This command creates directory and spec.
28
-
28
+
29
29
  $ bundle exec green_day new <contest-name>
30
30
 
31
- For example
32
-
31
+ For example
32
+
33
33
  $ bundle exec green_day new abc150
34
-
34
+
35
35
  ```
36
36
  abc150
37
37
  ├── A.rb
@@ -48,69 +48,44 @@ For example
48
48
  ├── E_spec.rb
49
49
  └── F_spec.rb
50
50
  ```
51
-
52
- Example of output spec
51
+
52
+ ### Example of output spec
53
53
 
54
54
  ```ruby
55
55
  RSpec.describe 'abc150/A.rb' do
56
56
  it 'test with "2 900\n"' do
57
- if ENV['GD_REPL']
58
- File.chmod(0o755, 'abc150/A.rb')
59
- system(%q(expect -c 'set timeout 2; spawn ruby abc150/A.rb; send "2 900\n\\004"; interact'))
60
- else
61
- io = IO.popen('ruby abc150/A.rb', 'w+')
62
- io.puts("2 900\n")
63
- io.close_write
64
- expect(io.readlines.join).to eq("Yes\n")
65
- end
57
+ io = IO.popen('ruby abc150/A.rb', 'w+')
58
+ io.puts("2 900\n")
59
+ io.close_write
60
+ expect(io.readlines.join).to eq("Yes\n")
66
61
  end
67
62
 
68
63
  it 'test with "1 501\n"' do
69
- if ENV['GD_REPL']
70
- File.chmod(0o755, 'abc150/A.rb')
71
- system(%q(expect -c 'set timeout 2; spawn ruby abc150/A.rb; send "1 501\n\\004"; interact'))
72
- else
73
- io = IO.popen('ruby abc150/A.rb', 'w+')
74
- io.puts("1 501\n")
75
- io.close_write
76
- expect(io.readlines.join).to eq("No\n")
77
- end
64
+ io = IO.popen('ruby abc150/A.rb', 'w+')
65
+ io.puts("1 501\n")
66
+ io.close_write
67
+ expect(io.readlines.join).to eq("No\n")
78
68
  end
79
69
 
80
70
  it 'test with "4 2000\n"' do
81
- if ENV['GD_REPL']
82
- File.chmod(0o755, 'abc150/A.rb')
83
- system(%q(expect -c 'set timeout 2; spawn ruby abc150/A.rb; send "4 2000\n\\004"; interact'))
84
- else
85
- io = IO.popen('ruby abc150/A.rb', 'w+')
86
- io.puts("4 2000\n")
87
- io.close_write
88
- expect(io.readlines.join).to eq("Yes\n")
89
- end
71
+ io = IO.popen('ruby abc150/A.rb', 'w+')
72
+ io.puts("4 2000\n")
73
+ io.close_write
74
+ expect(io.readlines.join).to eq("Yes\n")
90
75
  end
91
76
 
92
77
  end
93
-
94
78
  ```
95
- ## Debugging with REPL
96
- You can debug your code with sample input and REPL by setting `GD_REPL` environment variable.
97
79
 
98
- ```
99
- $ GD_REPL=1 bundle exec rspec abc150/spec/A_spec.rb
100
-
101
- abc150/A.rb
102
- spawn ruby abc150/A.rb
103
- 2 900
104
-
105
- From: abc150/A.rb @ line 2 :
80
+ ### template
81
+ You can use template file for creating spec.
82
+ GreenDay uses `template.rb` in the working directory as a template file.
106
83
 
107
- 1: a, b = gets.split.map(&:to_i)
108
- => 2: binding.irb
109
- 3: puts "Yes"
110
-
111
- irb(main):001:0> a
112
- => 2
84
+ ```ruby
85
+ requires "math"
86
+ x = gets.to_i
113
87
  ```
88
+
114
89
  ## Development
115
90
 
116
91
  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.
@@ -29,6 +29,12 @@ module GreenDay
29
29
 
30
30
  def get_parsed_body(path)
31
31
  res = conn.get(path)
32
+ if res.status == 429
33
+ puts "429 error with #{path} retrying..."
34
+ sleep 1
35
+ return get_parsed_body(path)
36
+ end
37
+
32
38
  Nokogiri::HTML.parse(res.body)
33
39
  end
34
40
 
data/lib/green_day/cli.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
- require 'parallel'
5
4
  require 'colorize'
6
5
  require 'io/console'
7
6
  require_relative 'atcoder_client'
8
7
  require_relative 'contest'
9
- require_relative 'test_builder'
8
+ require_relative 'task_source_to_file_worker'
10
9
 
11
10
  module GreenDay
12
11
  class Cli < Thor
@@ -29,33 +28,8 @@ module GreenDay
29
28
  contest = Contest.new(contest_name)
30
29
  FileUtils.makedirs("#{contest.name}/spec")
31
30
 
32
- contest.tasks.map do |task|
33
- create_files_in_thread(task)
34
- end.each(&:join)
35
-
31
+ TaskSourceToFileWorker.run_threads(contest.task_sources).each(&:join)
36
32
  puts "Successfully created #{contest.name} directory".colorize(:green)
37
33
  end
38
-
39
- private
40
-
41
- def create_files_in_thread(task)
42
- Thread.new do
43
- create_task_file(task)
44
- create_task_spec_file(task)
45
- end
46
- end
47
-
48
- def create_task_file(task)
49
- FileUtils.touch(task_file_name(task))
50
- end
51
-
52
- def create_task_spec_file(task)
53
- test_content = TestBuilder.build_test(task_file_name(task), task.sample_answers)
54
- File.write("#{task.contest.name}/spec/#{task.name}_spec.rb", test_content)
55
- end
56
-
57
- def task_file_name(task)
58
- "#{task.contest.name}/#{task.name}.rb"
59
- end
60
34
  end
61
35
  end
@@ -4,21 +4,15 @@ require_relative 'task'
4
4
 
5
5
  module GreenDay
6
6
  class Contest
7
- attr_reader :name, :tasks
7
+ TaskSource = Struct.new(:name, :path, :contest_name)
8
+ attr_reader :name, :task_sources
8
9
 
9
10
  def initialize(contest_name)
10
11
  @name = contest_name
11
12
 
12
- @tasks = fetch_task_names_and_paths.map.with_index do |(task_name, task_path), i|
13
- if !i.zero? && (i % 10).zero? && !ENV['CI']
14
- puts 'Sleeping 2 second to avoid 429 error'
15
- sleep 2
16
- end
17
-
18
- Thread.new do
19
- Task.new(self, task_name, task_path)
20
- end
21
- end.map(&:value)
13
+ @task_sources = fetch_task_names_and_paths.map do |name, path|
14
+ TaskSource.new(name, path, @name)
15
+ end
22
16
  end
23
17
 
24
18
  private
@@ -2,21 +2,43 @@
2
2
 
3
3
  module GreenDay
4
4
  class Task
5
- attr_reader :contest, :name, :path, :sample_answers
5
+ SampleAnswer = Struct.new(:input, :output)
6
+ attr_reader :name, :path, :contest_name
6
7
 
7
- def initialize(contest, name, path)
8
- @contest = contest
8
+ def initialize(name, path, contest_name)
9
9
  @name = name
10
10
  @path = path
11
- @sample_answers = create_sample_answers_hash
11
+ @contest_name = contest_name
12
+ end
13
+
14
+ def create_file
15
+ template = if File.exist?(GreenDay::TEMPLATE_FILE_PATH)
16
+ File.read(GreenDay::TEMPLATE_FILE_PATH)
17
+ end
18
+
19
+ File.write(file_name, template)
20
+ end
21
+
22
+ def file_name
23
+ "#{contest_name}/#{name}.rb"
24
+ end
25
+
26
+ def create_spec_file
27
+ test_content = TestBuilder.build_test(
28
+ file_name,
29
+ sample_answers
30
+ )
31
+ File.write("#{contest_name}/spec/#{name}_spec.rb", test_content)
12
32
  end
13
33
 
14
34
  private
15
35
 
16
- def create_sample_answers_hash
36
+ def sample_answers
17
37
  input_samples, output_samples = fetch_inputs_and_outputs
18
38
 
19
- input_samples.zip(output_samples).to_h
39
+ input_samples.zip(output_samples).map do |input, output|
40
+ SampleAnswer.new(input, output)
41
+ end
20
42
  end
21
43
 
22
44
  def fetch_inputs_and_outputs
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'test_builder'
4
+
5
+ module GreenDay
6
+ class TaskSourceToFileWorker
7
+ def self.run_threads(task_sources)
8
+ new(task_sources).run_threads
9
+ end
10
+
11
+ def initialize(task_sources)
12
+ @task_sources = task_sources
13
+ end
14
+
15
+ def run_threads
16
+ @task_sources.map.with_index do |task_source, i|
17
+ # avoid 429 error
18
+ sleep 1 if (i % 7).zero? && !i.zero?
19
+
20
+ Thread.new do
21
+ task = Task.new(task_source.name,
22
+ task_source.path,
23
+ task_source.contest_name)
24
+ task.create_file
25
+ task.create_spec_file
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -4,31 +4,24 @@ module GreenDay
4
4
  module TestBuilder
5
5
  module_function
6
6
 
7
- def build_test(submit_file_path, input_output_hash)
7
+ def build_test(submit_file_path, sample_answers)
8
8
  <<~SPEC
9
9
  RSpec.describe '#{submit_file_path}' do
10
- #{input_output_hash.map { |input, output| build_example(submit_file_path, input, output) }.join("\n")}
10
+ #{sample_answers.map { |sample_answer| build_example(submit_file_path, sample_answer.input, sample_answer.output) }.join("\n")}
11
11
  end
12
12
  SPEC
13
13
  end
14
14
 
15
- # rubocop:disable Metrics/AbcSize
16
15
  def build_example(submit_file_path, input, output)
17
16
  <<~SPEC
18
17
  #{tab}it 'test with #{unify_cr_lf(input).chomp}' do
19
- #{tab}#{tab}if ENV['GD_REPL']
20
- #{tab}#{tab}#{tab}File.chmod(0o755, '#{submit_file_path}')
21
- #{tab}#{tab}#{tab}system(%q(expect -c 'set timeout 2; spawn ruby #{submit_file_path}; send #{unify_cr_lf("#{input}\\004")}; interact'))
22
- #{tab}#{tab}else
23
- #{tab}#{tab}#{tab}io = IO.popen('ruby #{submit_file_path}', 'w+')
24
- #{tab}#{tab}#{tab}io.puts(#{unify_cr_lf(input)})
25
- #{tab}#{tab}#{tab}io.close_write
26
- #{tab}#{tab}#{tab}expect(io.readlines.join).to eq(#{unify_cr_lf(output)})
27
- #{tab}#{tab}end
18
+ #{tab}#{tab}io = IO.popen('ruby #{submit_file_path}', 'w+')
19
+ #{tab}#{tab}io.puts(#{unify_cr_lf(input)})
20
+ #{tab}#{tab}io.close_write
21
+ #{tab}#{tab}expect(io.readlines.join).to eq(#{unify_cr_lf(output)})
28
22
  #{tab}end
29
23
  SPEC
30
24
  end
31
- # rubocop:enable Metrics/AbcSize
32
25
 
33
26
  def unify_cr_lf(string)
34
27
  return unless string # たまに画像で例を出してくるとsampleの文字がなくなる
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GreenDay
4
- VERSION = '0.9.0'
4
+ VERSION = '1.1.0'
5
5
  end
data/lib/green_day.rb CHANGED
@@ -5,4 +5,5 @@ require_relative 'green_day/cli'
5
5
 
6
6
  module GreenDay
7
7
  class Error < StandardError; end
8
+ TEMPLATE_FILE_PATH = File.expand_path('green_day/template.rb', __dir__)
8
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: green_day
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - qwyng
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-26 00:00:00.000000000 Z
11
+ date: 2024-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -107,6 +107,7 @@ files:
107
107
  - lib/green_day/cli.rb
108
108
  - lib/green_day/contest.rb
109
109
  - lib/green_day/task.rb
110
+ - lib/green_day/task_source_to_file_worker.rb
110
111
  - lib/green_day/test_builder.rb
111
112
  - lib/green_day/version.rb
112
113
  homepage: https://github.com/QWYNG/green_day
@@ -116,7 +117,7 @@ metadata:
116
117
  homepage_uri: https://github.com/QWYNG/green_day
117
118
  source_code_uri: https://github.com/QWYNG/green_day
118
119
  rubygems_mfa_required: 'true'
119
- post_install_message:
120
+ post_install_message:
120
121
  rdoc_options: []
121
122
  require_paths:
122
123
  - lib
@@ -132,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
133
  version: '0'
133
134
  requirements: []
134
135
  rubygems_version: 3.4.10
135
- signing_key:
136
+ signing_key:
136
137
  specification_version: 4
137
138
  summary: CLI tool for AtCoder and Ruby
138
139
  test_files: []