advent 0.1.4 → 0.1.6
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 +4 -4
- data/README.md +40 -3
- data/lib/advent/cli/downloader.rb +32 -0
- data/lib/advent/cli/solver.rb +5 -9
- data/lib/advent/cli.rb +29 -65
- data/lib/advent/configuration.rb +30 -0
- data/lib/advent/session.rb +13 -2
- data/lib/advent/version.rb +1 -1
- data/lib/advent.rb +23 -1
- metadata +12 -4
- data/Rakefile +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a49571ac28572d7a91bcc6a26ecb7253b4f10690dfe2c529a86eca8d310b059b
|
4
|
+
data.tar.gz: 470af342600d4fac184e63837dd0f0cdfbd27d34268d34d4a191ef65ce59b960
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e94342f2d83c40b0bd360478d7535583da1076517b218c045b44ead0d455e389c174e58c92321da978f63cecbd41abfff0904927552b1acaeb08853b74874a34
|
7
|
+
data.tar.gz: 5d2af6a890fc835148f7e1bc054ef49a3e69e641d7a93528ae184b8b39d48a8c69ce4cdf166c29750525750167278c8c84350d8c2d766df77c8d2a2b30f4e502
|
data/README.md
CHANGED
@@ -16,15 +16,26 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
+
Initialise a new project somewhere:
|
20
|
+
|
21
|
+
```bash
|
22
|
+
mkdir advent_of_code && cd advent_of_code
|
23
|
+
|
24
|
+
# create a blank advent.yml config file
|
25
|
+
advent init
|
26
|
+
```
|
27
|
+
|
28
|
+
Configuration values and format are explained in the [Config](#config) section.
|
29
|
+
|
19
30
|
Advent expects you to have a working directory resembling something like:
|
20
31
|
|
21
32
|
$ tree
|
22
33
|
.
|
23
34
|
├── 2015
|
24
|
-
|
35
|
+
├── 2016
|
36
|
+
└── advent.yml
|
25
37
|
|
26
|
-
|
27
|
-
better to run from the parent directory where possible.
|
38
|
+
You can run commands from anywhere under this directory.
|
28
39
|
|
29
40
|
The typical flow for tackling a daily challenge would be:
|
30
41
|
|
@@ -40,6 +51,32 @@ A list of commands and help is available using `advent`:
|
|
40
51
|
|
41
52
|
$ advent help
|
42
53
|
|
54
|
+
## Config
|
55
|
+
|
56
|
+
The config file should be at the root of your working directory called
|
57
|
+
`advent.yml`. The default values if you don't provide an override are:
|
58
|
+
|
59
|
+
```yaml
|
60
|
+
download_when_generating: true
|
61
|
+
remember_session: true
|
62
|
+
```
|
63
|
+
|
64
|
+
### Config explained
|
65
|
+
|
66
|
+
<dl>
|
67
|
+
<dt>download_when_generating</dt>
|
68
|
+
<dd>
|
69
|
+
When you run `advent generate` it will automatically download the input file to
|
70
|
+
go with it
|
71
|
+
</dd>
|
72
|
+
|
73
|
+
<dt>remember_session</dt>
|
74
|
+
<dd>
|
75
|
+
Save your session cookie in `.advent_session` when prompted so you don't need to
|
76
|
+
find it again
|
77
|
+
</dd>
|
78
|
+
</dl>
|
79
|
+
|
43
80
|
## Development
|
44
81
|
|
45
82
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Advent::CLI::Downloader
|
4
|
+
def initialize(command, year, day)
|
5
|
+
@command = command
|
6
|
+
@year = year
|
7
|
+
@day = day
|
8
|
+
end
|
9
|
+
|
10
|
+
def download
|
11
|
+
ask_for_session_cookie_if_needed
|
12
|
+
input = Advent::Input.new(Advent.root.join(@year), day: @day.to_i)
|
13
|
+
|
14
|
+
if input.download(Advent.session.value, @command.options.http_module)
|
15
|
+
@command.say "Input downloaded to #{input.file_path}.", :green
|
16
|
+
@command.say "\nUsing #load_input in your daily solution will load the input file for you."
|
17
|
+
else
|
18
|
+
@command.say_error "Something went wrong, maybe an old session cookie?", :red
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def ask_for_session_cookie_if_needed
|
25
|
+
return if Advent.session.exist?
|
26
|
+
|
27
|
+
session = @command.ask "What is your Advent of Code session cookie value?", echo: false
|
28
|
+
Advent.session.value = session
|
29
|
+
|
30
|
+
@command.say "\n\nThanks. Psst, we're going to save this for next time. It's in .advent_session if you need to update or delete it.\n\n"
|
31
|
+
end
|
32
|
+
end
|
data/lib/advent/cli/solver.rb
CHANGED
@@ -18,7 +18,7 @@ class Advent::CLI::Solver
|
|
18
18
|
load @path, Solutions
|
19
19
|
solution = Solutions.const_get(solution_class_name).new
|
20
20
|
else
|
21
|
-
require @path
|
21
|
+
require @path.expand_path
|
22
22
|
solution = Object.const_get(solution_class_name).new
|
23
23
|
end
|
24
24
|
|
@@ -37,15 +37,11 @@ class Advent::CLI::Solver
|
|
37
37
|
|
38
38
|
private
|
39
39
|
|
40
|
-
def day
|
41
|
-
@_day ||= @path.basename.to_s.match(/day([0-9]+)\.rb/)[1]
|
42
|
-
end
|
43
|
-
|
44
|
-
def solution_file_name
|
45
|
-
"day#{day}.rb"
|
46
|
-
end
|
47
|
-
|
48
40
|
def solution_class_name
|
49
41
|
"Day#{day}"
|
50
42
|
end
|
43
|
+
|
44
|
+
def day
|
45
|
+
@_day ||= @path.basename.to_s.match(/day([0-9]+)\.rb/)[1]
|
46
|
+
end
|
51
47
|
end
|
data/lib/advent/cli.rb
CHANGED
@@ -8,15 +8,19 @@ require "thor"
|
|
8
8
|
module Advent
|
9
9
|
class CLI < Thor
|
10
10
|
include Thor::Actions
|
11
|
+
EXCLUDED_ROOT_COMMANDS = %w[help init version]
|
11
12
|
|
12
|
-
class_option :root_path, default: Dir.pwd, hide: true, check_default_type: false
|
13
13
|
class_option :http_module, default: Net::HTTP, check_default_type: false
|
14
14
|
|
15
15
|
def initialize(*args)
|
16
16
|
super
|
17
17
|
|
18
|
-
self.destination_root = root_path
|
19
18
|
source_paths << File.expand_path("templates", __dir__)
|
19
|
+
|
20
|
+
# Don't try to load Advent.root if we're a command that doesn't need it
|
21
|
+
unless EXCLUDED_ROOT_COMMANDS.include? args.last[:current_command]&.name
|
22
|
+
self.destination_root = Advent.root
|
23
|
+
end
|
20
24
|
end
|
21
25
|
|
22
26
|
# @return [Boolean] defines whether an exit status is set if a command fails
|
@@ -24,44 +28,12 @@ module Advent
|
|
24
28
|
true
|
25
29
|
end
|
26
30
|
|
27
|
-
no_commands do
|
28
|
-
# @return [Boolean] whether the current root_path option is in a
|
29
|
-
# directory that looks like a year (eg. 2015)
|
30
|
-
def in_year_directory?
|
31
|
-
dir = root_path.basename.to_s
|
32
|
-
dir =~ /^20[0-9]{2}/
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
31
|
desc "download YEAR DAY", "Download the input for YEAR and DAY"
|
37
|
-
def download(
|
38
|
-
|
39
|
-
|
40
|
-
if (error_message = validate(year, day))
|
41
|
-
say_error error_message, :red
|
42
|
-
return
|
43
|
-
end
|
32
|
+
def download(year, day)
|
33
|
+
require "advent/cli/downloader"
|
44
34
|
|
45
|
-
|
46
|
-
|
47
|
-
else
|
48
|
-
"#{year}/"
|
49
|
-
end
|
50
|
-
|
51
|
-
unless Advent.session.exist?
|
52
|
-
session = ask "What is your Advent of Code session cookie value?", echo: false
|
53
|
-
Advent.session.value = session
|
54
|
-
|
55
|
-
say "\n\nThanks. Psst, we're going to save this for next time. It's in .advent_session if you need to update or delete it.\n\n"
|
56
|
-
end
|
57
|
-
|
58
|
-
input = Advent::Input.new(root_path.join(subpath), day: day.to_i)
|
59
|
-
|
60
|
-
if input.download(Advent.session.value, options.http_module)
|
61
|
-
say "Input downloaded to #{input.file_path}.", :green
|
62
|
-
say "\nUsing #load_input in your daily solution will load the input file for you."
|
63
|
-
else
|
64
|
-
say_error "Something went wrong, maybe an old session cookie?", :red
|
35
|
+
Dir.chdir Advent.root do
|
36
|
+
Downloader.new(self, year, day).download
|
65
37
|
end
|
66
38
|
end
|
67
39
|
|
@@ -69,29 +41,37 @@ module Advent
|
|
69
41
|
# Generates a new solution file. If within a year directory, only the day
|
70
42
|
# is used, otherwise both the year and day will be required to generate the
|
71
43
|
# output.
|
72
|
-
def generate(
|
73
|
-
year
|
44
|
+
def generate(year, day)
|
45
|
+
year = parse_number year
|
46
|
+
day = parse_number day
|
74
47
|
|
75
|
-
if (
|
76
|
-
say_error
|
48
|
+
if (message = validate(year, day))
|
49
|
+
say_error message, :red
|
77
50
|
return
|
78
51
|
end
|
79
52
|
|
80
|
-
|
53
|
+
template "solution.rb.tt", "#{year}/day#{day}.rb", context: binding
|
54
|
+
template "solution_test.rb.tt", "#{year}/test/day#{day}_test.rb", context: binding
|
55
|
+
|
56
|
+
download year, day if Advent.config.download_when_generating
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "init DIR", "Initialise a new advent project in DIR"
|
60
|
+
def init(dir = ".")
|
61
|
+
create_file Pathname.getwd.join(dir).join(Advent::Configuration::FILE_NAME) do
|
81
62
|
""
|
82
|
-
else
|
83
|
-
"#{year}/"
|
84
63
|
end
|
85
|
-
|
86
|
-
template "solution.rb.tt", "#{subpath}day#{day}.rb", context: binding
|
87
|
-
template "solution_test.rb.tt", "#{subpath}test/day#{day}_test.rb", context: binding
|
88
64
|
end
|
89
65
|
|
90
66
|
desc "solve FILE", "Solve your solution"
|
91
67
|
# Runs a solution file, outputting both :part1 and :part2 method return values.
|
92
68
|
def solve(path)
|
93
69
|
require "advent/cli/solver"
|
94
|
-
|
70
|
+
file_path = Pathname.getwd.join(path)
|
71
|
+
|
72
|
+
Dir.chdir Advent.root do
|
73
|
+
Solver.new(self, file_path.relative_path_from(Advent.root)).solve
|
74
|
+
end
|
95
75
|
end
|
96
76
|
|
97
77
|
desc "version", "Prints the current version of the gem"
|
@@ -102,22 +82,6 @@ module Advent
|
|
102
82
|
|
103
83
|
private
|
104
84
|
|
105
|
-
def determine_year_and_day(year_or_day, day)
|
106
|
-
if in_year_directory?
|
107
|
-
[root_path.basename.to_s, parse_number(year_or_day)]
|
108
|
-
else
|
109
|
-
[year_or_day, parse_number(day)]
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def root_path
|
114
|
-
@_root_path ||= if options.root_path.is_a?(Pathname)
|
115
|
-
options.root_path
|
116
|
-
else
|
117
|
-
Pathname.new(options.root_path)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
85
|
def parse_number(str)
|
122
86
|
if (m = str.match(/[0-9]+/))
|
123
87
|
m[0]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "psych"
|
2
|
+
|
3
|
+
module Advent
|
4
|
+
class Configuration
|
5
|
+
DEFAULTS = {
|
6
|
+
"download_when_generating" => true,
|
7
|
+
"remember_session" => true
|
8
|
+
}
|
9
|
+
FILE_NAME = "advent.yml"
|
10
|
+
|
11
|
+
attr_reader :download_when_generating, :remember_session
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def from_file(file = FILE_NAME)
|
15
|
+
if RUBY_VERSION >= "3.1"
|
16
|
+
new Psych.safe_load_file(file)
|
17
|
+
else
|
18
|
+
new Psych.safe_load(File.read(file))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(conf)
|
24
|
+
config = DEFAULTS.merge(conf || {})
|
25
|
+
|
26
|
+
@download_when_generating = config.dig("download_when_generating")
|
27
|
+
@remember_session = config.dig("remember_session")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/advent/session.rb
CHANGED
@@ -18,11 +18,22 @@ module Advent
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def value=(val)
|
21
|
-
|
21
|
+
if save_to_disk?
|
22
|
+
File.write file_name, val
|
23
|
+
else
|
24
|
+
@_value = val
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def value
|
25
|
-
|
29
|
+
return @_value unless save_to_disk?
|
30
|
+
return File.read(file_name) if exist?
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def save_to_disk?
|
36
|
+
Advent.config.remember_session
|
26
37
|
end
|
27
38
|
end
|
28
39
|
end
|
data/lib/advent/version.rb
CHANGED
data/lib/advent.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "advent/configuration"
|
3
4
|
require_relative "advent/input"
|
4
5
|
require_relative "advent/session"
|
5
6
|
require_relative "advent/solution"
|
@@ -10,8 +11,29 @@ module Advent
|
|
10
11
|
class Error < StandardError; end
|
11
12
|
|
12
13
|
class << self
|
14
|
+
def config
|
15
|
+
@_config ||= Configuration.from_file(root.join(Configuration::FILE_NAME))
|
16
|
+
end
|
17
|
+
|
18
|
+
def root
|
19
|
+
if (location = find_config_location)
|
20
|
+
location
|
21
|
+
else
|
22
|
+
raise Error, "Cannot find advent.yml config file in current or parent directories."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
13
26
|
def session
|
14
|
-
@_session
|
27
|
+
@_session ||= Session.new
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def find_config_location
|
33
|
+
Pathname.new(Dir.pwd).ascend do |path|
|
34
|
+
return path if File.exist? path.join(Configuration::FILE_NAME)
|
35
|
+
return nil if path.to_s == "/"
|
36
|
+
end
|
15
37
|
end
|
16
38
|
end
|
17
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: advent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Grieve
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -34,11 +34,12 @@ extra_rdoc_files: []
|
|
34
34
|
files:
|
35
35
|
- LICENSE.txt
|
36
36
|
- README.md
|
37
|
-
- Rakefile
|
38
37
|
- exe/advent
|
39
38
|
- lib/advent.rb
|
40
39
|
- lib/advent/cli.rb
|
40
|
+
- lib/advent/cli/downloader.rb
|
41
41
|
- lib/advent/cli/solver.rb
|
42
|
+
- lib/advent/configuration.rb
|
42
43
|
- lib/advent/input.rb
|
43
44
|
- lib/advent/session.rb
|
44
45
|
- lib/advent/solution.rb
|
@@ -50,7 +51,13 @@ homepage: https://github.com/dnlgrv/advent-rb
|
|
50
51
|
licenses:
|
51
52
|
- MIT
|
52
53
|
metadata: {}
|
53
|
-
post_install_message:
|
54
|
+
post_install_message: |2+
|
55
|
+
|
56
|
+
advent v0.1.5 requires a config file in your working directory.
|
57
|
+
|
58
|
+
See https://github.com/dnlgrv/advent-rb/blob/main/README.md#usage or if you're
|
59
|
+
brave run `advent init` in your current directory.
|
60
|
+
|
54
61
|
rdoc_options: []
|
55
62
|
require_paths:
|
56
63
|
- lib
|
@@ -70,3 +77,4 @@ signing_key:
|
|
70
77
|
specification_version: 4
|
71
78
|
summary: Have fun with the Advent of Code using Ruby.
|
72
79
|
test_files: []
|
80
|
+
...
|
data/Rakefile
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bundler/gem_tasks"
|
4
|
-
require "rake/testtask"
|
5
|
-
require "standard/rake"
|
6
|
-
|
7
|
-
Rake::TestTask.new(:test) do |t|
|
8
|
-
t.libs << "test"
|
9
|
-
t.libs << "lib"
|
10
|
-
t.options = "-p"
|
11
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
12
|
-
end
|
13
|
-
|
14
|
-
task default: %i[test]
|