advent 0.1.4 → 0.1.6

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: 360b1871cc09fd664dd8562fd1a29afd9b2e8bbc7a83d9d711c7933a6c62b5ec
4
- data.tar.gz: 2f9cde07fa43650354a3f11c7cb869efa7c969d4254083ca807bd7a855fcf9d0
3
+ metadata.gz: a49571ac28572d7a91bcc6a26ecb7253b4f10690dfe2c529a86eca8d310b059b
4
+ data.tar.gz: 470af342600d4fac184e63837dd0f0cdfbd27d34268d34d4a191ef65ce59b960
5
5
  SHA512:
6
- metadata.gz: e27b9323e1ad7a07484fe9302dfd49b430bd4fc5433ef0e412e1af14f734bdd1c0a8c719803e108e4b7b3aec144ec942119bc6a07bc93381f4aae9ef634324b1
7
- data.tar.gz: b8e99258c57406a1cf945e868a1642d8ed8636c983fd960fd3f889bc6760c170bb346e3cdb0cc82e547f880dbd8c6f71898e941defdfd41b97a73974bc4cdec0
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
- └── 2016
35
+ ├── 2016
36
+ └── advent.yml
25
37
 
26
- Some commands can be run from within a directory for a specific year, but it's
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
@@ -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(year_or_day, day = nil)
38
- year, day = determine_year_and_day(year_or_day, day)
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
- subpath = if in_year_directory?
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(year_or_day, day = nil)
73
- year, day = determine_year_and_day(year_or_day, day)
44
+ def generate(year, day)
45
+ year = parse_number year
46
+ day = parse_number day
74
47
 
75
- if (error_message = validate(year, day))
76
- say_error error_message, :red
48
+ if (message = validate(year, day))
49
+ say_error message, :red
77
50
  return
78
51
  end
79
52
 
80
- subpath = if in_year_directory?
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
- Solver.new(self, root_path.join(path)).solve
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
@@ -18,11 +18,22 @@ module Advent
18
18
  end
19
19
 
20
20
  def value=(val)
21
- File.write file_name, val
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
- File.read file_name if exist?
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Advent
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.6"
5
5
  end
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 = Session.new
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
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-23 00:00:00.000000000 Z
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]