aoc_generator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +20 -0
- data/.tool-versions +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +107 -0
- data/README.md +39 -0
- data/Rakefile +12 -0
- data/bin/console +9 -0
- data/bin/setup +6 -0
- data/exe/aoc +7 -0
- data/lib/advent_of_code_generator/cli.rb +48 -0
- data/lib/advent_of_code_generator/generator.rb +110 -0
- data/lib/advent_of_code_generator/scraper.rb +40 -0
- data/lib/advent_of_code_generator.rb +7 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7c7406ac54325c97120e78a4eb03b1b6cf1ffaa17729bbee090459eb1c41ea69
|
4
|
+
data.tar.gz: ddb0ddd4e9b6756fbc085b33497e937d1f5cbb6a0c8322c466cb58dfba9c97fb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7be5d7348c737ed8c29a4f9ce2607b36c750341694d67022a558a38b252a27d41e0d69ba8aa2536a7004c0c19a1078de66c19e46b95c19ce26f86a0fc5094f5
|
7
|
+
data.tar.gz: 53ac78a563c392c9833d2b5dfc38da6e9bfadd3d508aa730c596353ab8f0d1447f9374f4bb0555b96ffd72276edc2c8df09ce5162fd888c8d12a74a181af7fc2
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rake
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
DisplayCopNames: true
|
7
|
+
NewCops: enable
|
8
|
+
TargetRubyVersion: 3.3
|
9
|
+
|
10
|
+
Metrics/MethodLength:
|
11
|
+
CountAsOne: heredoc
|
12
|
+
|
13
|
+
Style/StringLiterals:
|
14
|
+
EnforcedStyle: double_quotes
|
15
|
+
|
16
|
+
Style/StringLiteralsInInterpolation:
|
17
|
+
EnforcedStyle: double_quotes
|
18
|
+
|
19
|
+
RSpec/ExampleLength:
|
20
|
+
Enabled: false
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.3.4
|
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gemspec
|
6
|
+
|
7
|
+
ruby file: ".tool-versions"
|
8
|
+
|
9
|
+
gem "debug", "~> 1.9"
|
10
|
+
gem "nokogiri", "~> 1.16"
|
11
|
+
gem "rake", "~> 13.2"
|
12
|
+
gem "rspec", "~> 3.13"
|
13
|
+
gem "rubocop", "~> 1.68"
|
14
|
+
gem "rubocop-rake", "~> 0.6.0"
|
15
|
+
gem "rubocop-rspec", "~> 3.2"
|
16
|
+
gem "thor", "~> 1.3"
|
17
|
+
gem "webmock", "~> 3.24"
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
aoc_generator (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
addressable (2.8.7)
|
10
|
+
public_suffix (>= 2.0.2, < 7.0)
|
11
|
+
ast (2.4.2)
|
12
|
+
bigdecimal (3.1.8)
|
13
|
+
crack (1.0.0)
|
14
|
+
bigdecimal
|
15
|
+
rexml
|
16
|
+
debug (1.9.2)
|
17
|
+
irb (~> 1.10)
|
18
|
+
reline (>= 0.3.8)
|
19
|
+
diff-lcs (1.5.1)
|
20
|
+
hashdiff (1.1.2)
|
21
|
+
io-console (0.7.2)
|
22
|
+
irb (1.14.1)
|
23
|
+
rdoc (>= 4.0.0)
|
24
|
+
reline (>= 0.4.2)
|
25
|
+
json (2.8.2)
|
26
|
+
language_server-protocol (3.17.0.3)
|
27
|
+
mini_portile2 (2.8.8)
|
28
|
+
nokogiri (1.16.7)
|
29
|
+
mini_portile2 (~> 2.8.2)
|
30
|
+
racc (~> 1.4)
|
31
|
+
nokogiri (1.16.7-arm64-darwin)
|
32
|
+
racc (~> 1.4)
|
33
|
+
parallel (1.26.3)
|
34
|
+
parser (3.3.6.0)
|
35
|
+
ast (~> 2.4.1)
|
36
|
+
racc
|
37
|
+
psych (5.2.0)
|
38
|
+
stringio
|
39
|
+
public_suffix (6.0.1)
|
40
|
+
racc (1.8.1)
|
41
|
+
rainbow (3.1.1)
|
42
|
+
rake (13.2.1)
|
43
|
+
rdoc (6.8.1)
|
44
|
+
psych (>= 4.0.0)
|
45
|
+
regexp_parser (2.9.2)
|
46
|
+
reline (0.5.11)
|
47
|
+
io-console (~> 0.5)
|
48
|
+
rexml (3.3.9)
|
49
|
+
rspec (3.13.0)
|
50
|
+
rspec-core (~> 3.13.0)
|
51
|
+
rspec-expectations (~> 3.13.0)
|
52
|
+
rspec-mocks (~> 3.13.0)
|
53
|
+
rspec-core (3.13.2)
|
54
|
+
rspec-support (~> 3.13.0)
|
55
|
+
rspec-expectations (3.13.3)
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
57
|
+
rspec-support (~> 3.13.0)
|
58
|
+
rspec-mocks (3.13.2)
|
59
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
60
|
+
rspec-support (~> 3.13.0)
|
61
|
+
rspec-support (3.13.1)
|
62
|
+
rubocop (1.68.0)
|
63
|
+
json (~> 2.3)
|
64
|
+
language_server-protocol (>= 3.17.0)
|
65
|
+
parallel (~> 1.10)
|
66
|
+
parser (>= 3.3.0.2)
|
67
|
+
rainbow (>= 2.2.2, < 4.0)
|
68
|
+
regexp_parser (>= 2.4, < 3.0)
|
69
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
70
|
+
ruby-progressbar (~> 1.7)
|
71
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
72
|
+
rubocop-ast (1.36.1)
|
73
|
+
parser (>= 3.3.1.0)
|
74
|
+
rubocop-rake (0.6.0)
|
75
|
+
rubocop (~> 1.0)
|
76
|
+
rubocop-rspec (3.2.0)
|
77
|
+
rubocop (~> 1.61)
|
78
|
+
ruby-progressbar (1.13.0)
|
79
|
+
stringio (3.1.2)
|
80
|
+
thor (1.3.2)
|
81
|
+
unicode-display_width (2.6.0)
|
82
|
+
webmock (3.24.0)
|
83
|
+
addressable (>= 2.8.0)
|
84
|
+
crack (>= 0.3.2)
|
85
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
86
|
+
|
87
|
+
PLATFORMS
|
88
|
+
arm64-darwin-23
|
89
|
+
ruby
|
90
|
+
|
91
|
+
DEPENDENCIES
|
92
|
+
aoc_generator!
|
93
|
+
debug (~> 1.9)
|
94
|
+
nokogiri (~> 1.16)
|
95
|
+
rake (~> 13.2)
|
96
|
+
rspec (~> 3.13)
|
97
|
+
rubocop (~> 1.68)
|
98
|
+
rubocop-rake (~> 0.6.0)
|
99
|
+
rubocop-rspec (~> 3.2)
|
100
|
+
thor (~> 1.3)
|
101
|
+
webmock (~> 3.24)
|
102
|
+
|
103
|
+
RUBY VERSION
|
104
|
+
ruby 3.3.4p94
|
105
|
+
|
106
|
+
BUNDLED WITH
|
107
|
+
2.5.22
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Advent of Code Generator
|
2
|
+
|
3
|
+
A Ruby gem that generates daily puzzle templates for Advent of Code.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```sh
|
8
|
+
# With default arguments
|
9
|
+
aoc generate
|
10
|
+
|
11
|
+
# With custom arguments
|
12
|
+
aoc generate -y=2023 -d=1 -u=cheddachedda -s=$SESSION_KEY
|
13
|
+
```
|
14
|
+
|
15
|
+
### Options
|
16
|
+
|
17
|
+
```sh
|
18
|
+
-y, [--year=N] # Defaults to the current year.
|
19
|
+
# Default: 2024
|
20
|
+
-d, [--day=N] # Defaults to the current day.
|
21
|
+
# Default: 28
|
22
|
+
-u, [--username=USERNAME] # Files will be generated in a directory with this name. Useful for multi-user repos.
|
23
|
+
# Default: advent_of_code
|
24
|
+
-s, [--session=SESSION] # Your adventofcode.com session key. Necessary for scraping data files and specs for part two.
|
25
|
+
```
|
26
|
+
|
27
|
+
## Generated file structure
|
28
|
+
|
29
|
+
```sh
|
30
|
+
adventofcode/
|
31
|
+
│
|
32
|
+
└── year_2024/
|
33
|
+
|
|
34
|
+
└── day_01/
|
35
|
+
├── main.rb
|
36
|
+
├── spec.rb
|
37
|
+
├── data.txt
|
38
|
+
└── README.md
|
39
|
+
```
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/exe/aoc
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
require_relative "generator"
|
5
|
+
require_relative "scraper"
|
6
|
+
|
7
|
+
module AdventOfCodeGenerator
|
8
|
+
# Command Line Interface for generating Advent of Code puzzle templates
|
9
|
+
class CLI < Thor
|
10
|
+
desc "generate", "Generate files for a new Advent of Code puzzle"
|
11
|
+
|
12
|
+
method_option :year,
|
13
|
+
required: false,
|
14
|
+
aliases: "-y",
|
15
|
+
type: :numeric,
|
16
|
+
desc: "Defaults to the current year.",
|
17
|
+
default: Time.now.year
|
18
|
+
|
19
|
+
method_option :day,
|
20
|
+
required: false,
|
21
|
+
aliases: "-d",
|
22
|
+
type: :numeric,
|
23
|
+
desc: "Defaults to the current day.",
|
24
|
+
default: Time.now.day
|
25
|
+
|
26
|
+
method_option :username,
|
27
|
+
required: false,
|
28
|
+
aliases: "-u",
|
29
|
+
desc: "Files will be generated in a directory with this name. Useful for multi-user repos.",
|
30
|
+
default: "advent_of_code"
|
31
|
+
|
32
|
+
method_option :session,
|
33
|
+
required: false,
|
34
|
+
aliases: "-s",
|
35
|
+
desc: "Your adventofcode.com session key. Necessary for scraping data files and specs for part two."
|
36
|
+
|
37
|
+
def generate
|
38
|
+
scraper = AdventOfCodeGenerator::Scraper.new(options)
|
39
|
+
generator = AdventOfCodeGenerator::Generator.new(options, scraper)
|
40
|
+
|
41
|
+
generator.call
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.exit_on_failure?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AdventOfCodeGenerator
|
4
|
+
# Creates directory structure and files for daily Advent of Code puzzles:
|
5
|
+
#
|
6
|
+
# Generates a file structure like:
|
7
|
+
#
|
8
|
+
# username/
|
9
|
+
# │
|
10
|
+
# └── year_2024/
|
11
|
+
# |
|
12
|
+
# └── day_01/
|
13
|
+
# ├── main.rb
|
14
|
+
# ├── spec.rb
|
15
|
+
# ├── data.txt
|
16
|
+
# └── README.md
|
17
|
+
#
|
18
|
+
class Generator
|
19
|
+
FileData = Struct.new(:path, :content)
|
20
|
+
|
21
|
+
def initialize(options, scraper)
|
22
|
+
@year = options[:year].to_s
|
23
|
+
@day = options[:day].to_s.rjust(2, "0") # Ensures day is two digits (e.g., "01" instead of "1")
|
24
|
+
@username = options[:username].gsub(/[_\-\.\s]/, "")
|
25
|
+
@scraper = scraper
|
26
|
+
end
|
27
|
+
|
28
|
+
def call
|
29
|
+
FileUtils.mkdir_p(daily_directory)
|
30
|
+
|
31
|
+
[readme, data_file, main_file, spec_file].each do |file_data|
|
32
|
+
next if File.exist?(file_data.path)
|
33
|
+
|
34
|
+
File.write(file_data.path, file_data.content)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def daily_directory
|
41
|
+
@daily_directory ||= "#{@username}/year_#{@year}/day_#{@day}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def readme
|
45
|
+
path = "#{daily_directory}/README.md"
|
46
|
+
content = @scraper.puzzle_description
|
47
|
+
|
48
|
+
FileData.new(path, content)
|
49
|
+
end
|
50
|
+
|
51
|
+
def data_file
|
52
|
+
path = "#{daily_directory}/data.txt"
|
53
|
+
content = @scraper.input_data
|
54
|
+
|
55
|
+
FileData.new(path, content)
|
56
|
+
end
|
57
|
+
|
58
|
+
def main_file
|
59
|
+
path = "#{daily_directory}/main.rb"
|
60
|
+
content = <<~RUBY
|
61
|
+
# frozen_string_literal: true
|
62
|
+
|
63
|
+
module #{@username.capitalize}
|
64
|
+
module Year#{@year}
|
65
|
+
class Day#{@day}
|
66
|
+
def initialize(input)
|
67
|
+
@input = input
|
68
|
+
end
|
69
|
+
|
70
|
+
def part_one
|
71
|
+
raise NotImplementedError
|
72
|
+
end
|
73
|
+
|
74
|
+
def part_two
|
75
|
+
raise NotImplementedError
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
RUBY
|
81
|
+
|
82
|
+
FileData.new(path, content)
|
83
|
+
end
|
84
|
+
|
85
|
+
def spec_file
|
86
|
+
path = "#{daily_directory}/spec.rb"
|
87
|
+
content = <<~RUBY
|
88
|
+
# frozen_string_literal: true
|
89
|
+
|
90
|
+
require_relative "main"
|
91
|
+
|
92
|
+
RSpec.describe #{@username.capitalize}::Year#{@year}::Day#{@day} do
|
93
|
+
subject(:puzzle) { described_class.new(input) }
|
94
|
+
|
95
|
+
let(:input) { File.read("\#{__dir__}/data.txt") }
|
96
|
+
|
97
|
+
it "solves Part One" do
|
98
|
+
expect(puzzle.part_one).to eq("")
|
99
|
+
end
|
100
|
+
|
101
|
+
xit "solves Part Two" do
|
102
|
+
expect(puzzle.part_two).to eq("some other value")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
RUBY
|
106
|
+
|
107
|
+
FileData.new(path, content)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "net/http"
|
4
|
+
|
5
|
+
module AdventOfCodeGenerator
|
6
|
+
# Fetches puzzle descriptions and input data from adventofcode.com.
|
7
|
+
class Scraper
|
8
|
+
def initialize(options)
|
9
|
+
@year = options[:year]
|
10
|
+
@day = options[:day]
|
11
|
+
@session_key = options[:session]
|
12
|
+
end
|
13
|
+
|
14
|
+
def puzzle_description
|
15
|
+
warn "You'll need to provide a session key to scrape Part Two." unless @session_key
|
16
|
+
|
17
|
+
uri = URI("https://adventofcode.com/#{@year}/day/#{@day}")
|
18
|
+
response = Net::HTTP.get_response(uri, headers)
|
19
|
+
|
20
|
+
response.body
|
21
|
+
end
|
22
|
+
|
23
|
+
def input_data
|
24
|
+
return @input_data if @input_data
|
25
|
+
return warn "No session key provided; unable to download data file." unless @session_key
|
26
|
+
|
27
|
+
uri = URI("https://adventofcode.com/#{@year}/day/#{@day}/input")
|
28
|
+
response = Net::HTTP.get_response(uri, headers)
|
29
|
+
@input_data ||= response.body
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def headers
|
35
|
+
return {} unless @session_key
|
36
|
+
|
37
|
+
@headers ||= { cookie: "session=#{@session_key}" }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aoc_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Nguyen
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-11-27 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
Automatically creates daily puzzle files and test templates for Advent of Code challenges,
|
15
|
+
helping developers focus on solving the puzzles rather than project setup.
|
16
|
+
Includes support for multiple years and customizable templates.
|
17
|
+
email:
|
18
|
+
- daniel.n.q.nguyen@gmail.com
|
19
|
+
executables:
|
20
|
+
- aoc
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- ".rspec"
|
25
|
+
- ".rubocop.yml"
|
26
|
+
- ".tool-versions"
|
27
|
+
- Gemfile
|
28
|
+
- Gemfile.lock
|
29
|
+
- README.md
|
30
|
+
- Rakefile
|
31
|
+
- bin/console
|
32
|
+
- bin/setup
|
33
|
+
- exe/aoc
|
34
|
+
- lib/advent_of_code_generator.rb
|
35
|
+
- lib/advent_of_code_generator/cli.rb
|
36
|
+
- lib/advent_of_code_generator/generator.rb
|
37
|
+
- lib/advent_of_code_generator/scraper.rb
|
38
|
+
homepage: https://github.com/cheddachedda/advent_of_code_generator
|
39
|
+
licenses: []
|
40
|
+
metadata:
|
41
|
+
rubygems_mfa_required: 'true'
|
42
|
+
allowed_push_host: https://rubygems.org
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.3'
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubygems_version: 3.5.23
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: A Ruby gem that generates daily puzzle templates for Advent of Code.
|
62
|
+
test_files: []
|