card 1.106.0 → 1.107.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|