card 1.105.0 → 1.105.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/card/director/card_class.rb +17 -14
- data/lib/card/fetch/card_class.rb +19 -13
- data/lib/card/name.rb +3 -3
- data/lib/card/query.rb +8 -5
- data/lib/card/set/abstract.rb +1 -0
- data/lib/card/set/format/abstract_format/wrapper.rb +0 -1
- data/lib/card/set/format/abstract_format.rb +4 -3
- data/lib/card/set/format.rb +46 -20
- data/lib/card/set/helpers.rb +49 -36
- data/lib/card/set/registrar.rb +3 -5
- data/lib/card/set/required_field.rb +3 -2
- data/lib/card/set/type.rb +1 -0
- data/lib/card/set.rb +67 -21
- data/lib/card.rb +30 -12
- data/lib/cardio/command/custom.rb +1 -0
- data/lib/cardio/command/rake_command.rb +1 -1
- data/lib/cardio/command/rspec_command/parser.rb +7 -4
- data/lib/cardio/generators.rb +1 -1
- data/lib/cardio/mod/class_methods.rb +2 -2
- data/lib/cardio/mod/dirs.rb +1 -1
- data/lib/cardio/mod/eat/edibles.rb +21 -1
- data/lib/cardio/mod/eat.rb +4 -2
- data/lib/cardio/mod/modfile_api.rb +2 -2
- data/lib/cardio/mod/sow.rb +16 -16
- data/lib/cardio/mod.rb +30 -48
- data/lib/cardio/railtie.rb +3 -3
- data/lib/generators/mod/mod_generator.rb +5 -5
- data/mod/core/lib/tasks/card/mod.rake +5 -2
- data/mod/core/lib/tasks/card/seed.rake +6 -4
- data/mod/core/lib/tasks/card.rake +8 -4
- data/mod/core/set/all/states.rb +8 -2
- metadata +6 -8
- data/mod/core/lib/tasks/card/assets.rake +0 -17
- data/mod/core/lib/tasks/card/create.rake +0 -81
- /data/mod/core/{locales → config/locales}/de.yml +0 -0
- /data/mod/core/{locales → config/locales}/en.yml +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d1c8cf4b2e9416f3e17e107de3651e51957b9bb0f8bd9a32dfb7c9e5ffcfe5e
|
4
|
+
data.tar.gz: ea4bf60694b93994f9fd8e626fe2dd6bf0860ce1e270e533066b42d3e98c0f39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65ff19795cd4a020bd67bf08d35d5eef95c3b904bc70fd2fe94eee219c5e34e4e77b29868302f98069d3fc2877c7cf9f69bffc5193bdffec337925a57997b1d3
|
7
|
+
data.tar.gz: 40ada7a7227dd40ae2d8edb9a23aa4a6c4777c505a73f1a39e2ed2ad9ce741078e1645ac995de6ad8c509bfb94f11f02dec78d8906ad465cdae09ecc444cbab1
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.15.
|
1
|
+
0.15.1
|
@@ -16,35 +16,38 @@ class Card
|
|
16
16
|
|
17
17
|
# The ensure methods are use to make sure a card exists and can be used when you're
|
18
18
|
# unsure as to whether it already does. It's arguments are largely the same as
|
19
|
-
# those used by Card
|
20
|
-
# `conflict`.
|
21
|
-
|
19
|
+
# those used by {#create Card#create} and {Director::All#update @card.update} with
|
20
|
+
# the important exception of `conflict`.
|
21
|
+
#
|
22
22
|
# The conflict argument takes one of three values:
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
23
|
+
#
|
24
|
+
# - **defer**: let existing card stay as it is
|
25
|
+
# - **default**: update existing card if it is "pristine" (meaning it has not
|
26
|
+
# been edited by anyone other than Decko Bot)
|
27
|
+
# - **override**: update existing card
|
28
|
+
#
|
28
29
|
# If the options specify a codename and the name is already in use, things get a
|
29
30
|
# little more involved. (Note: we MUST ensure that a card with the codename exists!)
|
30
|
-
|
31
|
-
# If the conflict setting is "defer":
|
31
|
+
#
|
32
|
+
# If the conflict setting is "**defer**":
|
32
33
|
#
|
33
34
|
# - if the _codename_ is NOT already in use, we create a new card with an
|
34
35
|
# altered name
|
35
36
|
# - otherwise we do nothing.
|
36
37
|
#
|
37
|
-
# If the conflict setting is "default":
|
38
|
+
# If the conflict setting is "**default**":
|
39
|
+
#
|
38
40
|
# - if the _codename_ is NOT already in use:
|
39
41
|
# - if the card using the name we want is pristine, we update that card
|
40
42
|
# - otherwise we create a new card with an altered name
|
41
|
-
# - if the
|
43
|
+
# - if the _codename_ IS already in use
|
42
44
|
# - if the card with the codename is pristine, we update everything but the
|
43
45
|
# name (which is used by another card)
|
44
46
|
# - otherwise we do nothing
|
45
47
|
#
|
46
|
-
# If the conflict setting is "override":
|
47
|
-
#
|
48
|
+
# If the conflict setting is "**override**":
|
49
|
+
#
|
50
|
+
# - if the _codename_ is NOT already in use, we update the existing card with the
|
48
51
|
# name.
|
49
52
|
# - otherwise we alter the card withe the conflicting name and update the card
|
50
53
|
# with the codename.
|
@@ -1,29 +1,32 @@
|
|
1
1
|
class Card
|
2
2
|
class Fetch
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# A multipurpose retrieval operator that integrates caching, database lookups,
|
3
|
+
# A multipurpose retrieval system that integrates caching, database lookups,
|
6
4
|
# and "virtual" card construction
|
7
5
|
module CardClass
|
8
6
|
# Look for cards in
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
7
|
+
# * cache
|
8
|
+
# * database
|
9
|
+
# * virtual cards
|
12
10
|
#
|
13
11
|
# @param args [Integer, String, Card::Name, Symbol, Array]
|
14
12
|
# Initials args must be one or more "marks," which uniquely idenfify cards:
|
13
|
+
#
|
14
|
+
#
|
15
15
|
# 1. a name/key. (String or Card::Name)
|
16
16
|
# 2. a numeric id. Can be (a) an Integer or (b) a String with an integer
|
17
17
|
# prefixed with a tilde, eg "~1234"
|
18
18
|
# 3. a codename. Can be (a) a Symbol or (b) a String with a colon prefix,
|
19
19
|
# eg :mycodename
|
20
|
+
#
|
20
21
|
# If you pass more then one mark or an array of marks they get joined with a '+'.
|
21
22
|
# The final argument can be a Hash to set the following options
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
23
|
+
#
|
24
|
+
# :skip_virtual Real cards only
|
25
|
+
# :skip_modules Don't load Set modules
|
26
|
+
# :look_in_trash Return trashed card objects
|
27
|
+
# :local_only Use only local cache for lookup and storing
|
28
|
+
# new: { opts for Card#new } Return a new card when not found
|
29
|
+
#
|
27
30
|
# @return [Card]
|
28
31
|
def fetch *args
|
29
32
|
f = Fetch.new(*args)
|
@@ -32,9 +35,9 @@ class Card
|
|
32
35
|
Card.new name: "card id out of range: #{f.mark}"
|
33
36
|
end
|
34
37
|
|
35
|
-
# fetch only real (no
|
38
|
+
# a shortcut for fetch that returns only real cards (no virtuals)
|
36
39
|
#
|
37
|
-
# @param mark - see #fetch
|
40
|
+
# @param mark [various] - see {#fetch}
|
38
41
|
# @return [Card]
|
39
42
|
def [] *mark
|
40
43
|
fetch(*mark, skip_virtual: true)
|
@@ -62,6 +65,9 @@ class Card
|
|
62
65
|
# ATTRIBUTE FETCHING
|
63
66
|
# The following methods optimize fetching of specific attributes
|
64
67
|
|
68
|
+
# numerical card id
|
69
|
+
# @params cardish [various] interprets integers as id, symbols as codename, etc
|
70
|
+
# @return [Integer]
|
65
71
|
def id cardish
|
66
72
|
case cardish
|
67
73
|
when Integer then cardish
|
data/lib/card/name.rb
CHANGED
@@ -5,10 +5,10 @@
|
|
5
5
|
require "cardname"
|
6
6
|
|
7
7
|
class Card
|
8
|
-
# The Cardname class provides generalized of Card naming patterns
|
9
|
-
#
|
8
|
+
# The {Cardname} class provides generalized of Card naming patterns (compound names,
|
9
|
+
# key-based variants, etc) and can be used independently of Card objects.
|
10
10
|
#
|
11
|
-
# Card::Name adds support for deeper
|
11
|
+
# {Card::Name} adds support for deeper integration with Card objects
|
12
12
|
class Name < Cardname
|
13
13
|
include NameVariants
|
14
14
|
|
data/lib/card/query.rb
CHANGED
@@ -7,8 +7,8 @@ class Card
|
|
7
7
|
# frequently used directly in code.
|
8
8
|
#
|
9
9
|
# Query "statements" (objects, really) are made in CQL (Card Query
|
10
|
-
# Language). Because CQL is used by Sharks, the primary
|
11
|
-
#
|
10
|
+
# Language). Because CQL is used by Sharks, [the primary CQL Syntax documentation is
|
11
|
+
# on decko.org](https://decko.org/CQL_Syntax). Note that the
|
12
12
|
# examples there are in JSON, like Search card content, but statements in
|
13
13
|
# Card::Query are in ruby form.
|
14
14
|
#
|
@@ -17,9 +17,11 @@ class Card
|
|
17
17
|
# CQL statement interpretation.
|
18
18
|
#
|
19
19
|
# The most common way to use Card::Query is as follows:
|
20
|
+
#
|
20
21
|
# list_of_cards = Card::Query.run(statement)
|
21
22
|
#
|
22
23
|
# This is equivalent to:
|
24
|
+
#
|
23
25
|
# query = Card::Query.new(statement)
|
24
26
|
# list_of_cards = query.run
|
25
27
|
#
|
@@ -32,7 +34,8 @@ class Card
|
|
32
34
|
# - @subqueries - a list of other queries nested within this one
|
33
35
|
#
|
34
36
|
# Each condition is either a SQL-ready string (boo) or an Array in this form:
|
35
|
-
#
|
37
|
+
#
|
38
|
+
# [field_string_or_sym, (Card::Value::Query object)]
|
36
39
|
module Query
|
37
40
|
require "card/query/clause"
|
38
41
|
require "card/query/card_query"
|
@@ -48,8 +51,8 @@ class Card
|
|
48
51
|
# their values are translated fairly directly into SQL-safe values.
|
49
52
|
# (These are referred to as "properties" in CQL documentation. Need to
|
50
53
|
# reconcile #EFM)
|
51
|
-
basic: %i[id name key type_id content left_id right_id
|
52
|
-
creator_id updater_id
|
54
|
+
basic: %i[id name key type_id content left_id right_id codename read_rule_id
|
55
|
+
created_at updated_at creator_id updater_id ],
|
53
56
|
# "Relational" values can involve tying multiple queries together
|
54
57
|
relational: %i[type
|
55
58
|
part left right
|
data/lib/card/set/abstract.rb
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
class Card
|
4
4
|
module Set
|
5
5
|
module Format
|
6
|
-
# AbstractFormat manages the
|
7
|
-
#
|
8
|
-
# create a format
|
6
|
+
# AbstractFormat manages the DSL for defining {#view views}.
|
7
|
+
#
|
8
|
+
# Whenever you create a {Format format} block in a {Cardio::Set set module},
|
9
|
+
# you create a format module that is extended with AbstractFormat.
|
9
10
|
module AbstractFormat
|
10
11
|
include ViewOpts
|
11
12
|
include ViewDefinition
|
data/lib/card/set/format.rb
CHANGED
@@ -2,33 +2,58 @@
|
|
2
2
|
|
3
3
|
class Card
|
4
4
|
module Set
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Card::Set::Format is responsible for handling `format` blocks within the set module
|
6
|
+
# DSL, which is used in {Cardio::Mod Set module} files found in {Cardio::Mod mods'}
|
7
|
+
# set directories. Monkeys use the DSL to define views that apply to specific sets of
|
8
|
+
# cards in specific formats. The views can then be
|
9
|
+
# used by Monkeys in code and by Sharks via the UI.
|
7
10
|
#
|
8
|
-
#
|
11
|
+
# For example, imagine you have a set module file in `mod/mymod/type/my_type.rb`.
|
12
|
+
# There you can define a view like this:
|
9
13
|
#
|
10
14
|
# format :html do
|
11
|
-
#
|
15
|
+
# view :hello do
|
16
|
+
# greeting
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# {AbstractFormat#view Learn more about defining views}
|
21
|
+
#
|
22
|
+
# This view will now be available to MyType cards in HTML -- but not in other formats.
|
23
|
+
# Similarly, you can define other methods in format blocks:
|
24
|
+
#
|
25
|
+
# format :html do
|
26
|
+
# def greeting
|
12
27
|
# :rocks
|
13
28
|
# end
|
14
29
|
# end
|
15
30
|
#
|
16
|
-
# The magic that happens here is that the method #
|
17
|
-
# available) _only_ to the cards in the set specified by the mod, and
|
18
|
-
#
|
31
|
+
# The magic that happens here is that the method #greeting is now applicable (and
|
32
|
+
# available) _only_ to the cards in the {Card::Set set} specified by the mod, and
|
33
|
+
# only when rendering a view of the card in the HTML format. {Card::Format Learn
|
34
|
+
# more about formats}.
|
19
35
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# How the format object for a given card in the set includes this module dynamically
|
23
|
-
# when it's initialized. And so on...
|
36
|
+
# So if, for example, I had a card "MyCard" with the type "MyType", the following
|
37
|
+
# should use the method above:
|
24
38
|
#
|
25
|
-
#
|
39
|
+
# ````
|
40
|
+
# "MyCard".card.format(:html).greeting
|
41
|
+
# ````
|
42
|
+
#
|
43
|
+
# ...but if the card had a different type, or if I tried to use the method in, say,
|
44
|
+
# the JSON format, this #beethoven method wouldn't be available.
|
45
|
+
#
|
46
|
+
# Under the hood, the DSL creates a ruby module that looks something like
|
47
|
+
# `Card::Set::Type::MyType::HtmlFormat`. This module will then be dynamically included
|
48
|
+
# in HTML format objects for MyCard.
|
49
|
+
#
|
50
|
+
# As monkeys, we don't usually think about all that much, because we work in
|
26
51
|
# the set module space, which lets us focus on the card patterns.
|
27
52
|
#
|
28
53
|
# Speaking of which, there are a few key patterns to be aware of:
|
29
54
|
#
|
30
55
|
# 1. Just as in {Card::Set sets}, format methods for narrower sets will override
|
31
|
-
# format methods for more general sets. So if a #
|
56
|
+
# format methods for more general sets. So if a #greeting method is defined
|
32
57
|
# for all cards and again for a specific card type, then the type method will
|
33
58
|
# override the all method when both apply.
|
34
59
|
# 2. Similarly, specific formats inherit from more general formats, and all formats
|
@@ -36,27 +61,28 @@ class Card
|
|
36
61
|
# will define methods on the base format class.
|
37
62
|
#
|
38
63
|
# format do
|
39
|
-
# def
|
40
|
-
#
|
64
|
+
# def farewell
|
65
|
+
# "goodbye"
|
41
66
|
# end
|
42
67
|
# end
|
43
68
|
#
|
44
69
|
# 3. It is possible to use super to refer to overridden methods. For example
|
45
70
|
#
|
46
71
|
# format :html do
|
47
|
-
# def
|
72
|
+
# def goodbye
|
48
73
|
# "<em>#{super}</em>"
|
49
74
|
# end
|
50
75
|
# end
|
51
76
|
#
|
52
77
|
# Note: Set precedence has a higher priority than Format precedence.
|
53
78
|
#
|
54
|
-
# 4.
|
55
|
-
# be defined on the base format.
|
56
|
-
#
|
57
|
-
# 5. Some very powerful API calls (including {AbstractFormat#view view} and
|
79
|
+
# 4. Some very powerful API calls (including {AbstractFormat#view view} and
|
58
80
|
# {AbstractFormat#before before}) are defined in {AbstractFormat}. These methods are
|
59
81
|
# always available in format blocks.
|
82
|
+
#
|
83
|
+
# 5. {#view} and {#before}, however, can ALSO both be called outside of a format
|
84
|
+
# block. They will be defined on the base format.
|
85
|
+
#
|
60
86
|
module Format
|
61
87
|
require "card/set/format/haml_paths"
|
62
88
|
require "card/set/format/abstract_format"
|
data/lib/card/set/helpers.rb
CHANGED
@@ -1,42 +1,32 @@
|
|
1
1
|
class Card
|
2
2
|
module Set
|
3
|
+
# These helper methods provide easy access to metadata, such as information about
|
4
|
+
# the set modified by a module. These methods are seldom used by Monkeys; they are
|
5
|
+
# primarily Platypus tools.
|
3
6
|
module Helpers
|
4
7
|
SET_PATTERN_TEST_REGEXP = /^(?<pattern>\w+)_set\?$/
|
5
8
|
|
9
|
+
# @return [String] short name of card module. For example, returns Type::User for
|
10
|
+
# Card::Set::Type::User
|
6
11
|
def shortname
|
7
12
|
first = 2 # shortname eliminates Card::Set
|
8
13
|
last = first + num_set_parts(pattern_code)
|
9
14
|
set_name_parts[first..last].join "::"
|
10
15
|
end
|
11
16
|
|
12
|
-
|
17
|
+
# @return [String] name of card module with underscores. For example, returns
|
18
|
+
# Card__Set__Type__User for Card::Set::Type::User
|
19
|
+
def underscored_name
|
13
20
|
shortname.tr(":", "_").underscore
|
14
21
|
end
|
15
22
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
Pattern.find(pattern_code).anchor_parts_count
|
20
|
-
end
|
21
|
-
|
22
|
-
def set_format_type_key
|
23
|
-
@set_format_type_key ||= :"#{set_type_key}_format"
|
24
|
-
end
|
25
|
-
|
26
|
-
def set_type_key
|
27
|
-
if all_set?
|
28
|
-
:base
|
29
|
-
elsif abstract_set?
|
30
|
-
:abstract
|
31
|
-
else
|
32
|
-
:nonbase
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
23
|
+
# @return [Array] list of strings of parts of set module's name
|
24
|
+
# Eg, returns ["Card", "Set", "Type", "User"] for Card::Set::Type::User
|
36
25
|
def set_name_parts
|
37
26
|
@set_name_parts ||= name.split "::"
|
38
27
|
end
|
39
28
|
|
29
|
+
# @return [Symbol] codename associated with set's pattern. Eg :type, :right, etc
|
40
30
|
def pattern_code
|
41
31
|
@pattern_code ||= set_name_parts[2].underscore.to_sym
|
42
32
|
end
|
@@ -50,6 +40,8 @@ class Card
|
|
50
40
|
end
|
51
41
|
end
|
52
42
|
|
43
|
+
# @return [true/false]
|
44
|
+
# handles all_set?, abstract_set?, type_set?, etc.
|
53
45
|
def respond_to_missing? method_name, _include_private=false
|
54
46
|
method_name.match? SET_PATTERN_TEST_REGEXP
|
55
47
|
end
|
@@ -64,21 +56,6 @@ class Card
|
|
64
56
|
end
|
65
57
|
end
|
66
58
|
|
67
|
-
def test_set
|
68
|
-
# rubocop:disable Lint/Eval
|
69
|
-
::Card::Set::Self.const_remove_if_defined :TestSet
|
70
|
-
eval <<-RUBY, binding, __FILE__, __LINE__ + 1
|
71
|
-
class ::Card::Set::Self
|
72
|
-
module TestSet
|
73
|
-
extend Card::Set
|
74
|
-
include_set #{name}
|
75
|
-
end
|
76
|
-
end
|
77
|
-
RUBY
|
78
|
-
::Card::Set::Self::TestSet
|
79
|
-
# rubocop:enable Lint/Eval
|
80
|
-
end
|
81
|
-
|
82
59
|
def format_modules format_sym, test: true
|
83
60
|
if base_format_modules?
|
84
61
|
[format_module(format_sym)]
|
@@ -95,6 +72,36 @@ class Card
|
|
95
72
|
|
96
73
|
private
|
97
74
|
|
75
|
+
# @return [Symbol] base_format,
|
76
|
+
def set_format_type_key
|
77
|
+
@set_format_type_key ||= :"#{set_type_key}_format"
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_type_key
|
81
|
+
if all_set?
|
82
|
+
:base
|
83
|
+
elsif abstract_set?
|
84
|
+
:abstract
|
85
|
+
else
|
86
|
+
:nonbase
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_set
|
91
|
+
# rubocop:disable Lint/Eval
|
92
|
+
::Card::Set::Self.const_remove_if_defined :TestSet
|
93
|
+
eval <<-RUBY, binding, __FILE__, __LINE__ + 1
|
94
|
+
class ::Card::Set::Self
|
95
|
+
module TestSet
|
96
|
+
extend Card::Set
|
97
|
+
include_set #{name}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
RUBY
|
101
|
+
::Card::Set::Self::TestSet
|
102
|
+
# rubocop:enable Lint/Eval
|
103
|
+
end
|
104
|
+
|
98
105
|
def base_format_modules?
|
99
106
|
!set_format_type_key || set_format_type_key == :base_format
|
100
107
|
end
|
@@ -107,6 +114,12 @@ class Card
|
|
107
114
|
format_class = Card::Format.format_class format: format_sym
|
108
115
|
Card::Set.modules[set_format_type_key][format_class][shortname] || []
|
109
116
|
end
|
117
|
+
|
118
|
+
def num_set_parts pattern_code
|
119
|
+
return 1 if pattern_code == :abstract
|
120
|
+
|
121
|
+
Pattern.find(pattern_code).anchor_parts_count
|
122
|
+
end
|
110
123
|
end
|
111
124
|
end
|
112
125
|
end
|
data/lib/card/set/registrar.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
class Card
|
4
4
|
module Set
|
5
5
|
# the set loading process has two main phases:
|
6
|
-
|
6
|
+
#
|
7
7
|
# 1. Definition: interpret each set file, creating/defining set and
|
8
8
|
# set_format modules
|
9
9
|
# 2. Organization: have base classes include modules associated with the
|
@@ -72,10 +72,8 @@ class Card
|
|
72
72
|
|
73
73
|
# makes sets ready for dynamic loading via #include_set_modules
|
74
74
|
def register_set_of_type set_module, set_type
|
75
|
-
|
76
|
-
|
77
|
-
mods[key] ||= []
|
78
|
-
mods[key] << set_module
|
75
|
+
list = modules[set_type][set_module.shortname] ||= []
|
76
|
+
list << set_module unless list.member? set_module
|
79
77
|
end
|
80
78
|
|
81
79
|
def process_base_format_modules base_format_modules
|
@@ -18,11 +18,12 @@ class Card
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def parent_event_name
|
21
|
-
[parent_set.
|
21
|
+
[parent_set.underscored_name, "requires_field", field].join("__").to_sym
|
22
22
|
end
|
23
23
|
|
24
24
|
def field_event_name action
|
25
|
-
[field, "required_by", parent_set.
|
25
|
+
[field, "required_by", parent_set.underscored_name, "on", action]
|
26
|
+
.join("__").to_sym
|
26
27
|
end
|
27
28
|
|
28
29
|
private
|
data/lib/card/set/type.rb
CHANGED
data/lib/card/set.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
class Card
|
4
|
-
#
|
5
4
|
# A _Set_ is a group of {Card Cards} to which _Rules_ may apply. Sets can be as
|
6
5
|
# specific as a single card, as general as all cards, or anywhere in between.
|
7
6
|
#
|
@@ -11,39 +10,86 @@ class Card
|
|
11
10
|
# web interface and are thus documented at https://decko.org/rules.
|
12
11
|
# - **Code rules** can be defined in a 'set module'.
|
13
12
|
#
|
14
|
-
#
|
15
|
-
#
|
13
|
+
# ## Set Modules
|
14
|
+
#
|
15
|
+
# ### File structure
|
16
|
+
#
|
17
|
+
# Set modules specify views, events, and other methods for a given set of cards.
|
18
|
+
# They are defined in a {Cardio::Mod mod's} _set_ directory. For example, suppose
|
19
|
+
# you've created a mod called *biz*, your deck has Company cards, and you want to
|
20
|
+
# extend the behavior of those cards.
|
21
|
+
#
|
22
|
+
# You can add a set module like so:
|
23
|
+
#
|
24
|
+
# card generate set biz type company
|
25
|
+
#
|
26
|
+
# This will create the following two files:
|
27
|
+
#
|
28
|
+
# mod/biz/set/type/company.rb
|
29
|
+
# mod/biz/spec/set/type/company.rb
|
30
|
+
#
|
31
|
+
# If you would like to break this code into smaller files, you can extend this
|
32
|
+
# pattern into another directory, eg:
|
33
|
+
#
|
34
|
+
# mod/biz/set/type/company/foo.rb
|
35
|
+
# mod/biz/set/type/company/bar.rb
|
36
|
+
#
|
37
|
+
# The general pattern can be expressed as follows:
|
38
|
+
#
|
39
|
+
# DECKNAME/mod/MODNAME/set/SET_PATTERN/ANCHOR[/FREENAME].rb
|
16
40
|
#
|
17
|
-
#
|
18
|
-
# and
|
41
|
+
# **Note:** _the set module's filename connects it to the set, so both the set_pattern
|
42
|
+
# and the set_anchor must correspond to the codename of a card in the database to
|
43
|
+
# function correctly. For example, the type/company directory corresponds to the Set
|
44
|
+
# card named `:company+:type`. Both the :company and :type codenames must exist for this
|
45
|
+
# to work properly._
|
46
|
+
#
|
47
|
+
# ### Writing/Editing set modules
|
48
|
+
#
|
49
|
+
# A set module is mostly standard ruby, but the files are quite concise because
|
50
|
+
#
|
51
|
+
# 1. the set module's file location is used to autogenerate ruby module definitions
|
52
|
+
# 2. A DSL (Domain-Specific Language) makes common tasks easy.
|
53
|
+
#
|
54
|
+
# You can, for example, edit `mod/biz/set/type/company.rb`, and add _only_ the
|
55
|
+
# following code:
|
56
|
+
#
|
57
|
+
# def hello
|
58
|
+
# "world"
|
59
|
+
# end
|
19
60
|
#
|
20
|
-
#
|
61
|
+
# No further code is needed for this method to be available to cards with the type
|
62
|
+
# Company (as specified by the file's location). This code will automatically be added
|
63
|
+
# to a ruby module named `Card::Set::Type::Company`. That module is extended with the
|
64
|
+
# {Card::Set} module, giving it access to the set module DSL.
|
21
65
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
66
|
+
# These important Card::Set subclasses explain more about the DSL
|
67
|
+
#
|
68
|
+
# - {Format} introduces format blocks
|
69
|
+
# - {Format::AbstractFormat} covers {Format::AbstractFormat#view view} definitions
|
70
|
+
# - {Event::Api} explains {Event::Api#event event} definitions
|
71
|
+
#
|
72
|
+
# ### Loading set modules
|
73
|
+
#
|
74
|
+
# Whenever you fetch or instantiate a card, the card will automatically
|
75
|
+
# include code from all the set modules associated with sets of which it is a member.
|
25
76
|
#
|
26
77
|
# For example, say you have a Plaintext card named 'Philipp+address', and you have set
|
27
78
|
# files for the following sets:
|
28
79
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
80
|
+
# * all cards
|
81
|
+
# * all Plaintext cards
|
82
|
+
# * all cards ending in +address
|
32
83
|
#
|
33
|
-
# When you run
|
84
|
+
# When you run any of these:
|
34
85
|
#
|
35
|
-
# mycard = Card.fetch
|
86
|
+
# mycard = Card.fetch "Philipp+address"
|
87
|
+
# mycard = "Philipp+address".card
|
88
|
+
# mycard = ["Philipp", "address"].card
|
36
89
|
#
|
37
90
|
# ...then mycard will include the set modules associated with each of those sets in the
|
38
91
|
# above order.
|
39
92
|
#
|
40
|
-
# Note that the set module's filename connects it to the set, so both the set_pattern
|
41
|
-
# and the set_anchor must correspond to the codename of a card in the database to
|
42
|
-
# function correctly.
|
43
|
-
#
|
44
|
-
# A set module is "just ruby", but is generally quite concise because Card uses
|
45
|
-
# a) the set module's file location to autogenerate ruby module names and
|
46
|
-
# b) Card::Set to provide API for the most common set methods.
|
47
93
|
#
|
48
94
|
module Set
|
49
95
|
include Event::Api
|