card 1.108.1 → 1.109.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.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/environments/development.rb +1 -1
  4. data/config/environments/production.rb +5 -2
  5. data/config/initializers/01_core_extensions/array.rb +1 -0
  6. data/config/initializers/01_core_extensions/hash.rb +4 -0
  7. data/config/initializers/02_patches/active_record.rb +1 -1
  8. data/config/initializers/core_extensions.rb +0 -1
  9. data/config/initializers/deck_config.rb +3 -3
  10. data/config/initializers/patches.rb +6 -6
  11. data/config/locales/es.yml +2 -3
  12. data/db/seeds.rb +0 -1
  13. data/lib/card/auth/current.rb +8 -6
  14. data/lib/card/auth/permissions.rb +1 -1
  15. data/lib/card/auth/proxy.rb +2 -2
  16. data/lib/card/auth/setup.rb +2 -2
  17. data/lib/card/auth.rb +7 -6
  18. data/lib/card/cache/all.rb +1 -1
  19. data/lib/card/cache/class_methods.rb +2 -4
  20. data/lib/card/cache/shared.rb +1 -1
  21. data/lib/card/cache/temporary.rb +2 -2
  22. data/lib/card/codename.rb +1 -1
  23. data/lib/card/content/chunk/abstract.rb +1 -0
  24. data/lib/card/content/chunk.rb +0 -1
  25. data/lib/card/content/clean.rb +4 -2
  26. data/lib/card/content/diff/l_c_s.rb +1 -2
  27. data/lib/card/content/diff/result.rb +2 -1
  28. data/lib/card/content/diff.rb +2 -1
  29. data/lib/card/content/parser.rb +8 -7
  30. data/lib/card/content.rb +1 -1
  31. data/lib/card/director/subdirector_array.rb +1 -0
  32. data/lib/card/director.rb +1 -1
  33. data/lib/card/dirty/method_factory.rb +1 -0
  34. data/lib/card/env/location.rb +3 -3
  35. data/lib/card/env/location_history.rb +20 -20
  36. data/lib/card/env/success/target.rb +4 -4
  37. data/lib/card/env/support.rb +25 -2
  38. data/lib/card/error.rb +1 -0
  39. data/lib/card/fetch/store.rb +1 -1
  40. data/lib/card/format/error.rb +13 -2
  41. data/lib/card/format/method_delegation.rb +6 -4
  42. data/lib/card/format/registration.rb +5 -3
  43. data/lib/card/format/render.rb +51 -47
  44. data/lib/card/format/wrapper.rb +1 -0
  45. data/lib/card/lexicon.rb +5 -2
  46. data/lib/card/mailer.rb +1 -14
  47. data/lib/card/name/all/parts.rb +1 -1
  48. data/lib/card/name/all.rb +5 -0
  49. data/lib/card/name/name_variants.rb +1 -0
  50. data/lib/card/query/abstract_query/query_helper.rb +1 -2
  51. data/lib/card/query/abstract_query/tie.rb +1 -1
  52. data/lib/card/query/abstract_query.rb +3 -3
  53. data/lib/card/query/card_class.rb +1 -0
  54. data/lib/card/query/card_query/relational_attributes.rb +1 -1
  55. data/lib/card/query/card_query/run.rb +5 -1
  56. data/lib/card/query/clause.rb +1 -0
  57. data/lib/card/query/join.rb +3 -3
  58. data/lib/card/query/sql_statement.rb +7 -1
  59. data/lib/card/query.rb +1 -1
  60. data/lib/card/reference/all.rb +6 -7
  61. data/lib/card/rule/cache.rb +1 -0
  62. data/lib/card/rule/preference_cache.rb +2 -0
  63. data/lib/card/rule/read_rule_cache.rb +3 -0
  64. data/lib/card/set/event/all.rb +6 -4
  65. data/lib/card/set/event/callbacks.rb +1 -0
  66. data/lib/card/set/event/options.rb +3 -2
  67. data/lib/card/set/event/skip_and_trigger.rb +1 -1
  68. data/lib/card/set/event.rb +2 -2
  69. data/lib/card/set/format/abstract_format/view_definition.rb +1 -1
  70. data/lib/card/set/format/haml_paths.rb +1 -1
  71. data/lib/card/set/format.rb +4 -4
  72. data/lib/card/set/helpers.rb +4 -4
  73. data/lib/card/set/i18n_scanner.rb +23 -22
  74. data/lib/card/set/i18n_scope.rb +4 -3
  75. data/lib/card/set/pattern/all.rb +1 -1
  76. data/lib/card/set/pattern/base.rb +6 -3
  77. data/lib/card/set/pattern/class_methods.rb +1 -1
  78. data/lib/card/set/pattern.rb +1 -1
  79. data/lib/card/set/required_field.rb +3 -0
  80. data/lib/card/set/trait.rb +6 -1
  81. data/lib/card/subcards/all.rb +12 -4
  82. data/lib/card/view/cache/cache_action.rb +9 -3
  83. data/lib/card/view/cache.rb +17 -15
  84. data/lib/card/view/classy.rb +5 -5
  85. data/lib/card/view/options/key_lists.rb +1 -0
  86. data/lib/card/view/options/voo_api.rb +2 -2
  87. data/lib/card/view/options.rb +1 -0
  88. data/lib/card/view.rb +1 -1
  89. data/lib/cardio/command/application.rb +1 -1
  90. data/lib/cardio/command/custom.rb +7 -6
  91. data/lib/cardio/command/rake_command.rb +3 -2
  92. data/lib/cardio/command/rspec_command.rb +1 -0
  93. data/lib/cardio/generators/deck_generator_loader.rb +1 -1
  94. data/lib/cardio/generators.rb +4 -3
  95. data/lib/cardio/migration/port.rb +2 -0
  96. data/lib/cardio/migration/stamp.rb +1 -0
  97. data/lib/cardio/migration/transform.rb +1 -0
  98. data/lib/cardio/migration.rb +2 -0
  99. data/lib/cardio/mod/class_methods.rb +1 -2
  100. data/lib/cardio/mod/dirs.rb +2 -4
  101. data/lib/cardio/mod/eat/edibles.rb +8 -6
  102. data/lib/cardio/mod/eat.rb +7 -9
  103. data/lib/cardio/mod/load_strategy/set_binding_magic.rb +1 -1
  104. data/lib/cardio/mod/load_strategy/tmp_files.rb +3 -2
  105. data/lib/cardio/mod/load_strategy.rb +1 -0
  106. data/lib/cardio/mod/loader/set_pattern_loader.rb +4 -0
  107. data/lib/cardio/mod/loader/set_template.rb +14 -4
  108. data/lib/cardio/mod/loader.rb +2 -2
  109. data/lib/cardio/mod/sow/card_source.rb +1 -1
  110. data/lib/cardio/mod/sow/remote_source.rb +32 -0
  111. data/lib/cardio/mod/sow.rb +10 -10
  112. data/lib/cardio/railtie.rb +1 -0
  113. data/lib/cardio/script_loader.rb +1 -1
  114. data/lib/cardio/seed.rb +2 -2
  115. data/lib/cardio/utils.rb +1 -1
  116. data/lib/cardio/version.rb +2 -1
  117. data/lib/cardio.rb +3 -0
  118. data/lib/generators/deck/templates/config.ru.erb +1 -1
  119. data/mod/core/config/locales/de.yml +1 -1
  120. data/mod/core/config/locales/en.yml +2 -1
  121. data/mod/core/data/fixtures/real/cards.yml +1 -1
  122. data/mod/core/data/real.yml +1 -1
  123. data/mod/core/data/recode.yml +1 -0
  124. data/mod/core/data/schema/20141001105348_move_revisions_to_actions.rb +2 -2
  125. data/mod/core/data/schema/20241017160402_unique_codename.rb +8 -0
  126. data/mod/core/data/transform/20150724123438_update_file_and_image_cards.rb +1 -1
  127. data/mod/core/lib/tasks/card/export.rake +28 -0
  128. data/mod/core/lib/tasks/card/migrate.rake +3 -3
  129. data/mod/core/lib/tasks/card/mod.rake +1 -1
  130. data/mod/core/lib/tasks/card/seed.rake +2 -1
  131. data/mod/core/lib/tasks/card.rake +48 -16
  132. data/mod/core/set/all/admin.rb +1 -2
  133. data/mod/core/set/all/assign_attributes.rb +3 -2
  134. data/mod/core/set/all/codename.rb +7 -1
  135. data/mod/core/set/all/debug.rb +3 -3
  136. data/mod/core/set/all/initialize.rb +1 -0
  137. data/mod/core/set/all/states.rb +13 -16
  138. data/mod/core/set/all/type.rb +3 -1
  139. data/mod/core/set/all/utils.rb +0 -1
  140. data/mod/core/set/self/admin.rb +2 -1
  141. data/mod/core/set/self/autoname.rb +1 -1
  142. data/mod/core/set/self/mod.rb +4 -4
  143. data/mod/core/set/self/trash.rb +1 -1
  144. data/mod/core/set/type/mod.rb +18 -15
  145. data/mod/core/set_pattern/09_self.rb +4 -0
  146. data/mod/core/spec/set/all/admin_spec.rb +1 -1
  147. data/mod/core/spec/set/all/trash_spec.rb +9 -9
  148. metadata +42 -29
@@ -19,13 +19,13 @@ module Cardio
19
19
  @verbose = !verbose.nil?
20
20
  end
21
21
 
22
- def up
22
+ def run
23
23
  handle_up do
24
24
  edibles.each do |edible|
25
25
  track edible do
26
26
  current_user edible.delete(:user)
27
27
  time_machine edible.delete(:time) do
28
- Card.ensure edible
28
+ Card.ensure! edible
29
29
  end
30
30
  end
31
31
  end
@@ -35,10 +35,10 @@ module Cardio
35
35
  private
36
36
 
37
37
  # if output mod given,
38
- def handle_up
38
+ def handle_up &block
39
39
  Card::Cache.reset_all
40
40
  Card::Mailer.perform_deliveries = false
41
- Card::Auth.as_bot { yield }
41
+ Card::Auth.as_bot(&block)
42
42
  :success
43
43
  rescue StandardError => e
44
44
  e.message
@@ -46,9 +46,6 @@ module Cardio
46
46
 
47
47
  def track edible
48
48
  rescuing edible do
49
- # n = edible[:name]
50
- # binding.pry if (n.is_a? Array) && n.first.to_s == "main_menu"
51
- # puts "eating: #{edible}" if @verbose
52
49
  card = yield
53
50
  puts "eaten: #{card.name}".cyan if @verbose
54
51
  end
@@ -63,7 +60,7 @@ module Cardio
63
60
  end
64
61
 
65
62
  def current_user item_user
66
- Card::Auth.current_id = item_user&.card_id || @user_id || Card::WagnBotID
63
+ Card::Auth.current_id = item_user&.card_id || @user_id || Card::DeckoBotID
67
64
  end
68
65
 
69
66
  def time_machine value, &block
@@ -76,7 +73,8 @@ module Cardio
76
73
  case value
77
74
  when /^[+-]\d+$/
78
75
  # plus or minus an integer (safe to eval)
79
- eval "#{Time.now.to_i} #{value}", binding, __FILE__, __LINE__
76
+ eval "#{Time.now.to_i} #{value}", # 1741296981 +1 (e.g.)
77
+ binding, __FILE__, __LINE__ - 1
80
78
  when Integer
81
79
  value
82
80
  else
@@ -39,7 +39,7 @@ module Cardio
39
39
  mod.name.split("::").each do |part|
40
40
  m, b =
41
41
  eval(
42
- "[ #{part} , #{part}.module_eval('binding') ]",
42
+ "[ #{part} , #{part}.module_eval('binding') ]", # [ History , History.module_eval('binding') ]
43
43
  b
44
44
  )
45
45
  end
@@ -24,9 +24,10 @@ module Cardio
24
24
  end
25
25
 
26
26
  def rewrite_tmp_files?
27
- return @rewrite if defined? @rewrite
27
+ return @rewrite_tmp_files if defined? @rewrite_tmp_files
28
28
 
29
- @rewrite = !(Rails.env.production? && Card.paths["tmp/set"].existent.first)
29
+ @rewrite_tmp_files =
30
+ !(Rails.env.production? && Card.paths["tmp/set"].existent.first)
30
31
  end
31
32
 
32
33
  def write_tmp_file from_file, to_file, const_parts
@@ -33,6 +33,7 @@ module Cardio
33
33
  end
34
34
 
35
35
  attr_reader :loader
36
+
36
37
  delegate :template_class, :pattern_groups, :each_file, :mod_dirs, :parts_from_path,
37
38
  to: :loader
38
39
 
@@ -1,6 +1,9 @@
1
1
  module Cardio
2
2
  class Mod
3
3
  class Loader
4
+ # arguably overkill, the set pattern loader makes set patterns use
5
+ # directory/file-aware loading much as set patterns do. Since they are so
6
+ # rarely added, this optimization should probably be deprecated
4
7
  class SetPatternLoader < Loader
5
8
  def template_class
6
9
  SetPatternTemplate
@@ -17,6 +20,7 @@ module Cardio
17
20
  end
18
21
  end
19
22
 
23
+ # templates for set pattern modules
20
24
  class SetPatternTemplate < ModuleTemplate
21
25
  def to_const
22
26
  return Object if simple_load?
@@ -28,9 +28,9 @@ module Cardio
28
28
  format_name = Regexp.last_match(1)
29
29
  format_name = format_name.blank? ? nil : format_name.to_sym
30
30
  "module #{module_name format_name}; " \
31
- "module_parent.send :register_set_format, "\
32
- "#{format_class format_name}, self; "\
33
- "extend Card::Set::AbstractFormat"
31
+ "module_parent.send :register_set_format, " \
32
+ "#{format_class format_name}, self; " \
33
+ "extend Card::Set::AbstractFormat"
34
34
  end
35
35
  end
36
36
 
@@ -92,7 +92,7 @@ module Cardio
92
92
  def pattern_label *anchors
93
93
  anchor_count = pattern_class.anchor_parts_count
94
94
  label = pattern_class.label(pattern_anchor(*anchors, anchor_count))
95
- remainder = anchors[anchor_count..-1]
95
+ remainder = anchors[anchor_count..]
96
96
  label += " (#{remainder.join ', '})" if remainder.any?
97
97
  label
98
98
  end
@@ -125,6 +125,16 @@ module Cardio
125
125
  def postamble
126
126
  "end;" * (@modules.size + 3)
127
127
  end
128
+
129
+ # [set_registration, ends].compact.join "\n"
130
+ # end
131
+ #
132
+ # def set_registration
133
+ # "Card::Set.register_set self" unless helper_module?
134
+ # end
135
+ #
136
+ # def ends
137
+ # end
128
138
  end
129
139
  end
130
140
  end
@@ -28,7 +28,7 @@ module Cardio
28
28
  end
29
29
 
30
30
  def load_initializers
31
- Cardio.config.paths["late/initializers"].existent.sort.each do |init|
31
+ Cardio.config.paths["late/initializers"].existent.each do |init|
32
32
  load init
33
33
  end
34
34
  end
@@ -60,7 +60,7 @@ module Cardio
60
60
 
61
61
  def parts_from_path path
62
62
  # remove file extension and number prefixes
63
- parts = path.gsub(/\.rb/, "").gsub(%r{(?<=\A|/)\d+_}, "").split(File::SEPARATOR)
63
+ parts = path.gsub(/\.rb$/, "").gsub(%r{(?<=\A|/)\d+_}, "").split(File::SEPARATOR)
64
64
  parts.map(&:camelize)
65
65
  end
66
66
 
@@ -1,7 +1,7 @@
1
1
  module Cardio
2
2
  class Mod
3
3
  class Sow
4
- # Fetch sow data form cards
4
+ # Fetch sow data from cards
5
5
  module CardSource
6
6
  def new_data_from_cards
7
7
  cards.map { |c| c.pod_hash field_tags: field_tag_marks }
@@ -0,0 +1,32 @@
1
+ module Cardio
2
+ class Mod
3
+ class Sow
4
+ # Fetch sow data from remote
5
+ module RemoteSource
6
+ def remote_source
7
+ @remote_source ||=
8
+ if @remote
9
+ raise Card::Error::NotFound, "must specify name (-n)" unless @name
10
+
11
+ URI.join(@remote, "/#{@name.cardname.url_key}/", "pod.yml")
12
+ else
13
+ @url
14
+ end
15
+ end
16
+
17
+ def pod_from_url
18
+ parsed_yaml = parse_pod_yaml yaml_from_url
19
+ Array.wrap(parsed_yaml)
20
+ rescue Psych::SyntaxError
21
+ raise "Url #{@remote_source} provided invalid yaml"
22
+ end
23
+
24
+ def yaml_from_url
25
+ @yaml_from_url ||= URI.open(@remote_source).read
26
+ rescue OpenURI::HTTPError => e
27
+ raise "#{@remote_source} not available\n#{e}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -7,25 +7,25 @@ module Cardio
7
7
  class Sow
8
8
  include YamlDump
9
9
  include CardSource
10
+ include RemoteSource
10
11
 
11
12
  def initialize **args
12
13
  @mod = args[:mod]
13
14
  @name = args[:name]
14
15
  @cql = args[:cql]
15
16
  @url = args[:url]
17
+ @remote = args[:remote]
16
18
  @podtype = args[:podtype] || (Rails.env.test? ? :test : :real)
17
19
  @items = args[:items]
18
20
  @field_tags = args[:field_tags]
19
21
  end
20
22
 
21
23
  # if output mod given,
22
- def out
24
+ def run
23
25
  Card::Cache.reset_all
24
26
  @mod ? dump(output_hash) : puts(new_data.to_yaml.yellow)
25
27
  :success
26
- rescue Card::Error::NotFound => e
27
- e.message
28
- rescue JSON::ParserError => e
28
+ rescue Card::Error::NotFound, JSON::ParserError => e
29
29
  e.message
30
30
  end
31
31
 
@@ -42,8 +42,11 @@ module Cardio
42
42
 
43
43
  # @return [Array <Hash>]
44
44
  def new_data
45
- @new_data ||=
46
- @url ? pod_hash_from_url : new_data_from_cards
45
+ @new_data ||= fetch_new_data
46
+ end
47
+
48
+ def fetch_new_data
49
+ remote_source ? pod_from_url : new_data_from_cards
47
50
  end
48
51
 
49
52
  def merge_data
@@ -72,11 +75,8 @@ module Cardio
72
75
 
73
76
  def old_data
74
77
  return unless File.exist? filename
75
- parse_pod_yaml File.read(filename)
76
- end
77
78
 
78
- def pod_hash_from_url
79
- parse_pod_yaml URI.open(@url).read
79
+ parse_pod_yaml File.read(filename)
80
80
  end
81
81
 
82
82
  def parse_pod_yaml pod_yaml
@@ -38,6 +38,7 @@ module Cardio
38
38
  config.raise_all_rendering_errors = false
39
39
 
40
40
  config.cache_set_module_list = false
41
+ config.max_temporary_cache_keys = 10_000
41
42
 
42
43
  config.i18n.enforce_available_locales = true
43
44
  config.read_only = !ENV["DECKO_READ_ONLY"].nil?
@@ -46,7 +46,7 @@ module Cardio
46
46
 
47
47
  def in_application_subdirectory? path=Pathname.new(Dir.pwd)
48
48
  File.exist?(File.join(path, script)) ||
49
- !path.root? && in_application_subdirectory?(path.parent)
49
+ (!path.root? && in_application_subdirectory?(path.parent))
50
50
  end
51
51
  end
52
52
 
data/lib/cardio/seed.rb CHANGED
@@ -64,7 +64,7 @@ module Cardio
64
64
 
65
65
  def write_seed_file table
66
66
  filename = File.join default_path, "#{table}.yml"
67
- File.open(filename, "w") { |file| file.write yield }
67
+ File.write(filename, yield)
68
68
  end
69
69
 
70
70
  def yamlize_records table
@@ -104,7 +104,7 @@ module Cardio
104
104
  end
105
105
 
106
106
  def author_id
107
- Card::WagnBotID
107
+ Card::DeckoBotID
108
108
  end
109
109
  end
110
110
  end
data/lib/cardio/utils.rb CHANGED
@@ -58,7 +58,7 @@ module Cardio
58
58
 
59
59
  def all_file_ids
60
60
  dir = Card.paths["files"].existent.first
61
- Dir.entries(dir)[2..-1].map(&:to_i)
61
+ Dir.entries(dir)[2..].map(&:to_i)
62
62
  end
63
63
 
64
64
  def all_trashed_card_ids
@@ -1,12 +1,13 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  module Cardio
4
+ # handle version numbers for releases
4
5
  module Version
5
6
  class << self
6
7
  CARD_MINOR = { 0 => 90, 1 => 1000 }.freeze # can remove and hardcode after 1.0
7
8
 
8
9
  def release
9
- @version ||= File.read(File.expand_path("../../VERSION", __dir__)).strip
10
+ @release ||= File.read(File.expand_path("../../VERSION", __dir__)).strip
10
11
  end
11
12
 
12
13
  def card_release
data/lib/cardio.rb CHANGED
@@ -8,6 +8,9 @@ ActiveSupport.on_load :after_card do
8
8
  Cardio::Mod.load
9
9
  end
10
10
 
11
+ # Cardio is a quick loading module and is at the heart (get it?) of
12
+ # card loading and configuration because it is useful long before the Card class is
13
+ # (or card objects are)
11
14
  module Cardio
12
15
  extend Delaying
13
16
 
@@ -8,4 +8,4 @@ if Rails.env.profile?
8
8
  end
9
9
 
10
10
  <% end -%>
11
- run <%= app_const %>
11
+ run Cardio.application.class
@@ -8,7 +8,7 @@ de:
8
8
  core_error_cant_alter: Typ kann nicht geändert werden; es gibt noch %{name} Karten
9
9
  core_error_cant_change_errors: "von %{name} kann nicht geändert werden; Fehler beim Erstellen von neuen %{type_id}: %{error_messages}"
10
10
  core_error_code_in_use: Codename %{codename} ist bereits vergeben
11
- core_error_hard_templated: kann nicht geändert werden, weil %{name} ist eine Vorlage für %{type_name}
11
+ core_error_structured: kann nicht geändert werden, weil %{name} ist eine Vorlage für %{type_name}
12
12
  core_error_indestructible: "%{name} ist eine unzerstörbare Regel"
13
13
  core_error_invalid_character_in_cardtype: "folgende Zeichen sind nicht erlaubt: %{banned}"
14
14
  core_error_name_exists: muss eindeutig sein; '%{name}' gibt es bereits.
@@ -8,7 +8,8 @@ en:
8
8
  core_error_cant_alter: can't alter this type; %{name} cards still exist
9
9
  core_error_cant_change_errors: "of %{name} can't be changed; errors creating new %{type_id}: %{error_messages}"
10
10
  core_error_code_in_use: codename %{codename} already in use
11
- core_error_hard_templated: can't be changed because %{name} is hard templated to %{type_name}
11
+ core_codename_must_be_simple: only simple cards can have codenames
12
+ core_error_structured: can't be changed because %{name} is structured as a %{type_name}
12
13
  core_error_indestructible: "%{name} is an indestructible rule"
13
14
  core_error_invalid_character_in_cardtype: "may not contain any of the following characters: %{banned}"
14
15
  core_error_name_exists: must be unique; '%{name}' already exists.
@@ -3,7 +3,7 @@ cards_001:
3
3
  id: 1
4
4
  name: Decko Bot
5
5
  key: decko_bot
6
- codename: wagn_bot
6
+ codename: decko_bot
7
7
  creator_id: 1
8
8
  updater_id: 1
9
9
  read_rule_class: "*all"
@@ -16,7 +16,7 @@
16
16
  [[http://decko.org/card_types|more]]
17
17
  </p>
18
18
  - :name: Decko Bot
19
- :codename: wagn_bot
19
+ :codename: decko_bot
20
20
  :content: |-
21
21
  <p>
22
22
  This is the account that makes any automated updates &mdash; cards
@@ -5,3 +5,4 @@ input: input_type
5
5
  options: content_options
6
6
  options_label: content_option_view
7
7
  token: api_key
8
+ wagn_bot: decko_bot
@@ -3,7 +3,7 @@ class MoveRevisionsToActions < Cardio::Migration::Schema
3
3
  belongs_to :tmp_card, foreign_key: :card_id
4
4
  self.table_name = "card_revisions"
5
5
  def self.delete_cardless
6
- left_join = "LEFT JOIN cards "\
6
+ left_join = "LEFT JOIN cards " \
7
7
  "ON card_revisions.card_id = cards.id"
8
8
  TmpRevision.joins(left_join).where("cards.id IS NULL").delete_all
9
9
  end
@@ -55,7 +55,7 @@ class MoveRevisionsToActions < Cardio::Migration::Schema
55
55
 
56
56
  def create_create_action rev
57
57
  TmpAction.connection.execute(
58
- "INSERT INTO card_actions (id, card_id, card_act_id, action_type) VALUES "\
58
+ "INSERT INTO card_actions (id, card_id, card_act_id, action_type) VALUES " \
59
59
  "('#{rev.id}', '#{rev.card_id}', '#{rev.id}', 0)")
60
60
  if (tmp_card = rev.tmp_card)
61
61
  TmpChange.connection.execute "INSERT INTO card_changes (card_action_id, field, value) VALUES
@@ -2,6 +2,7 @@
2
2
 
3
3
  class UniqueCodename < Cardio::Migration::Schema
4
4
  def up
5
+ remove_blank_codenames
5
6
  remove_index :cards, name: "cards_codename_index"
6
7
  add_index :cards, :codename, name: "cards_codename_index", unique: true
7
8
  end
@@ -10,4 +11,11 @@ class UniqueCodename < Cardio::Migration::Schema
10
11
  remove_index :cards, name: "cards_codename_index"
11
12
  add_index :cards, :codename, name: "cards_codename_index"
12
13
  end
14
+
15
+ private
16
+
17
+ def remove_blank_codenames
18
+ Cardio::Record.connection
19
+ .execute "UPDATE cards SET codename = null where codename = ''"
20
+ end
13
21
  end
@@ -88,7 +88,7 @@ class UpdateFileAndImageCards < Cardio::Migration::Transform
88
88
  def get_new_file_name filename
89
89
  original_filename = filename
90
90
  if filename =~ /^(icon|small|medium|large|original)-([^.]+).(.+)$/
91
- filename = "#{Regexp.last_match(2)}-#{Regexp.last_match(1)}."\
91
+ filename = "#{Regexp.last_match(2)}-#{Regexp.last_match(1)}." \
92
92
  "#{Regexp.last_match(3)}"
93
93
  end
94
94
  filename = filename.downcase
@@ -0,0 +1,28 @@
1
+ require "csv"
2
+
3
+ namespace :card do
4
+ namespace :export do
5
+ desc "export all cards to csv"
6
+ task csv: :environment do
7
+ parse_options :csv do
8
+ add_opt :f, :file, "file name"
9
+ end
10
+ filename = options[:file] || "cards.csv"
11
+ puts "Exporting all card data to #{filename}..."
12
+ File.write(filename) { |f| f.write to_csv }
13
+ end
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def to_csv
20
+ attributes = %w[id name codename type content]
21
+
22
+ CSV.generate(headers: true) do |csv|
23
+ csv << attributes
24
+ Card.all.each do |card|
25
+ csv << attributes.map { |attr| card.send(attr) }
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  namespace :card do
3
2
  desc "migrate structure and cards"
4
3
  task migrate: :environment do
@@ -47,6 +46,7 @@ namespace :card do
47
46
 
48
47
  task port: :environment do
49
48
  puts "porting"
49
+ ENV["NO_CARD_LOAD"] = "true"
50
50
  Cardio::Migration.port_all
51
51
  end
52
52
 
@@ -60,7 +60,7 @@ namespace :card do
60
60
  end
61
61
 
62
62
  def version
63
- ENV["VERSION"] ? ENV["VERSION"].to_i : nil
63
+ ENV["VERSION"]&.to_i
64
64
  end
65
65
  end
66
66
  end
@@ -109,7 +109,7 @@ end
109
109
  # FIXME: too general
110
110
  # intent is to find Record classes; this gets a lot more.
111
111
  def load_mod_lib
112
- Dir.glob(Cardio.root.join("mod/*/lib/*.rb")).sort.each { |x| require x }
112
+ Dir.glob(Cardio.root.join("mod/*/lib/*.rb")).each { |x| require x }
113
113
  end
114
114
 
115
115
  def without_dumping
@@ -30,7 +30,7 @@ namespace :card do
30
30
  desc "install all mods"
31
31
  task install: :environment do
32
32
  puts "installing mods"
33
- Card::Auth.signin :wagn_bot.card
33
+ Card::Auth.signin :decko_bot.card
34
34
  # Cardio.config.compress_assets = true # should not be here, imo #efm
35
35
  Cardio::Mod.ensure_installed
36
36
  end
@@ -34,6 +34,7 @@ namespace :card do
34
34
 
35
35
  # desc "dump db to fixtures"
36
36
  task dump: :environment do
37
+ puts "dumping".green
37
38
  Card::Cache.reset_all
38
39
  Cardio::Seed.dump
39
40
  end
@@ -54,7 +55,7 @@ namespace :card do
54
55
  end
55
56
 
56
57
  def invoke_card_task task
57
- puts "invoking: #{task}".green
58
+ puts "invoking: #{task}"
58
59
  Rake::Task["card:#{task}"].invoke
59
60
  end
60
61
  end
@@ -11,9 +11,25 @@ namespace :card do
11
11
  task :update do
12
12
  failing_loudly "decko update" do
13
13
  ENV["NO_RAILS_CACHE"] = "true"
14
- # Benchmark.bm do |x|
15
- ["migrate:port", "migrate:schema", "migrate:recode", :eat, "migrate:transform",
16
- "mod:uninstall", "mod:install", "mod:symlink", :reset].each do |task|
14
+ run_tasks ["migrate:port", "migrate:schema", "migrate:recode",
15
+ :eat, "migrate:transform",
16
+ "mod:uninstall", "mod:install", "mod:symlink", :reset]
17
+ # , with_benchmark: true
18
+ end
19
+ end
20
+
21
+ def run_tasks tasks, with_benchmark: false
22
+ if with_benchmark
23
+ require "benchmark"
24
+ Benchmark.bm do |x|
25
+ x.report("total") do
26
+ tasks.each do |task|
27
+ x.report(task) { Rake::Task["card:#{task}"].invoke }
28
+ end
29
+ end
30
+ end
31
+ else
32
+ tasks.each do |task|
17
33
  Rake::Task["card:#{task}"].invoke
18
34
  end
19
35
  end
@@ -21,8 +37,7 @@ namespace :card do
21
37
 
22
38
  desc "Ingests card data from mod yaml"
23
39
  task eat: :environment do
24
- puts "eating"
25
- parse_options :eat do
40
+ run_with_options :eat, Cardio::Mod::Eat, "eating" do
26
41
  add_opt :m, :mod, "only eat cards in given mod"
27
42
  add_opt :n, :name, "only eat card with name (handles : for codenames)"
28
43
  add_opt :u, :user, "user to credit unless specified (default is Decko Bot)"
@@ -31,26 +46,46 @@ namespace :card do
31
46
  add_opt :e, :env, "environment (test, production, etc)"
32
47
  flag_opt :v, :verbose, "output progress info and error backtraces"
33
48
  end
49
+ end
34
50
 
35
- adjust_environment options, :eat do
36
- rake_result(:eat) { Cardio::Mod::Eat.new(**options).up }
37
- end
51
+ def args_without_env_arg
52
+ env_index = ARGV.find_index { |entry| %w[-e --env].include?(entry) }
53
+ args =
54
+ if env_index
55
+ ARGV[1..].select.with_index do |_, index|
56
+ (index != env_index - 1) && (index != env_index)
57
+ end
58
+ else
59
+ ARGV[1..]
60
+ end
61
+ args&.join " "
38
62
  end
39
63
 
40
- def adjust_environment options, task
64
+ def adjust_environment options, args_without_env, task, task_message
41
65
  if (env = options.delete(:env))
42
- task_options = options.map { |k, v| "--#{k}=#{v}" }.join(" ")
43
- system "env RAILS_ENV=#{env} bundle exec rake card:#{task} #{task_options}"
66
+ command = "env RAILS_ENV=#{env} bundle exec rake card:#{task} #{args_without_env}"
67
+ puts command.yellow
68
+ success = system command
69
+ exit success # to avoid that rake tries to run the arguments as rake tasks
44
70
  else
71
+ puts task_message
45
72
  yield
46
73
  end
47
74
  end
48
75
 
76
+ def run_with_options task_name, task_class, start_message, &block
77
+ args_without_env = args_without_env_arg
78
+ parse_options task_name, &block
79
+ adjust_environment options, args_without_env, task_name, start_message do
80
+ rake_result(task_name) { task_class.new(**options).run }
81
+ end
82
+ end
83
+
49
84
  desc "Exports card data to mod yaml"
50
85
  task sow: :environment do
51
- puts "sowing"
52
- parse_options :sow do
86
+ run_with_options :sow, Cardio::Mod::Sow, "sowing" do
53
87
  add_opt :n, :name, "export card with name/mark (handles : and ~ prefixes)"
88
+ add_opt :r, :remote, "export card from remote deck (with -n)"
54
89
  flag_opt :i, :items, "also export card items (with -n)"
55
90
  flag_opt :o, :only_items, "only export card items (with -n)", items: :only
56
91
  add_opt :c, :cql, "export cards found by CQL (in JSON format)"
@@ -60,9 +95,6 @@ namespace :card do
60
95
  add_opt :t, :field_tags, "comma-separated list of field tag marks"
61
96
  add_opt :e, :env, "environment (test, production, etc)"
62
97
  end
63
- adjust_environment options, :sow do
64
- rake_result(:sow) { Cardio::Mod::Sow.new(**options).out }
65
- end
66
98
  end
67
99
 
68
100
  desc "Clears both cache and tmpfiles"
@@ -1,4 +1,3 @@
1
-
2
1
  basket[:tasks] = {}
3
2
  basket[:config_title] = {
4
3
  basic: "Basic configuration",
@@ -59,7 +58,7 @@ def all_admin_configs_of_category category
59
58
  end
60
59
 
61
60
  def config_codenames_grouped_by_title configs
62
- configs&.group_by { |c| c.title }&.map do |title, grouped_configs|
61
+ configs&.group_by(&:title)&.map do |title, grouped_configs|
63
62
  [title, grouped_configs.map { |config| config.codename.to_sym }]
64
63
  end
65
64
  end