card 1.106.0 → 1.107.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 +4 -4
- data/VERSION +1 -1
- data/config/environments/development.rb +0 -3
- data/config/environments/production.rb +0 -3
- data/config/environments/test.rb +0 -2
- data/lib/card/auth/current.rb +1 -1
- data/lib/card/auth/permissions.rb +1 -9
- data/lib/card/fetch/all.rb +1 -1
- data/lib/card/query/abstract_query/tie.rb +2 -2
- data/lib/card/view/permission.rb +1 -1
- data/lib/cardio/command/rspec_command/parser.rb +1 -9
- data/lib/cardio/command.rb +1 -0
- data/lib/cardio/migration.rb +6 -1
- data/lib/cardio/mod/dirs.rb +6 -5
- data/lib/cardio/mod/eat/edibles.rb +1 -1
- data/lib/cardio/mod/sow/card_source.rb +48 -0
- data/lib/cardio/mod/sow/yaml_dump.rb +25 -0
- data/lib/cardio/mod/sow.rb +22 -64
- data/lib/cardio/mod.rb +3 -2
- data/lib/cardio/railtie.rb +0 -1
- data/lib/generators/deck/templates/cypress.json.erb +1 -1
- data/mod/core/config/admin.yml +10 -0
- data/mod/core/data/real.yml +0 -1
- data/mod/core/data/transform/20141204061304_watchers_to_following.rb +1 -1
- data/mod/core/lib/admin_item.rb +21 -0
- data/mod/core/lib/tasks/card/seed.rake +1 -1
- data/mod/core/lib/tasks/card.rake +56 -25
- data/mod/core/set/abstract/task_table.rb +16 -0
- data/mod/core/set/all/admin.rb +108 -0
- data/mod/core/set/self/admin.rb +3 -12
- data/mod/core/set/self/mod.rb +39 -0
- data/mod/core/set/self/version.rb +1 -1
- data/mod/core/set/type/mod.rb +227 -0
- data/mod/core/spec/set/all/admin_spec.rb +34 -0
- data/mod/core/spec/set/type/mod_spec.rb +30 -0
- data/mod/core/spec/shared_examples/mod_admin_config.rb +10 -0
- metadata +16 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df537d34eb8d348b41930c7ce3e6de5ed600b4d7e8df87ba2d935b2e259ae8e6
|
4
|
+
data.tar.gz: e108f9e1f0833c0aac0248c6ec59bf41c18aef70e09e42ea8bd364f94705fe7c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec38c34b70331bf7a919963b7337682e1456286ec5007db1d6d5408f270bb326bb6c55cd2c8af455bb7ed2794d8bd7ae1012dc3eb741d89ba2ce575a63c804bd
|
7
|
+
data.tar.gz: 901b1dc8198578fac3b59040919c02520b177ff8e240c4cebb0a1adb6c978054491b62aa4cc44a3a3514b114645b914a23515ffb36d71ab39b36054fe31c7cd7
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.17.0
|
@@ -38,9 +38,6 @@ Cardio.application.class.configure do
|
|
38
38
|
# in the nest where the error occurred
|
39
39
|
config.raise_all_rendering_errors = true
|
40
40
|
|
41
|
-
# if false, application will raise errors that make it to controller.
|
42
|
-
config.rescue_all_in_controller = false
|
43
|
-
|
44
41
|
# config.performance_logger = {
|
45
42
|
# methods: [:event, :search, :fetch, :view], # choose methods to log
|
46
43
|
# min_time: 100, # show only method calls that are slower than 100ms
|
data/config/environments/test.rb
CHANGED
data/lib/card/auth/current.rb
CHANGED
@@ -34,15 +34,7 @@ class Card
|
|
34
34
|
# @param user_mark [Cardish]
|
35
35
|
# @return [true/false]
|
36
36
|
def admin? user_mark=nil
|
37
|
-
user_mark
|
38
|
-
has_role? Card::AdministratorID, user_mark
|
39
|
-
end
|
40
|
-
|
41
|
-
def has_role? role_mark, user_mark=nil
|
42
|
-
user_mark ||= as_id
|
43
|
-
return false unless (role_id = role_mark&.card_id)
|
44
|
-
|
45
|
-
Card[user_mark].all_enabled_roles.include? role_id
|
37
|
+
(user_mark || as_id).card&.admin?
|
46
38
|
end
|
47
39
|
|
48
40
|
def update_always_cache value
|
data/lib/card/fetch/all.rb
CHANGED
@@ -2,9 +2,9 @@ class Card
|
|
2
2
|
module Query
|
3
3
|
class AbstractQuery
|
4
4
|
# The "Tie" methods support tying two queries (CardQuery, ReferenceQuery, etc)
|
5
|
-
# together. The "
|
5
|
+
# together. The "subquery_type" variable determines which tying strategy is used.
|
6
6
|
#
|
7
|
-
# We currently support three values for "
|
7
|
+
# We currently support three values for "subquery_type": :join, :exist, and :in
|
8
8
|
#
|
9
9
|
# In concept, here's how the different strategies would tie table A to table B
|
10
10
|
# in SQL assuming A.id = B.a_id
|
data/lib/card/view/permission.rb
CHANGED
@@ -24,12 +24,10 @@ module Cardio
|
|
24
24
|
|
25
25
|
RSPEC ARGS
|
26
26
|
|
27
|
-
See https://
|
27
|
+
See https://rspec.info/features/3-12/rspec-core/command-line/ or run card rspec -- -hbe
|
28
28
|
BANNER
|
29
29
|
|
30
30
|
DESC = {
|
31
|
-
d: "Run spec for a Decko deck file",
|
32
|
-
c: "Run spec for a Decko core file",
|
33
31
|
m: "Run all specs for a mod or matching a mod"
|
34
32
|
}.freeze
|
35
33
|
|
@@ -47,15 +45,9 @@ module Cardio
|
|
47
45
|
private
|
48
46
|
|
49
47
|
def file_options parser, opts
|
50
|
-
parser.on("-d", "--spec FILENAME(:LINE)", DESC[:d]) do |file|
|
51
|
-
opts[:files] = find_spec_file(file, "#{Decko.root}/mod")
|
52
|
-
end
|
53
48
|
parser.on("-m", "--mod MODNAME", DESC[:m]) do |file|
|
54
49
|
opts[:files] = find_mod_file(file, Cardio.gem_root)
|
55
50
|
end
|
56
|
-
parser.on("-c", "--core-spec FILENAME(:LINE)", DESC[:c]) do |file|
|
57
|
-
opts[:files] = find_spec_file(file, Cardio.gem_root)
|
58
|
-
end
|
59
51
|
end
|
60
52
|
|
61
53
|
def other_options parser, opts
|
data/lib/cardio/command.rb
CHANGED
@@ -38,6 +38,7 @@ module Cardio
|
|
38
38
|
runner: { desc: "run code in app environment", group: :monkey, alias: :r },
|
39
39
|
rspec: { desc: "run rspec tests", group: :monkey, alias: :rs, via: :call },
|
40
40
|
generate: { desc: "generate templated code", group: :monkey, alias: :g },
|
41
|
+
reset: { desc: "reset cache and tmpfiles", group: :monkey, via: :rake },
|
41
42
|
sow: { desc: "export card data to mod yaml", group: :monkey, via: :rake },
|
42
43
|
eat: { desc: "ingest card data from mod yaml", group: :monkey, via: :rake }
|
43
44
|
}
|
data/lib/cardio/migration.rb
CHANGED
@@ -25,12 +25,17 @@ module Cardio
|
|
25
25
|
def port
|
26
26
|
return unless connection.table_exists? old_deck_table
|
27
27
|
rename_old_tables
|
28
|
-
connection.execute "INSERT INTO #{table} (
|
28
|
+
connection.execute "INSERT INTO #{table} (#{select_nonduplicate_versions})"
|
29
29
|
connection.drop_table old_deck_table
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
+
def select_nonduplicate_versions
|
35
|
+
"SELECT * FROM #{old_deck_table} o WHERE NOT EXISTS " \
|
36
|
+
"(SELECT * FROM #{table} n WHERE o.version = n.version)"
|
37
|
+
end
|
38
|
+
|
34
39
|
def rename_old_tables
|
35
40
|
old_tables.each do |old_table_name|
|
36
41
|
next unless connection.table_exists? old_table_name
|
data/lib/cardio/mod/dirs.rb
CHANGED
@@ -63,7 +63,7 @@ module Cardio
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# Add a mod to mod load paths
|
66
|
-
def add_mod mod_name, path: nil, group: nil
|
66
|
+
def add_mod mod_name, path: nil, group: nil, spec: nil
|
67
67
|
if @mods_by_name.key? Mod.normalize_name(mod_name)
|
68
68
|
raise StandardError,
|
69
69
|
"name conflict: mod with name \"#{mod_name}\" already loaded"
|
@@ -72,7 +72,7 @@ module Cardio
|
|
72
72
|
path ||= File.join @current_path, mod_name
|
73
73
|
group ||= @current_group
|
74
74
|
|
75
|
-
mod = Mod.new mod_name, path, group, @mods.size
|
75
|
+
mod = Mod.new mod_name, path, group: group, index: @mods.size, spec: spec
|
76
76
|
@mods << mod
|
77
77
|
@mods_by_name[mod.name] = mod
|
78
78
|
end
|
@@ -139,15 +139,16 @@ module Cardio
|
|
139
139
|
|
140
140
|
def add_gem_mods
|
141
141
|
Cardio::Mod.gem_specs.each do |mod_name, spec|
|
142
|
-
add_gem_mod mod_name, spec
|
142
|
+
add_gem_mod mod_name, spec
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
def add_gem_mod mod_name,
|
146
|
+
def add_gem_mod mod_name, spec
|
147
147
|
return if @loaded_gem_mods.include?(mod_name)
|
148
148
|
|
149
149
|
@loaded_gem_mods << mod_name
|
150
|
-
|
150
|
+
group = spec.metadata["card-mod-group"] || "gem"
|
151
|
+
add_mod mod_name, path: spec.full_gem_path, group: group, spec: spec
|
151
152
|
end
|
152
153
|
|
153
154
|
def add_core_mods
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Cardio
|
2
|
+
class Mod
|
3
|
+
class Sow
|
4
|
+
# Fetch sow data form cards
|
5
|
+
module CardSource
|
6
|
+
def new_data_from_cards
|
7
|
+
cards.map { |c| c.pod_hash field_tags: field_tag_marks }
|
8
|
+
end
|
9
|
+
|
10
|
+
def field_tag_marks
|
11
|
+
@field_tag_marks ||= @field_tags.to_s.split(",").map do |mark|
|
12
|
+
mark.strip.cardname.codename_or_string
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def cards
|
17
|
+
if @name
|
18
|
+
cards_from_name
|
19
|
+
elsif @cql
|
20
|
+
Card.search JSON.parse(@cql).reverse_merge(limit: 0)
|
21
|
+
else
|
22
|
+
raise Card::Error::NotFound, "must specify either name (-n) or CQL (-c)"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def cards_from_name
|
27
|
+
case @items
|
28
|
+
when :only then item_cards
|
29
|
+
when true then main_cards + item_cards
|
30
|
+
else main_cards
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def item_cards
|
35
|
+
main_cards.map(&:item_cards).flatten
|
36
|
+
end
|
37
|
+
|
38
|
+
def main_cards
|
39
|
+
@main_cards ||= @name.split(",").map { |n| require_card n }
|
40
|
+
end
|
41
|
+
|
42
|
+
def require_card name
|
43
|
+
Card.fetch(name) || raise(Card::Error::NotFound, "card not found: #{name}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Cardio
|
2
|
+
class Mod
|
3
|
+
class Sow
|
4
|
+
# Writing the card representations to yaml files in mod directories
|
5
|
+
module YamlDump
|
6
|
+
# write yaml to file
|
7
|
+
def dump hash
|
8
|
+
File.write filename, hash.to_yaml
|
9
|
+
puts "#{filename} now contains #{hash.size} items".green
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String] -- MOD_DIR/data/ENVIRONMENT.yml
|
13
|
+
def filename
|
14
|
+
@filename ||= File.join mod_path, "#{@podtype}.yml"
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return Path
|
18
|
+
def mod_path
|
19
|
+
Mod.dirs.subpaths("data")[@mod] ||
|
20
|
+
raise(Card::Error::NotFound, "no data directory found for mod: #{@mod}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/cardio/mod/sow.rb
CHANGED
@@ -5,10 +5,14 @@ module Cardio
|
|
5
5
|
#
|
6
6
|
# https://docs.google.com/document/d/13K_ynFwfpHwc3t5gnLeAkZJZHco1wK063nJNYwU8qfc/edit#
|
7
7
|
class Sow
|
8
|
+
include YamlDump
|
9
|
+
include CardSource
|
10
|
+
|
8
11
|
def initialize **args
|
9
12
|
@mod = args[:mod]
|
10
13
|
@name = args[:name]
|
11
14
|
@cql = args[:cql]
|
15
|
+
@url = args[:url]
|
12
16
|
@podtype = args[:podtype] || (Rails.env.test? ? :test : :real)
|
13
17
|
@items = args[:items]
|
14
18
|
@field_tags = args[:field_tags]
|
@@ -17,7 +21,7 @@ module Cardio
|
|
17
21
|
# if output mod given,
|
18
22
|
def out
|
19
23
|
Card::Cache.reset_all
|
20
|
-
@mod ? dump : puts(new_data.to_yaml.yellow)
|
24
|
+
@mod ? dump(output_hash) : puts(new_data.to_yaml.yellow)
|
21
25
|
:success
|
22
26
|
rescue Card::Error::NotFound => e
|
23
27
|
e.message
|
@@ -27,59 +31,6 @@ module Cardio
|
|
27
31
|
|
28
32
|
private
|
29
33
|
|
30
|
-
# @return [Array <Hash>]
|
31
|
-
def new_data
|
32
|
-
@new_data ||= cards.map { |c| c.pod_hash field_tags: field_tag_marks }
|
33
|
-
end
|
34
|
-
|
35
|
-
def field_tag_marks
|
36
|
-
@field_tag_marks ||= @field_tags.to_s.split(",").map do |mark|
|
37
|
-
mark.strip.cardname.codename_or_string
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [String] -- MOD_DIR/data/ENVIRONMENT.yml
|
42
|
-
def filename
|
43
|
-
@filename ||= File.join mod_path, "#{@podtype}.yml"
|
44
|
-
end
|
45
|
-
|
46
|
-
# write yaml to file
|
47
|
-
def dump
|
48
|
-
hash = output_hash
|
49
|
-
File.write filename, hash.to_yaml
|
50
|
-
puts "#{filename} now contains #{hash.size} items".green
|
51
|
-
end
|
52
|
-
|
53
|
-
def cards
|
54
|
-
if @name
|
55
|
-
cards_from_name
|
56
|
-
elsif @cql
|
57
|
-
Card.search JSON.parse(@cql).reverse_merge(limit: 0)
|
58
|
-
else
|
59
|
-
raise Card::Error::NotFound, "must specify either name (-n) or CQL (-c)"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def cards_from_name
|
64
|
-
case @items
|
65
|
-
when :only then item_cards
|
66
|
-
when true then main_cards + item_cards
|
67
|
-
else main_cards
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def item_cards
|
72
|
-
main_cards.map(&:item_cards).flatten
|
73
|
-
end
|
74
|
-
|
75
|
-
def main_cards
|
76
|
-
@main_cards ||= @name.split(",").map { |n| require_card n }
|
77
|
-
end
|
78
|
-
|
79
|
-
def require_card name
|
80
|
-
Card.fetch(name) || raise(Card::Error::NotFound, "card not found: #{name}")
|
81
|
-
end
|
82
|
-
|
83
34
|
def output_hash
|
84
35
|
if target.present?
|
85
36
|
merge_data
|
@@ -89,6 +40,12 @@ module Cardio
|
|
89
40
|
end
|
90
41
|
end
|
91
42
|
|
43
|
+
# @return [Array <Hash>]
|
44
|
+
def new_data
|
45
|
+
@new_data ||=
|
46
|
+
@url ? pod_hash_from_url : new_data_from_cards
|
47
|
+
end
|
48
|
+
|
92
49
|
def merge_data
|
93
50
|
new_data.each do |item|
|
94
51
|
if (index = target_index item)
|
@@ -99,6 +56,10 @@ module Cardio
|
|
99
56
|
end
|
100
57
|
end
|
101
58
|
|
59
|
+
def target
|
60
|
+
@target ||= (old_data || nil)
|
61
|
+
end
|
62
|
+
|
102
63
|
def target_index new_item
|
103
64
|
new_code = new_item[:codename]
|
104
65
|
new_name = new_item[:name].to_name
|
@@ -109,20 +70,17 @@ module Cardio
|
|
109
70
|
end
|
110
71
|
end
|
111
72
|
|
112
|
-
def target
|
113
|
-
@target ||= (old_data || nil)
|
114
|
-
end
|
115
|
-
|
116
73
|
def old_data
|
117
74
|
return unless File.exist? filename
|
118
|
-
|
119
|
-
|
75
|
+
parse_pod_yaml File.read(filename)
|
76
|
+
end
|
77
|
+
|
78
|
+
def pod_hash_from_url
|
79
|
+
parse_pod_yaml URI.open(@url).read
|
120
80
|
end
|
121
81
|
|
122
|
-
|
123
|
-
|
124
|
-
Mod.dirs.subpaths("data")[@mod] ||
|
125
|
-
raise(Card::Error::NotFound, "no data directory found for mod: #{@mod}")
|
82
|
+
def parse_pod_yaml pod_yaml
|
83
|
+
YAML.safe_load pod_yaml, permitted_classes: [Symbol]
|
126
84
|
end
|
127
85
|
end
|
128
86
|
end
|
data/lib/cardio/mod.rb
CHANGED
@@ -42,13 +42,14 @@ module Cardio
|
|
42
42
|
class Mod
|
43
43
|
extend ClassMethods
|
44
44
|
|
45
|
-
attr_reader :name, :path, :group, :index
|
45
|
+
attr_reader :name, :path, :group, :index, :spec
|
46
46
|
|
47
|
-
def initialize name, path, group
|
47
|
+
def initialize name, path, group:, index:, spec: nil
|
48
48
|
@name = Mod.normalize_name name
|
49
49
|
@path = required_path path
|
50
50
|
@group = group || :custom
|
51
51
|
@index = index
|
52
|
+
@spec = spec
|
52
53
|
end
|
53
54
|
|
54
55
|
def mod_card_name
|
data/lib/cardio/railtie.rb
CHANGED
@@ -4,5 +4,5 @@
|
|
4
4
|
"watchForFileChanges": false,
|
5
5
|
"projectId": "n4h7vq",
|
6
6
|
"integrationFolder": "<%= expanded_repo_path %>/decko/spec/cypress/integration",
|
7
|
-
"supportFile": "<%= expanded_repo_path %>/decko/spec/cypress/support/
|
7
|
+
"supportFile": "<%= expanded_repo_path %>/decko/spec/cypress/support/e2e.js"
|
8
8
|
}
|
data/mod/core/data/real.yml
CHANGED
@@ -20,7 +20,7 @@ class WatchersToFollowing < Cardio::Migration::Transform
|
|
20
20
|
end
|
21
21
|
|
22
22
|
follower_hash.each do |user, items|
|
23
|
-
next unless (card =
|
23
|
+
next unless (card = user.card)&.account?
|
24
24
|
|
25
25
|
following = card.fetch "following", new: { type_code: :pointer }
|
26
26
|
items.each { |item| following.add_item item }
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# represents an entry in admin.yml
|
2
|
+
class AdminItem
|
3
|
+
attr_reader :mod, :category, :subcategory, :codename
|
4
|
+
attr_accessor :roles
|
5
|
+
|
6
|
+
def initialize mod, category, subcategory, codename
|
7
|
+
@mod = mod
|
8
|
+
@category = category
|
9
|
+
@subcategory = subcategory
|
10
|
+
@codename = codename
|
11
|
+
end
|
12
|
+
|
13
|
+
def title
|
14
|
+
config_titles = Card::Set::All::Admin.basket[:config_title]
|
15
|
+
if subcategory
|
16
|
+
config_titles[subcategory.to_sym] || subcategory.capitalize
|
17
|
+
else
|
18
|
+
config_titles[category.to_sym] || category.capitalize
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -45,7 +45,7 @@ namespace :card do
|
|
45
45
|
ENV["CARD_UPDATE_SEED"] = "true"
|
46
46
|
# tells Cardio::Seed to use fixtures upon which the seeds being updated depend
|
47
47
|
|
48
|
-
invoke_card_tasks %w[
|
48
|
+
invoke_card_tasks %w[reset seed:replant]
|
49
49
|
end
|
50
50
|
|
51
51
|
def invoke_card_tasks tasks
|
@@ -4,6 +4,8 @@ namespace :card do
|
|
4
4
|
desc "Creates the database, loads the schema, initializes seed data, " \
|
5
5
|
"and adds symlinks to public directories"
|
6
6
|
task setup: %w[db:setup card:mod:symlink]
|
7
|
+
# task setup: %w[db:setup card:update] # can't do update yet, because it overrides
|
8
|
+
# coded assets, which breaks testing
|
7
9
|
|
8
10
|
desc "Runs migrations, installs mods, and updates symlinks"
|
9
11
|
task :update do
|
@@ -11,7 +13,7 @@ namespace :card do
|
|
11
13
|
ENV["NO_RAILS_CACHE"] = "true"
|
12
14
|
# Benchmark.bm do |x|
|
13
15
|
["migrate:port", "migrate:schema", "migrate:recode", :eat, "migrate:transform",
|
14
|
-
:
|
16
|
+
:reset,
|
15
17
|
"mod:uninstall", "mod:install", "mod:symlink"].each do |task|
|
16
18
|
Rake::Task["card:#{task}"].invoke
|
17
19
|
end
|
@@ -22,15 +24,26 @@ namespace :card do
|
|
22
24
|
task eat: :environment do
|
23
25
|
parse_options :eat do
|
24
26
|
add_opt :m, :mod, "only eat cards in given mod"
|
25
|
-
add_opt :n, :name, "only eat card with name"
|
26
|
-
|
27
|
-
|
28
|
-
add_opt :u, :user, "user to credit unless specified (otherwise uses Decko Bot)"
|
27
|
+
add_opt :n, :name, "only eat card with name (handles : for codenames)"
|
28
|
+
add_opt :u, :user, "user to credit unless specified (default is Decko Bot)"
|
29
29
|
add_opt :p, :podtype, "pod type: real, test, or all " \
|
30
30
|
"(defaults to all in test env, otherwise real)"
|
31
|
+
add_opt :e, :env, "environment (test, production, etc)"
|
31
32
|
flag_opt :v, :verbose, "output progress info and error backtraces"
|
32
33
|
end
|
33
|
-
|
34
|
+
|
35
|
+
adjust_environment options, :eat do
|
36
|
+
rake_result(:eat) { Cardio::Mod::Eat.new(**options).up }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def adjust_environment options, task
|
41
|
+
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}"
|
44
|
+
else
|
45
|
+
yield
|
46
|
+
end
|
34
47
|
end
|
35
48
|
|
36
49
|
desc "Exports card data to mod yaml"
|
@@ -40,30 +53,25 @@ namespace :card do
|
|
40
53
|
flag_opt :i, :items, "also export card items (with -n)"
|
41
54
|
flag_opt :o, :only_items, "only export card items (with -n)", items: :only
|
42
55
|
add_opt :c, :cql, "export cards found by CQL (in JSON format)"
|
56
|
+
add_opt_without_shortcut :url, "source card details from url"
|
43
57
|
add_opt :m, :mod, "output yaml file in mod"
|
44
58
|
add_opt :p, :podtype, "podtype to dump (real or test. default based on current env)"
|
45
59
|
add_opt :t, :field_tags, "comma-separated list of field tag marks"
|
60
|
+
add_opt :e, :env, "environment (test, production, etc)"
|
61
|
+
end
|
62
|
+
adjust_environment options, :sow do
|
63
|
+
rake_result(:sow) { Cardio::Mod::Sow.new(**options).out }
|
46
64
|
end
|
47
|
-
rake_result(:sow) { Cardio::Mod::Sow.new(**options).out }
|
48
|
-
end
|
49
|
-
|
50
|
-
desc "Resets cache"
|
51
|
-
task reset_cache: :environment do
|
52
|
-
Card::Cache.reset_all
|
53
65
|
end
|
54
66
|
|
55
|
-
desc "
|
56
|
-
task :
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
next if filename.match?(/^\./)
|
61
|
-
|
62
|
-
FileUtils.rm_rf File.join(tmp_dir, filename), secure: true
|
63
|
-
end
|
64
|
-
else
|
65
|
-
Dir.mkdir tmp_dir
|
67
|
+
desc "Clears both cache and tmpfiles"
|
68
|
+
task reset: :environment do
|
69
|
+
parse_options :reset do
|
70
|
+
flag_opt :c, :cache, "cache only"
|
71
|
+
flag_opt :t, :tmpfiles, "tmpfiles only"
|
66
72
|
end
|
73
|
+
reset_tmpfiles unless options[:cache]
|
74
|
+
Card::Cache.reset_all unless options[:tmpfiles]
|
67
75
|
end
|
68
76
|
|
69
77
|
desc "Loads seed data"
|
@@ -89,17 +97,27 @@ namespace :card do
|
|
89
97
|
end
|
90
98
|
|
91
99
|
def add_opt letter, key, desc
|
92
|
-
op.on "-#{letter}",
|
100
|
+
op.on "-#{letter}", key_to_option_description(key), desc do |val|
|
93
101
|
options[key] = val
|
94
102
|
end
|
95
103
|
end
|
96
104
|
|
105
|
+
def add_opt_without_shortcut key, desc
|
106
|
+
op.on key_to_option_description(key), desc do |val|
|
107
|
+
options[key] = val
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def key_to_option_description key
|
112
|
+
"--#{key.to_s.tr '_', '-'} #{key.to_s.upcase}"
|
113
|
+
end
|
114
|
+
|
97
115
|
def op
|
98
116
|
@op ||= OptionParser.new
|
99
117
|
end
|
100
118
|
|
101
119
|
def parse_options task
|
102
|
-
op.banner = "Usage:
|
120
|
+
op.banner = "Usage: card #{task} [options]"
|
103
121
|
yield if block_given?
|
104
122
|
args = op.order!(ARGV) {}
|
105
123
|
# args << "-h" if args.empty?
|
@@ -114,4 +132,17 @@ namespace :card do
|
|
114
132
|
raise "\n>>>>>> FAILURE! #{task} did not complete successfully." \
|
115
133
|
"\n>>>>>> Please address errors and re-run:\n\n\n"
|
116
134
|
end
|
135
|
+
|
136
|
+
def reset_tmpfiles
|
137
|
+
tmp_dir = Cardio.paths["tmp"].first
|
138
|
+
if Cardio.paths["tmp"].existent
|
139
|
+
Dir.foreach(tmp_dir) do |filename|
|
140
|
+
next if filename.match?(/^\./)
|
141
|
+
|
142
|
+
FileUtils.rm_rf File.join(tmp_dir, filename), secure: true
|
143
|
+
end
|
144
|
+
else
|
145
|
+
Dir.mkdir tmp_dir
|
146
|
+
end
|
147
|
+
end
|
117
148
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
format :html do
|
2
|
+
def task_row task, mod
|
3
|
+
base = "#{mod}_task_#{task}"
|
4
|
+
[
|
5
|
+
link_to_card(:admin, t("#{base}_link_text"), path: { action: :update, task: task }),
|
6
|
+
t("#{base}_description")
|
7
|
+
]
|
8
|
+
end
|
9
|
+
|
10
|
+
def task_table tasks
|
11
|
+
table_content = tasks.map do |task, task_config|
|
12
|
+
task_row task, task_config[:mod]
|
13
|
+
end
|
14
|
+
table table_content, header: %w[Task Description]
|
15
|
+
end
|
16
|
+
end
|
data/mod/core/set/all/admin.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
|
2
2
|
basket[:tasks] = {}
|
3
|
+
basket[:config_title] = {
|
4
|
+
basic: "Basic configuration",
|
5
|
+
editor: "Editor configuration"
|
6
|
+
}
|
3
7
|
# to add an admin task:
|
4
8
|
#
|
5
9
|
# basket[:tasks][TASK_NAME] = {
|
@@ -12,3 +16,107 @@ basket[:tasks] = {}
|
|
12
16
|
|
13
17
|
# MOD_task_TASK_NAME_link_text: LINK_TEXT
|
14
18
|
# MOD_task_TASK_NAME_description: DESCRIPTION
|
19
|
+
|
20
|
+
def mod_cards_with_config
|
21
|
+
Card.search(type: :mod).select { |mod| mod.admin_config.present? }
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_admin_items mod, category, subcategory, values
|
25
|
+
Array.wrap(values).map do |value|
|
26
|
+
::AdminItem.new(mod, category, subcategory, value).tap do |config|
|
27
|
+
codenamed = Card::Codename.exist? config.codename.to_sym
|
28
|
+
config.roles = codenamed ? Card[config.codename.to_sym].responsible_role : []
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def scoping_rule_card
|
34
|
+
Card.fetch([self, :self, :update], new: {})
|
35
|
+
end
|
36
|
+
|
37
|
+
def responsible_role
|
38
|
+
scoping_rule_card.find_existing_rule_card.item_cards.map(&:codename)
|
39
|
+
end
|
40
|
+
|
41
|
+
def all_configs
|
42
|
+
mod_cards_with_config.map(&:admin_config_objects).flatten
|
43
|
+
end
|
44
|
+
|
45
|
+
def all_admin_configs_grouped_by property1, property2=nil
|
46
|
+
return admin_config_group_by_properties property1, property2 if property2
|
47
|
+
|
48
|
+
result = Hash.new { |hash, k| hash[k] = [] }
|
49
|
+
all_configs.each_with_object(result) do |config, h|
|
50
|
+
property_values = Array.wrap(config.send(property1))
|
51
|
+
property_values.each do |value|
|
52
|
+
h[value] << config
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def all_admin_configs_of_category category
|
58
|
+
all_admin_configs_grouped_by(:category)[category]
|
59
|
+
end
|
60
|
+
|
61
|
+
def config_codenames_grouped_by_title configs
|
62
|
+
configs&.group_by { |c| c.title }&.map do |title, grouped_configs|
|
63
|
+
[title, grouped_configs.map { |config| config.codename.to_sym }]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
format :html do
|
68
|
+
def section title, content
|
69
|
+
"<p>#{section_title(title)}#{content}</p>"
|
70
|
+
end
|
71
|
+
|
72
|
+
def section_title title
|
73
|
+
"<h3>#{title}</h3>"
|
74
|
+
end
|
75
|
+
|
76
|
+
def list_section title, items, item_view=:bar
|
77
|
+
return unless items.present?
|
78
|
+
|
79
|
+
section title, list_section_content(items, item_view)
|
80
|
+
end
|
81
|
+
|
82
|
+
def nested_list_section title, grouped_items
|
83
|
+
output [
|
84
|
+
section_title(title),
|
85
|
+
wrap_with(:div, accordion_sections(grouped_items), class: "accordion")
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
def accordion_sections grouped_items
|
90
|
+
return unless grouped_items.present?
|
91
|
+
|
92
|
+
grouped_items.map do |title, codenames|
|
93
|
+
accordion_item(title,
|
94
|
+
subheader: nil,
|
95
|
+
body: list_section_content(codenames),
|
96
|
+
open: false,
|
97
|
+
context: title.hash)
|
98
|
+
end.join " "
|
99
|
+
end
|
100
|
+
|
101
|
+
def list_section_content items, item_view=:bar
|
102
|
+
items&.map do |card|
|
103
|
+
nest card, view: item_view
|
104
|
+
end&.join(" ")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def admin_config_group_by_properties property1, property2
|
111
|
+
result = Hash.new { |hash, k| hash[k] = Hash.new { |hash2, k2| hash2[k2] = [] } }
|
112
|
+
all_configs.each_with_object(result) do |config, h|
|
113
|
+
property1_values = Array.wrap(config.send(property1))
|
114
|
+
property2_values = Array.wrap(config.send(property2))
|
115
|
+
|
116
|
+
property1_values.each do |p1v|
|
117
|
+
property2_values.each do |p2v|
|
118
|
+
h[p1v][p2v] << config
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/mod/core/set/self/admin.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
include_set Abstract::TaskTable
|
2
|
+
|
1
3
|
basket[:tasks].merge!(
|
2
4
|
clear_cache: {
|
3
5
|
mod: :core,
|
@@ -54,18 +56,7 @@ end
|
|
54
56
|
|
55
57
|
format :html do
|
56
58
|
view :core, cache: :never do
|
57
|
-
|
58
|
-
task_row task, task_config[:mod]
|
59
|
-
end
|
60
|
-
table table_content, header: %w[Task Description]
|
61
|
-
end
|
62
|
-
|
63
|
-
def task_row task, mod
|
64
|
-
base = "#{mod}_task_#{task}"
|
65
|
-
[
|
66
|
-
link_to_card(:admin, t("#{base}_link_text"), path: { action: :update, task: task }),
|
67
|
-
t("#{base}_description")
|
68
|
-
]
|
59
|
+
task_table basket[:tasks]
|
69
60
|
end
|
70
61
|
|
71
62
|
view :warning do
|
@@ -0,0 +1,39 @@
|
|
1
|
+
include_set Abstract::List
|
2
|
+
|
3
|
+
def item_codenames
|
4
|
+
Cardio.mods.map do |mod|
|
5
|
+
"#{mod}_mod"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def content
|
10
|
+
item_codenames.map(&:cardname).compact.to_pointer_content
|
11
|
+
end
|
12
|
+
|
13
|
+
format :html do
|
14
|
+
%i[cardtypes settings tasks configurations].each do |view_name|
|
15
|
+
view view_name do
|
16
|
+
[
|
17
|
+
content_tag(:h1, view_name),
|
18
|
+
card.all_admin_configs_grouped_by(:category, :mod)[view_name.to_s]
|
19
|
+
.map do |(mod, configs)|
|
20
|
+
list_section(mod.name, configs.map { |c| c.codename.to_sym })
|
21
|
+
end.join("<br\>")
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
view :roles do
|
27
|
+
[
|
28
|
+
content_tag(:h1, "Roles"),
|
29
|
+
card.all_admin_configs_grouped_by(:roles, :category).map do |(role, configs_by_cat)|
|
30
|
+
output [
|
31
|
+
content_tag(:h2, Card[role.to_sym].name),
|
32
|
+
(configs_by_cat.map do |(cat, configs)|
|
33
|
+
list_section cat, configs.map(&:codename)
|
34
|
+
end)
|
35
|
+
]
|
36
|
+
end.join("<br\>")
|
37
|
+
]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
# TODO: We can't detect file removal for folder group
|
2
|
+
|
3
|
+
include_set Abstract::List
|
4
|
+
include_set Abstract::TaskTable
|
5
|
+
|
6
|
+
format :html do
|
7
|
+
view :core do
|
8
|
+
render_section_views(%i[
|
9
|
+
description
|
10
|
+
settings
|
11
|
+
configurations
|
12
|
+
cardtypes
|
13
|
+
styles
|
14
|
+
scripts
|
15
|
+
tasks
|
16
|
+
views
|
17
|
+
depends_on
|
18
|
+
].select { |name| card.send("#{name}?") })
|
19
|
+
end
|
20
|
+
|
21
|
+
view :description do
|
22
|
+
content_tag(:p, card.description)
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_section_views list
|
26
|
+
list.map { |view_name| send("render_#{view_name}") }.compact.join "<br/>"
|
27
|
+
end
|
28
|
+
|
29
|
+
view :settings do
|
30
|
+
list_section "Settings", card.settings
|
31
|
+
end
|
32
|
+
|
33
|
+
view :cardtypes do
|
34
|
+
nested_list_section "Cardtypes", card.cardtypes
|
35
|
+
end
|
36
|
+
|
37
|
+
view :configurations do
|
38
|
+
return unless card.configurations
|
39
|
+
|
40
|
+
card.configurations.map do |category, names|
|
41
|
+
list_section("#{category.capitalize} Configuration",
|
42
|
+
names.map(&:to_sym))
|
43
|
+
end.join " "
|
44
|
+
end
|
45
|
+
|
46
|
+
view :tasks do
|
47
|
+
tasks = card.tasks
|
48
|
+
return unless tasks.present?
|
49
|
+
|
50
|
+
section "Tasks", task_table(tasks)
|
51
|
+
end
|
52
|
+
|
53
|
+
view :styles do
|
54
|
+
style = card.fetch :style
|
55
|
+
return unless style
|
56
|
+
section "Styles", nest(style, view: :core)
|
57
|
+
end
|
58
|
+
|
59
|
+
view :scripts do
|
60
|
+
style = card.fetch :script
|
61
|
+
return unless style
|
62
|
+
section "Scripts", nest(style, view: :core)
|
63
|
+
end
|
64
|
+
|
65
|
+
view :gem_info do
|
66
|
+
return unless card.mod&.spec
|
67
|
+
properties =
|
68
|
+
%w[name summary version authors description email homepage].map do |property|
|
69
|
+
"#{property}: #{card.mod.spec.send(property)}"
|
70
|
+
end
|
71
|
+
|
72
|
+
section "Gem info",
|
73
|
+
list_group(properties) +
|
74
|
+
accordion_item("files",
|
75
|
+
body: list_group(card.mod.spec.files),
|
76
|
+
context: "files") +
|
77
|
+
accordion_item("depends on ",
|
78
|
+
body: list_section_content(card.depends_on),
|
79
|
+
context: "depends_on")
|
80
|
+
end
|
81
|
+
|
82
|
+
view :depends_on do
|
83
|
+
list_section "Depends on", card.depends_on
|
84
|
+
end
|
85
|
+
|
86
|
+
view :views do
|
87
|
+
section "Views", list_group(card.views)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def settings?
|
92
|
+
settings.present?
|
93
|
+
end
|
94
|
+
|
95
|
+
def cardtypes?
|
96
|
+
cardtypes.present?
|
97
|
+
end
|
98
|
+
|
99
|
+
def configurations?
|
100
|
+
configurations.present?
|
101
|
+
end
|
102
|
+
|
103
|
+
def tasks?
|
104
|
+
tasks.present?
|
105
|
+
end
|
106
|
+
|
107
|
+
def styles?
|
108
|
+
fetch(:style).present?
|
109
|
+
end
|
110
|
+
|
111
|
+
def scripts?
|
112
|
+
fetch(:script).present?
|
113
|
+
end
|
114
|
+
|
115
|
+
def depends_on?
|
116
|
+
mod&.spec&.dependencies.present?
|
117
|
+
end
|
118
|
+
|
119
|
+
def description?
|
120
|
+
true
|
121
|
+
end
|
122
|
+
|
123
|
+
def views?
|
124
|
+
views.present?
|
125
|
+
end
|
126
|
+
|
127
|
+
def depends_on
|
128
|
+
mod&.spec&.dependencies
|
129
|
+
&.map { |dep| dep.name }
|
130
|
+
&.select { |name| name.starts_with? "card-mod" }
|
131
|
+
&.map { |name| "mod_#{name[8..-1]}" }
|
132
|
+
end
|
133
|
+
|
134
|
+
def tasks
|
135
|
+
basket[:tasks].select { |_k, v| v[:mod] == modname.to_sym }
|
136
|
+
end
|
137
|
+
|
138
|
+
def settings
|
139
|
+
return unless admin_config
|
140
|
+
|
141
|
+
admin_config["settings"]&.map do |setting|
|
142
|
+
setting.to_sym
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def configurations
|
147
|
+
return unless admin_config
|
148
|
+
|
149
|
+
admin_config["configurations"]
|
150
|
+
end
|
151
|
+
|
152
|
+
def cardtypes
|
153
|
+
return unless admin_config
|
154
|
+
|
155
|
+
config_codenames_grouped_by_title admin_config_section(:cardtypes)
|
156
|
+
end
|
157
|
+
|
158
|
+
def views
|
159
|
+
return unless admin_config
|
160
|
+
|
161
|
+
admin_config["views"]
|
162
|
+
end
|
163
|
+
|
164
|
+
def description
|
165
|
+
default = if mod&.spec&.description.present?
|
166
|
+
mod&.spec&.description
|
167
|
+
else
|
168
|
+
mod&.spec&.summary
|
169
|
+
end
|
170
|
+
t("#{modname}_mod_description", default: default)
|
171
|
+
end
|
172
|
+
|
173
|
+
def modname
|
174
|
+
codename.to_s.gsub(/^mod_/, "")
|
175
|
+
end
|
176
|
+
|
177
|
+
def mod
|
178
|
+
@mod ||= Cardio::Mod.fetch modname
|
179
|
+
end
|
180
|
+
|
181
|
+
def admin_config_section category
|
182
|
+
admin_config_objects_by_category[category.to_s]
|
183
|
+
end
|
184
|
+
|
185
|
+
def admin_config
|
186
|
+
@admin_config ||= load_admin_config
|
187
|
+
end
|
188
|
+
|
189
|
+
def admin_config_objects
|
190
|
+
@admin_config_objects ||= admin_config.map do |category, values|
|
191
|
+
if values.is_a? Hash
|
192
|
+
values.map do |subcategory, subvalues|
|
193
|
+
create_admin_items mod, category, subcategory, subvalues
|
194
|
+
end.flatten
|
195
|
+
else
|
196
|
+
create_admin_items mod, category, nil, values
|
197
|
+
end
|
198
|
+
end.flatten
|
199
|
+
end
|
200
|
+
|
201
|
+
def admin_config_objects_by_category
|
202
|
+
@admin_config_objects_by_category ||=
|
203
|
+
admin_config_objects.group_by(&:category)
|
204
|
+
end
|
205
|
+
|
206
|
+
def load_admin_config
|
207
|
+
return unless admin_config_exists?
|
208
|
+
admin_config = YAML.load_file admin_config_path
|
209
|
+
return {} unless admin_config # blank manifest
|
210
|
+
# validate_manifest manifest
|
211
|
+
admin_config
|
212
|
+
end
|
213
|
+
|
214
|
+
def admin_config_exists?
|
215
|
+
@admin_config_exists = !admin_config_path.nil? if @admin_config_exists.nil?
|
216
|
+
@admin_config_exists
|
217
|
+
end
|
218
|
+
|
219
|
+
def admin_config_path
|
220
|
+
@admin_config_path ||= mod&.subpath "config", "admin.yml"
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
def read_admin_yml
|
226
|
+
YAML.safe_load File.read(filename), [Symbol] if File.exist? filename
|
227
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
RSpec.describe Card::Set::All::Admin do
|
2
|
+
describe "all_admin_configs_of_category" do
|
3
|
+
it "finds settings" do
|
4
|
+
expect(Card[:all].all_admin_configs_of_category("settings").map(&:codename))
|
5
|
+
.to include("create")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "create setting has the correct role" do
|
9
|
+
create_config = Card[:all].all_admin_configs_of_category("settings")
|
10
|
+
.find { |x| x.codename == "create" }
|
11
|
+
expect(create_config.roles).to eq([:shark])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "finds views" do
|
15
|
+
views = Card[:all].all_admin_configs_of_category("views").map(&:codename)
|
16
|
+
expect(views).to include("name", "link", "content")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "admin_config_by_role" do
|
21
|
+
roles = Card[:all].all_admin_configs_grouped_by(:roles)
|
22
|
+
expect(roles[:anyone_signed_in].map(&:codename))
|
23
|
+
.to contain_exactly("mod", "user", "setting", "json", "number", "plain_text",
|
24
|
+
"toggle", "phrase", "uri",
|
25
|
+
"list", "pointer", "email_template", "file", "image",
|
26
|
+
"link_list",
|
27
|
+
"local_script_folder_group", "local_script_manifest_group",
|
28
|
+
"local_style_folder_group",
|
29
|
+
"nest_list", "remote_manifest_group", "role",
|
30
|
+
"local_style_manifest_group", "bootswatch_skin",
|
31
|
+
"date", "notification_template", "session", "basic",
|
32
|
+
"search_type", "signup")
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
RSpec.describe Card::Set::Type::Mod do
|
2
|
+
check_views_for_errors
|
3
|
+
|
4
|
+
specify "cardtypes" do
|
5
|
+
expect(Card[:mod_format].cardtypes)
|
6
|
+
.to eq [["Text", %i[basic plain_text html phrase]],
|
7
|
+
["Scripting", [:json]], ["Data", %i[number toggle uri]]]
|
8
|
+
end
|
9
|
+
|
10
|
+
specify "admin_config_objects" do
|
11
|
+
config_objects = Card[:mod_core].admin_config_objects
|
12
|
+
expect(config_objects.size).to eq 7
|
13
|
+
|
14
|
+
expect(config_objects[0].category).to eq "cardtypes"
|
15
|
+
expect(config_objects[0].subcategory).to eq "admin"
|
16
|
+
expect(config_objects[0].title).to eq "Admin"
|
17
|
+
expect(config_objects[0].codename).to eq "mod"
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "core view" do
|
21
|
+
it "renders Cardtypes and Tasks section for core mod" do
|
22
|
+
view = render_card :core, :mod_core
|
23
|
+
expect(view).to have_tag :h3, "Cardtypes"
|
24
|
+
%w[Mod User Setting Cardtype].each do |cardtype_name|
|
25
|
+
expect(view).to have_tag :span, class: "card-title", content: cardtype_name
|
26
|
+
end
|
27
|
+
expect(view).to have_tag :h3, "Tasks"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
RSpec.shared_examples "mod admin config" do |codename, settings, configs, cardtypes|
|
2
|
+
card = codename.card
|
3
|
+
specify "admin.yml of #{codename} loaded correctly" do
|
4
|
+
aggregate_failures do
|
5
|
+
expect(card.settings).to eq settings
|
6
|
+
expect(card.configurations).to eq configs
|
7
|
+
expect(card.cardtypes).to eq cardtypes
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: card
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.107.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan McCutchen
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2024-06-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: cardname
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.17.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.
|
28
|
+
version: 0.17.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rake
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -616,6 +616,8 @@ files:
|
|
616
616
|
- lib/cardio/mod/modfile_loader.rb
|
617
617
|
- lib/cardio/mod/module_template.rb
|
618
618
|
- lib/cardio/mod/sow.rb
|
619
|
+
- lib/cardio/mod/sow/card_source.rb
|
620
|
+
- lib/cardio/mod/sow/yaml_dump.rb
|
619
621
|
- lib/cardio/railtie.rb
|
620
622
|
- lib/cardio/record.rb
|
621
623
|
- lib/cardio/script_loader.rb
|
@@ -673,6 +675,7 @@ files:
|
|
673
675
|
- lib/generators/set/set_generator.rb
|
674
676
|
- lib/generators/set/templates/set_spec_template.erb
|
675
677
|
- lib/generators/set/templates/set_template.erb
|
678
|
+
- mod/core/config/admin.yml
|
676
679
|
- mod/core/config/locales/de.yml
|
677
680
|
- mod/core/config/locales/en.yml
|
678
681
|
- mod/core/data/fixtures/real/card_actions.yml
|
@@ -744,10 +747,12 @@ files:
|
|
744
747
|
- mod/core/data/transform/20190909104250_add_cardtype_input_types.rb
|
745
748
|
- mod/core/data/transform/20191115160748_history_cleanup.rb
|
746
749
|
- mod/core/data/transform/20230502094848_repair_all_references.rb
|
750
|
+
- mod/core/lib/admin_item.rb
|
747
751
|
- mod/core/lib/tasks/card.rake
|
748
752
|
- mod/core/lib/tasks/card/migrate.rake
|
749
753
|
- mod/core/lib/tasks/card/mod.rake
|
750
754
|
- mod/core/lib/tasks/card/seed.rake
|
755
|
+
- mod/core/set/abstract/task_table.rb
|
751
756
|
- mod/core/set/all/admin.rb
|
752
757
|
- mod/core/set/all/assign_attributes.rb
|
753
758
|
- mod/core/set/all/autoname.rb
|
@@ -767,9 +772,11 @@ files:
|
|
767
772
|
- mod/core/set/self/admin.rb
|
768
773
|
- mod/core/set/self/admin/warning_alert.haml
|
769
774
|
- mod/core/set/self/autoname.rb
|
775
|
+
- mod/core/set/self/mod.rb
|
770
776
|
- mod/core/set/self/trash.rb
|
771
777
|
- mod/core/set/self/version.rb
|
772
778
|
- mod/core/set/type/cardtype.rb
|
779
|
+
- mod/core/set/type/mod.rb
|
773
780
|
- mod/core/set_pattern/01_all.rb
|
774
781
|
- mod/core/set_pattern/02_all_plus.rb
|
775
782
|
- mod/core/set_pattern/03_type.rb
|
@@ -779,6 +786,7 @@ files:
|
|
779
786
|
- mod/core/set_pattern/07_right.rb
|
780
787
|
- mod/core/set_pattern/08_type_plus_right.rb
|
781
788
|
- mod/core/set_pattern/09_self.rb
|
789
|
+
- mod/core/spec/set/all/admin_spec.rb
|
782
790
|
- mod/core/spec/set/all/assign_attributes_spec.rb
|
783
791
|
- mod/core/spec/set/all/autoname_spec.rb
|
784
792
|
- mod/core/spec/set/all/codename_spec.rb
|
@@ -791,6 +799,8 @@ files:
|
|
791
799
|
- mod/core/spec/set/self/trash_spec.rb
|
792
800
|
- mod/core/spec/set/self/version_spec.rb
|
793
801
|
- mod/core/spec/set/type/cardtype_spec.rb
|
802
|
+
- mod/core/spec/set/type/mod_spec.rb
|
803
|
+
- mod/core/spec/shared_examples/mod_admin_config.rb
|
794
804
|
homepage: https://decko.org
|
795
805
|
licenses:
|
796
806
|
- GPL-3.0
|
@@ -808,14 +818,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
808
818
|
requirements:
|
809
819
|
- - ">="
|
810
820
|
- !ruby/object:Gem::Version
|
811
|
-
version: '
|
821
|
+
version: '3.0'
|
812
822
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
813
823
|
requirements:
|
814
824
|
- - ">="
|
815
825
|
- !ruby/object:Gem::Version
|
816
826
|
version: '0'
|
817
827
|
requirements: []
|
818
|
-
rubygems_version: 3.
|
828
|
+
rubygems_version: 3.5.10
|
819
829
|
signing_key:
|
820
830
|
specification_version: 4
|
821
831
|
summary: a simple engine for emergent data structures
|