aoc_cli 1.0.0 → 1.0.1

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
2
  SHA256:
3
- metadata.gz: 523ec81af92a97e0d60f5e7490d29feb336e2c1577eecb00c7510c47171dfb87
4
- data.tar.gz: 6c6f424ee15d996c12d9552d6a7681fd946b0f0724c5803f3344bfdb41eaad72
3
+ metadata.gz: ddf7e8e1d35efd516bae0a1a9b4d773a0ff59120f3ae287491668fa81740ffba
4
+ data.tar.gz: 7fc18fbfcf0391b6d9b6ed43b6e6f35b372f368c9ffd8f5f23c2f3a305c470d2
5
5
  SHA512:
6
- metadata.gz: cd1fd05753d8fc593f37b6f28db96bb58cb9eae931a8b28852513ed25bf6cdcc300c44f4963a1581207dd8001b4d9fc0115ac582b6d79d49e1766c54dc17fbe7
7
- data.tar.gz: 1a5a042be37b1e4b661c05417a94312701c26eb794895cfc58455099ef9cd16f3c6df57ac74d096d20f5298019415b6beea15acc875f465728ef7314ad5dd031
6
+ metadata.gz: 41cb419b34d2d7a385e3c227e11b4f548f834d1f6d14566d11baff340367ff95ed7e87cdf512ae45aa3dc4339b65e9549ff2182960e33d0b26af06a6e36e1f24
7
+ data.tar.gz: e32591f10e88ff7aa402ebe0523328af2bc61a8458028ff3c559477ec81aa3ee34944b8cf63156ae8625e9000e4a9716d910c02a59a4010679c524dcf387652b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aoc_cli (1.0.0)
4
+ aoc_cli (1.0.1)
5
5
  http
6
6
  kangaru
7
7
  nokogiri
data/aoc_cli.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.bindir = "exe"
31
31
  spec.executables = ["aoc"]
32
- spec.require_paths = ["lib"]
32
+ spec.require_paths = %w[lib db]
33
33
 
34
34
  spec.add_dependency "http"
35
35
  spec.add_dependency "kangaru"
@@ -0,0 +1,17 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table :progresses do
4
+ primary_key :id
5
+
6
+ foreign_key :puzzle_id, :puzzles, null: false
7
+
8
+ integer :level, null: false
9
+
10
+ datetime :started_at, null: false
11
+ datetime :completed_at
12
+
13
+ datetime :created_at
14
+ datetime :updated_at
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table :puzzles do
4
+ drop_column :part_one_completed_at
5
+ drop_column :part_two_completed_at
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ module AocCli
2
+ class Progress < Kangaru::Model
3
+ many_to_one :puzzle
4
+
5
+ validates :puzzle, required: true
6
+ validates :level, integer: { between: 1..2 }
7
+ validates :started_at, required: true
8
+
9
+ def complete?
10
+ !incomplete?
11
+ end
12
+
13
+ def incomplete?
14
+ completed_at.nil?
15
+ end
16
+
17
+ def complete!
18
+ update(completed_at: Time.now)
19
+ end
20
+
21
+ def reset!
22
+ update(started_at: Time.now)
23
+ end
24
+
25
+ def time_taken
26
+ if complete?
27
+ completed_at - started_at
28
+ else
29
+ Time.now - started_at
30
+ end
31
+ end
32
+ end
33
+ end
@@ -6,6 +6,14 @@ module AocCli
6
6
  one_to_one :location, as: :resource
7
7
  one_to_many :attempts
8
8
 
9
+ one_to_one :part_one_progress,
10
+ class: "AocCli::Progress",
11
+ conditions: { level: 1 }
12
+
13
+ one_to_one :part_two_progress,
14
+ class: "AocCli::Progress",
15
+ conditions: { level: 2 }
16
+
9
17
  validates :event, required: true
10
18
  validates :day, integer: { between: 1..25 }
11
19
  validates :content, required: true
@@ -16,13 +24,5 @@ module AocCli
16
24
  def presenter
17
25
  @presenter ||= Presenters::PuzzlePresenter.new(self)
18
26
  end
19
-
20
- def mark_complete!(level)
21
- case level
22
- when 1 then update(part_one_completed_at: Time.now)
23
- when 2 then update(part_two_completed_at: Time.now)
24
- else raise "invalid level"
25
- end
26
- end
27
27
  end
28
28
  end
@@ -0,0 +1,48 @@
1
+ module AocCli
2
+ module Processors
3
+ class ProgressSyncer < Core::Processor
4
+ attr_accessor :puzzle, :stats
5
+
6
+ validates :puzzle, required: true
7
+ validates :stats, required: true
8
+
9
+ def run
10
+ case current_progress
11
+ when 0 then handle_not_complete!
12
+ when 1 then handle_partially_complete!
13
+ when 2 then handle_fully_complete!
14
+ else raise
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def_delegators :puzzle, :part_one_progress, :part_two_progress
21
+
22
+ def current_progress
23
+ stats.progress(puzzle.day)
24
+ end
25
+
26
+ def create_part_one_progress!
27
+ Progress.create(puzzle:, level: 1, started_at: Time.now)
28
+ end
29
+
30
+ def create_part_two_progress!
31
+ Progress.create(puzzle:, level: 2, started_at: Time.now)
32
+ end
33
+
34
+ def handle_not_complete!
35
+ create_part_one_progress! if part_one_progress.nil?
36
+ end
37
+
38
+ def handle_partially_complete!
39
+ part_one_progress&.complete! if part_one_progress&.incomplete?
40
+ create_part_two_progress! if part_two_progress.nil?
41
+ end
42
+
43
+ def handle_fully_complete!
44
+ part_two_progress&.complete! if part_two_progress&.incomplete?
45
+ end
46
+ end
47
+ end
48
+ end
@@ -8,6 +8,7 @@ module AocCli
8
8
 
9
9
  def validate
10
10
  super
11
+ validate_event_stats_set! if errors.empty?
11
12
  validate_event_location_set! if errors.empty?
12
13
  validate_event_dir_exists! if errors.empty?
13
14
  validate_puzzle_dir_does_not_exist! if errors.empty?
@@ -15,6 +16,8 @@ module AocCli
15
16
 
16
17
  def run
17
18
  create_or_update_puzzle!(fetch_content!, fetch_input!).tap do |puzzle|
19
+ sync_puzzle_progress!(puzzle)
20
+
18
21
  attach_puzzle_dir!(puzzle).tap do |location|
19
22
  write_puzzle_files!(puzzle, location)
20
23
  end
@@ -53,6 +56,10 @@ module AocCli
53
56
  end
54
57
  end
55
58
 
59
+ def sync_puzzle_progress!(puzzle)
60
+ ProgressSyncer.run!(puzzle:, stats: event.stats)
61
+ end
62
+
56
63
  def attach_puzzle_dir!(puzzle)
57
64
  puzzle_dir.mkdir
58
65
 
@@ -63,6 +70,14 @@ module AocCli
63
70
  PuzzleDirSynchroniser.run!(puzzle:, location:)
64
71
  end
65
72
 
73
+ def validate_event_stats_set!
74
+ return unless event.stats.nil?
75
+
76
+ errors << Kangaru::Validation::Error.new(
77
+ attribute: :event_stats, message: "can't be blank"
78
+ )
79
+ end
80
+
66
81
  def validate_event_location_set!
67
82
  return unless event.location.nil?
68
83
 
@@ -39,8 +39,8 @@ module AocCli
39
39
 
40
40
  def advance_puzzle!
41
41
  event.stats.advance_progress!(day)
42
- puzzle.mark_complete!(level)
43
42
 
43
+ ProgressSyncer.run!(puzzle:, stats: event.stats.reload)
44
44
  PuzzleDirSynchroniser.run!(puzzle:, location:, skip_cache: true)
45
45
  end
46
46
 
@@ -1,3 +1,3 @@
1
1
  module AocCli
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.0.1".freeze
3
3
  end
data/lib/aoc_cli.rb CHANGED
@@ -14,9 +14,13 @@ module AocCli
14
14
  config_path "spec/aoc.yml", env: :test
15
15
 
16
16
  configure do |config|
17
+ migration_path = File.join(
18
+ File.expand_path(__dir__ || raise), "../db/migrate"
19
+ )
20
+
17
21
  config.database.adaptor = :sqlite
18
22
  config.database.path = File.expand_path("~/.local/share/aoc/aoc.sqlite3")
19
- config.database.migration_path = "db/migrate"
23
+ config.database.migration_path = migration_path
20
24
  end
21
25
 
22
26
  configure env: :test do |config|
@@ -6,7 +6,7 @@ gems:
6
6
  source:
7
7
  type: git
8
8
  name: ruby/gem_rbs_collection
9
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
9
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
10
10
  remote: https://github.com/ruby/gem_rbs_collection.git
11
11
  repo_dir: gems
12
12
  - name: addressable
@@ -14,7 +14,7 @@ gems:
14
14
  source:
15
15
  type: git
16
16
  name: ruby/gem_rbs_collection
17
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
17
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
18
18
  remote: https://github.com/ruby/gem_rbs_collection.git
19
19
  repo_dir: gems
20
20
  - name: base64
@@ -42,7 +42,7 @@ gems:
42
42
  source:
43
43
  type: git
44
44
  name: ruby/gem_rbs_collection
45
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
45
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
46
46
  remote: https://github.com/ruby/gem_rbs_collection.git
47
47
  repo_dir: gems
48
48
  - name: connection_pool
@@ -50,7 +50,7 @@ gems:
50
50
  source:
51
51
  type: git
52
52
  name: ruby/gem_rbs_collection
53
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
53
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
54
54
  remote: https://github.com/ruby/gem_rbs_collection.git
55
55
  repo_dir: gems
56
56
  - name: date
@@ -74,7 +74,7 @@ gems:
74
74
  source:
75
75
  type: git
76
76
  name: ruby/gem_rbs_collection
77
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
77
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
78
78
  remote: https://github.com/ruby/gem_rbs_collection.git
79
79
  repo_dir: gems
80
80
  - name: i18n
@@ -82,7 +82,7 @@ gems:
82
82
  source:
83
83
  type: git
84
84
  name: ruby/gem_rbs_collection
85
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
85
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
86
86
  remote: https://github.com/ruby/gem_rbs_collection.git
87
87
  repo_dir: gems
88
88
  - name: kangaru
@@ -114,7 +114,7 @@ gems:
114
114
  source:
115
115
  type: git
116
116
  name: ruby/gem_rbs_collection
117
- revision: 20e6e0f0685139dbd29df50e03367e222aa5d1b8
117
+ revision: ec140aff951e3af39846eed4525ba5d040d294fa
118
118
  remote: https://github.com/ruby/gem_rbs_collection.git
119
119
  repo_dir: gems
120
120
  - name: pathname
@@ -0,0 +1,21 @@
1
+ module AocCli
2
+ class Progress < Kangaru::Model
3
+ attr_accessor id: Integer
4
+ attr_accessor puzzle: Puzzle
5
+ attr_accessor level: Integer
6
+ attr_accessor started_at: Time
7
+ attr_accessor completed_at: Time
8
+ attr_accessor created_at: Time
9
+ attr_accessor updated_at: Time
10
+
11
+ def complete?: -> bool
12
+
13
+ def incomplete?: -> bool
14
+
15
+ def complete!: -> void
16
+
17
+ def reset!: -> void
18
+
19
+ def time_taken: -> Float
20
+ end
21
+ end
@@ -9,8 +9,6 @@ module AocCli
9
9
  attr_accessor input: String
10
10
  attr_accessor created_at: Time
11
11
  attr_accessor updated_at: Time
12
- attr_accessor part_one_completed_at: Time
13
- attr_accessor part_two_completed_at: Time
14
12
 
15
13
  attr_accessor location: Location
16
14
  attr_accessor location_dataset: Sequel::Dataset
@@ -18,11 +16,12 @@ module AocCli
18
16
  attr_accessor attempts: Array[Attempt]
19
17
  attr_accessor attempts_dataset: Sequel::Dataset
20
18
 
19
+ attr_accessor part_one_progress: Progress?
20
+ attr_accessor part_two_progress: Progress?
21
+
21
22
  # Delegated to event
22
23
  def year: -> Integer
23
24
 
24
25
  attr_reader presenter: Presenters::PuzzlePresenter
25
-
26
- def mark_complete!: (Integer) -> void
27
26
  end
28
27
  end
@@ -0,0 +1,29 @@
1
+ module AocCli
2
+ module Processors
3
+ class ProgressSyncer < Core::Processor
4
+ attr_accessor puzzle: Puzzle
5
+ attr_accessor stats: Stats
6
+
7
+ def run: -> void
8
+
9
+ def self.run!: (puzzle: untyped, stats: untyped) -> void
10
+
11
+ private
12
+
13
+ def part_one_progress: -> Progress?
14
+ def part_two_progress: -> Progress?
15
+
16
+ def current_progress: -> Integer
17
+
18
+ def create_part_one_progress!: -> void
19
+
20
+ def create_part_two_progress!: -> void
21
+
22
+ def handle_not_complete!: -> void
23
+
24
+ def handle_partially_complete!: -> void
25
+
26
+ def handle_fully_complete!: -> void
27
+ end
28
+ end
29
+ end
@@ -23,10 +23,14 @@ module AocCli
23
23
 
24
24
  def create_or_update_puzzle!: (String, String) -> Puzzle
25
25
 
26
+ def sync_puzzle_progress!: (Puzzle) -> void
27
+
26
28
  def attach_puzzle_dir!: (Puzzle) -> Location
27
29
 
28
30
  def write_puzzle_files!: (Puzzle, Location) -> PuzzleDirSyncLog
29
31
 
32
+ def validate_event_stats_set!: -> void
33
+
30
34
  def validate_event_location_set!: -> void
31
35
 
32
36
  def validate_event_dir_exists!: -> void
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aoc_cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Welham
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-20 00:00:00.000000000 Z
11
+ date: 2024-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -123,6 +123,8 @@ files:
123
123
  - db/migrate/4_create_attempts.rb
124
124
  - db/migrate/5_create_locations.rb
125
125
  - db/migrate/6_create_puzzle_dir_sync_logs.rb
126
+ - db/migrate/7_create_progresses.rb
127
+ - db/migrate/8_remove_legacy_timestamps.rb
126
128
  - exe/aoc
127
129
  - lib/aoc_cli.rb
128
130
  - lib/aoc_cli/components/attempts_table.erb
@@ -155,6 +157,7 @@ files:
155
157
  - lib/aoc_cli/models/attempt.rb
156
158
  - lib/aoc_cli/models/event.rb
157
159
  - lib/aoc_cli/models/location.rb
160
+ - lib/aoc_cli/models/progress.rb
158
161
  - lib/aoc_cli/models/puzzle.rb
159
162
  - lib/aoc_cli/models/puzzle_dir_sync_log.rb
160
163
  - lib/aoc_cli/models/stats.rb
@@ -162,6 +165,7 @@ files:
162
165
  - lib/aoc_cli/presenters/puzzle_presenter.rb
163
166
  - lib/aoc_cli/presenters/stats_presenter.rb
164
167
  - lib/aoc_cli/processors/event_initialiser.rb
168
+ - lib/aoc_cli/processors/progress_syncer.rb
165
169
  - lib/aoc_cli/processors/puzzle_dir_synchroniser.rb
166
170
  - lib/aoc_cli/processors/puzzle_initialiser.rb
167
171
  - lib/aoc_cli/processors/puzzle_refresher.rb
@@ -215,6 +219,7 @@ files:
215
219
  - sig/aoc_cli/models/attempt.rbs
216
220
  - sig/aoc_cli/models/event.rbs
217
221
  - sig/aoc_cli/models/location.rbs
222
+ - sig/aoc_cli/models/progress.rbs
218
223
  - sig/aoc_cli/models/puzzle.rbs
219
224
  - sig/aoc_cli/models/puzzle_dir_sync_log.rbs
220
225
  - sig/aoc_cli/models/stats.rbs
@@ -222,6 +227,7 @@ files:
222
227
  - sig/aoc_cli/presenters/puzzle_presenter.rbs
223
228
  - sig/aoc_cli/presenters/stats_presenter.rbs
224
229
  - sig/aoc_cli/processors/event_initialiser.rbs
230
+ - sig/aoc_cli/processors/progress_syncer.rbs
225
231
  - sig/aoc_cli/processors/puzzle_dir_synchroniser.rbs
226
232
  - sig/aoc_cli/processors/puzzle_initialiser.rbs
227
233
  - sig/aoc_cli/processors/puzzle_refresher.rbs
@@ -249,6 +255,7 @@ post_install_message:
249
255
  rdoc_options: []
250
256
  require_paths:
251
257
  - lib
258
+ - db
252
259
  required_ruby_version: !ruby/object:Gem::Requirement
253
260
  requirements:
254
261
  - - ">="