openhab-jrubyscripting 5.0.0.rc11 → 5.0.0.rc.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openhab/core/actions/exec.rb +41 -41
  3. data/lib/openhab/core/actions/transformation.rb +3 -3
  4. data/lib/openhab/core/actions.rb +1 -1
  5. data/lib/openhab/core/events/item_command_event.rb +31 -31
  6. data/lib/openhab/core/events/item_state_changed_event.rb +41 -18
  7. data/lib/openhab/core/events/item_state_event.rb +46 -18
  8. data/lib/openhab/core/items/date_time_item.rb +3 -2
  9. data/lib/openhab/core/items/generic_item.rb +119 -1
  10. data/lib/openhab/core/items/item.rb +63 -9
  11. data/lib/openhab/core/items/metadata/hash.rb +1 -1
  12. data/lib/openhab/core/items/metadata/namespace_hash.rb +10 -2
  13. data/lib/openhab/core/items/metadata/provider.rb +2 -2
  14. data/lib/openhab/core/items/persistence.rb +48 -4
  15. data/lib/openhab/core/items/provider.rb +4 -0
  16. data/lib/openhab/core/items/registry.rb +10 -1
  17. data/lib/openhab/core/items/semantics/enumerable.rb +29 -6
  18. data/lib/openhab/core/items/state_storage.rb +2 -2
  19. data/lib/openhab/core/items.rb +6 -13
  20. data/lib/openhab/core/provider.rb +2 -2
  21. data/lib/openhab/core/proxy.rb +5 -0
  22. data/lib/openhab/core/registry.rb +12 -2
  23. data/lib/openhab/core/rules/provider.rb +0 -15
  24. data/lib/openhab/core/rules.rb +1 -1
  25. data/lib/openhab/core/script_handling.rb +8 -8
  26. data/lib/openhab/core/things/links/provider.rb +38 -0
  27. data/lib/openhab/core/things/provider.rb +4 -0
  28. data/lib/openhab/core/things/registry.rb +4 -0
  29. data/lib/openhab/core/timer.rb +3 -19
  30. data/lib/openhab/core/types/date_time_type.rb +1 -1
  31. data/lib/openhab/core/types/decimal_type.rb +4 -9
  32. data/lib/openhab/core/types/hsb_type.rb +2 -2
  33. data/lib/openhab/core/types/quantity_type.rb +4 -9
  34. data/lib/openhab/core/types/string_type.rb +1 -1
  35. data/lib/openhab/core/types/type.rb +8 -28
  36. data/lib/openhab/core/types.rb +16 -3
  37. data/lib/openhab/core.rb +3 -3
  38. data/lib/openhab/core_ext/java/duration.rb +2 -0
  39. data/lib/openhab/core_ext/java/local_date.rb +15 -7
  40. data/lib/openhab/core_ext/java/local_time.rb +13 -3
  41. data/lib/openhab/core_ext/java/month.rb +1 -1
  42. data/lib/openhab/core_ext/java/month_day.rb +13 -3
  43. data/lib/openhab/core_ext/java/period.rb +1 -1
  44. data/lib/openhab/core_ext/java/temporal_amount.rb +1 -1
  45. data/lib/openhab/core_ext/java/time.rb +5 -1
  46. data/lib/openhab/core_ext/java/zoned_date_time.rb +15 -2
  47. data/lib/openhab/core_ext/ruby/date.rb +2 -2
  48. data/lib/openhab/core_ext/ruby/{class.rb → module.rb} +3 -3
  49. data/lib/openhab/core_ext/ruby/numeric.rb +6 -1
  50. data/lib/openhab/dsl/items/builder.rb +25 -12
  51. data/lib/openhab/dsl/items/ensure.rb +8 -6
  52. data/lib/openhab/dsl/rules/automation_rule.rb +2 -23
  53. data/lib/openhab/dsl/rules/builder.rb +47 -2
  54. data/lib/openhab/dsl/rules/terse.rb +15 -13
  55. data/lib/openhab/dsl/timer_manager.rb +1 -1
  56. data/lib/openhab/dsl/version.rb +1 -1
  57. data/lib/openhab/dsl.rb +38 -11
  58. data/lib/openhab/osgi.rb +1 -3
  59. data/lib/openhab/rspec/helpers.rb +3 -5
  60. data/lib/openhab/rspec/hooks.rb +1 -0
  61. data/lib/openhab/rspec/mocks/timer.rb +33 -0
  62. data/lib/openhab/rspec.rb +9 -0
  63. metadata +23 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc3911eb787dc73ea31109aa6d4d8c3896a1019b381a70030f152c668f0b8f2e
4
- data.tar.gz: ebd2d7005e9f17827a4bf58d38b7fc2476a497cb428aab0270290c3c98461b80
3
+ metadata.gz: 8ef6b7b058463c4bbcbc500b23baf44e1ef8f3872c39f88f3819875523b9d350
4
+ data.tar.gz: f2c5511e9c61eb79a1464161d35ba239570e45172be44415784994688a789c67
5
5
  SHA512:
6
- metadata.gz: df4c1df793cd44700467728c63df6ba9d12ecf7111fc7daf2b9a8f4953c68575082f9f4b87f70a42bfedcc9af70d4537e45b6fb2d8b78ac8e7e3f7cca22aaf4b
7
- data.tar.gz: de1c8f5847bbbeb3eed3268ceedc2a61213b4f6ab269372a08bd4d8217f6b384a2c62b5ceb1f9de2777d264d0d6eb4e02fde6f245fa4fcc0dc03d068041a11bb
6
+ metadata.gz: 7b4aca0a4cb592c7bcb84c4c50772d359cfc704f4bccb31e3aa58a1e76be0e15de9276c0184bcd696aed1c05cb7361e0f4d74f892eb9347f0a43f54ac596ecdb
7
+ data.tar.gz: 1053d9bd85f8013bcfa37242f1354e333587884179f8600c4f48ad19c5d1aa8cfdbb7795a32b37147d83d1b11334cb993663e761c4a0c2cf9574b5ec1355586e
@@ -4,47 +4,47 @@ module OpenHAB
4
4
  module Core
5
5
  module Actions
6
6
  # @see https://www.openhab.org/docs/configuration/actions.html#exec-actions Exec Actions
7
- class Exec
8
- class << self # rubocop:disable Lint/EmptyClass
9
- # @!method execute_command_line
10
- #
11
- # @return [void]
12
- #
13
- # @overload execute_command_line(command_line)
14
- #
15
- # Executes a command on the command line without waiting for the
16
- # command to complete.
17
- #
18
- # @param [String] command_line
19
- # @return [void]
20
- #
21
- # @example Execute an external command
22
- # rule 'Run a command' do
23
- # every :day
24
- # run do
25
- # Exec.execute_command_line('/bin/true')
26
- # end
27
- # end
28
- #
29
- # @overload execute_command_line(timeout, command_line)
30
- #
31
- # Executes a command on the command and waits timeout seconds for
32
- # the command to complete, returning the output from the command
33
- # as a String.
34
- #
35
- # @param [Duration] timeout
36
- # @param [String] command_line
37
- # @return [String]
38
- #
39
- # @example Execute an external command and process its results
40
- # rule 'Run a command' do
41
- # every :day
42
- # run do
43
- # TodaysHoliday_String.update(Exec.execute_command_line(5.seconds, '/home/cody/determine_holiday.rb')
44
- # end
45
- # end
46
- #
47
- end
7
+ class Exec # rubocop:disable Lint/EmptyClass
8
+ # @!scope class
9
+
10
+ # @!method execute_command_line
11
+ #
12
+ # @return [void]
13
+ #
14
+ # @overload execute_command_line(command_line)
15
+ #
16
+ # Executes a command on the command line without waiting for the
17
+ # command to complete.
18
+ #
19
+ # @param [String] command_line
20
+ # @return [void]
21
+ #
22
+ # @example Execute an external command
23
+ # rule 'Run a command' do
24
+ # every :day
25
+ # run do
26
+ # Exec.execute_command_line('/bin/true')
27
+ # end
28
+ # end
29
+ #
30
+ # @overload execute_command_line(timeout, command_line)
31
+ #
32
+ # Executes a command on the command and waits timeout seconds for
33
+ # the command to complete, returning the output from the command
34
+ # as a String.
35
+ #
36
+ # @param [Duration] timeout
37
+ # @param [String] command_line
38
+ # @return [String]
39
+ #
40
+ # @example Execute an external command and process its results
41
+ # rule 'Run a command' do
42
+ # every :day
43
+ # run do
44
+ # TodaysHoliday_String.update(Exec.execute_command_line(5.seconds, '/home/cody/determine_holiday.rb')
45
+ # end
46
+ # end
47
+ #
48
48
  end
49
49
  end
50
50
  end
@@ -7,7 +7,7 @@ module OpenHAB
7
7
  class Transformation
8
8
  class << self
9
9
  # @!visibility private
10
- alias_method :transform_raw, :transform if instance_methods.include?(:say)
10
+ alias_method :raw_transform, :transform if instance_methods.include?(:transform)
11
11
 
12
12
  #
13
13
  # Applies a transformation of a given type with some function to a value.
@@ -20,10 +20,10 @@ module OpenHAB
20
20
  # @return [String] the transformed value, or the original value if an error occurred
21
21
  #
22
22
  # @example Run a transformation
23
- # Transformation.transform(:map, "myfan.map", 0)
23
+ # transform(:map, "myfan.map", 0)
24
24
  #
25
25
  def transform(type, function, value)
26
- transform_raw(type.to_s.upcase, function.to_s, value.to_s)
26
+ raw_transform(type.to_s.upcase, function.to_s, value.to_s)
27
27
  end
28
28
  end
29
29
  end
@@ -43,7 +43,7 @@ module OpenHAB
43
43
  end
44
44
 
45
45
  # Import common actions
46
- %w[Exec HTTP Ping].each do |action|
46
+ %w[Exec HTTP Ping Transformation].each do |action|
47
47
  klass = (java_import "org.openhab.core.model.script.actions.#{action}").first
48
48
  Object.const_set(action, klass)
49
49
  end
@@ -7,71 +7,71 @@ module OpenHAB
7
7
  module Events
8
8
  java_import org.openhab.core.items.events.ItemCommandEvent
9
9
 
10
- # Adds methods to core openHAB ItemCommandEvent to make it more natural in Ruby
10
+ # {AbstractEvent} sent when an item receives a command.
11
11
  class ItemCommandEvent < ItemEvent
12
12
  # @!attribute [r] command
13
13
  # @return [Command] The command sent to the item.
14
14
  alias_method :command, :item_command
15
15
 
16
16
  # @!method refresh?
17
- # Check if `self == REFRESH`
18
- # @return [true,false]
17
+ # Check if {#command} is {REFRESH}
18
+ # @return [true, false]
19
19
 
20
20
  # @!method on?
21
- # Check if `self == ON`
22
- # @return [true,false]
21
+ # Check if {#command} is (implicitly convertible to) {ON}
22
+ # @return [true, false]
23
23
 
24
24
  # @!method off?
25
- # Check if `self == OFF`
26
- # @return [true,false]
25
+ # Check if {#command} is (implicitly convertible to) {OFF}
26
+ # @return [true, false]
27
27
 
28
28
  # @!method up?
29
- # Check if `self == UP`
30
- # @return [true,false]
29
+ # Check if {#command} is (implicitly convertible to) {UP}
30
+ # @return [true, false]
31
31
 
32
32
  # @!method down?
33
- # Check if `self == DOWN`
34
- # @return [true,false]
33
+ # Check if {#command} is (implicitly convertible to) {DOWN}
34
+ # @return [true, false]
35
35
 
36
36
  # @!method stop?
37
- # Check if `self == STOP`
38
- # @return [true,false]
37
+ # Check if {#command} is {STOP}
38
+ # @return [true, false]
39
39
 
40
40
  # @!method move?
41
- # Check if `self == MOVE`
42
- # @return [true,false]
41
+ # Check if {#command} is {MOVE}
42
+ # @return [true, false]
43
43
 
44
44
  # @!method increase?
45
- # Check if `self == INCREASE`
46
- # @return [true,false]
45
+ # Check if {#command} is {INCREASE}
46
+ # @return [true, false]
47
47
 
48
48
  # @!method decrease?
49
- # Check if `self == DECREASE`
50
- # @return [true,false]
49
+ # Check if {#command} is {DECREASE}
50
+ # @return [true, false]
51
51
 
52
52
  # @!method play?
53
- # Check if `self == PLAY`
54
- # @return [true,false]
53
+ # Check if {#command} is {PLAY}
54
+ # @return [true, false]
55
55
 
56
56
  # @!method pause?
57
- # Check if `self == PAUSE`
58
- # @return [true,false]
57
+ # Check if {#command} is {PAUSE}
58
+ # @return [true, false]
59
59
 
60
60
  # @!method rewind?
61
- # Check if `self == REWIND`
62
- # @return [true,false]
61
+ # Check if {#command} is {REWIND}
62
+ # @return [true, false]
63
63
 
64
64
  # @!method fast_forward?
65
- # Check if `self == FASTFORWARD`
66
- # @return [true,false]
65
+ # Check if {#command} is {FASTFORWARD}
66
+ # @return [true, false]
67
67
 
68
68
  # @!method next?
69
- # Check if `self == NEXT`
70
- # @return [true,false]
69
+ # Check if {#command} is {NEXT}
70
+ # @return [true, false]
71
71
 
72
72
  # @!method previous?
73
- # Check if `self == PREVIOUS`
74
- # @return [true,false]
73
+ # Check if {#command} is {PREVIOUS}
74
+ # @return [true, false]
75
75
  end
76
76
  end
77
77
  end
@@ -8,32 +8,55 @@ module OpenHAB
8
8
  java_import org.openhab.core.items.events.ItemStateChangedEvent
9
9
 
10
10
  #
11
- # Adds methods to core openHAB ItemStateChangedEvent to make it more natural in Ruby
11
+ # {AbstractEvent} sent when an item's state has changed.
12
12
  #
13
13
  class ItemStateChangedEvent < ItemEvent
14
14
  include ItemState
15
15
 
16
- #
17
- # Check if state was == {UNDEF}
18
- #
19
- # @return [true,false] True if the state is {UNDEF}, false otherwise
20
- #
21
- def was_undef?
22
- old_item_state == UNDEF
23
- end
16
+ # @!method was_undef?
17
+ # Check if {#was} is {UNDEF}
18
+ # @return [true, false]
24
19
 
25
- #
26
- # Check if state was == {NULL}
27
- #
28
- # @return [true,false] True if the state is {NULL}, false otherwise
29
- def was_null?
30
- old_item_state == NULL
31
- end
20
+ # @!method was_null?
21
+ # Check if {#was} is {NULL}
22
+ # @return [true, false]
23
+
24
+ # @!method was_on?
25
+ # Check if {#was} is (implicitly convertible to) {ON}
26
+ # @return [true, false]
27
+
28
+ # @!method was_off?
29
+ # Check if {#was} is (implicitly convertible to) {OFF}
30
+ # @return [true, false]
31
+
32
+ # @!method was_up?
33
+ # Check if {#was} is (implicitly convertible to) {UP}
34
+ # @return [true, false]
35
+
36
+ # @!method was_down?
37
+ # Check if {#was} is (implicitly convertible to) {DOWN}
38
+ # @return [true, false]
39
+
40
+ # @!method was_open?
41
+ # Check if {#was} is (implicitly convertible to) {OPEN}
42
+ # @return [true, false]
43
+
44
+ # @!method was_closed?
45
+ # Check if {#was} is (implicitly convertible to) {CLOSED}
46
+ # @return [true, false]
47
+
48
+ # @!method was_playing?
49
+ # Check if {#was} is {PLAY}
50
+ # @return [true, false]
51
+
52
+ # @!method was_paused?
53
+ # Check if {#was} is {PAUSE}
54
+ # @return [true, false]
32
55
 
33
56
  #
34
57
  # Check if state was defined (not {UNDEF} or {NULL})
35
58
  #
36
- # @return [true,false] True if state is not {UNDEF} or {NULL}
59
+ # @return [true,false]
37
60
  #
38
61
  def was?
39
62
  !old_item_state.is_a?(UnDefType)
@@ -41,7 +64,7 @@ module OpenHAB
41
64
 
42
65
  #
43
66
  # @!attribute [r] was
44
- # @return [State, nil] The state of the item if it was not {UNDEF} or {NULL}, `nil` otherwise.
67
+ # @return [State, nil] the prior state of the item if it was not {UNDEF} or {NULL}, `nil` otherwise.
45
68
  #
46
69
  def was
47
70
  old_item_state if was?
@@ -5,29 +5,57 @@ module OpenHAB
5
5
  module Events
6
6
  java_import org.openhab.core.items.events.ItemStateEvent
7
7
 
8
+ #
8
9
  # Helpers common to {ItemStateEvent} and {ItemStateChangedEvent}.
10
+ #
11
+ # Methods that refer to implicit conversion mean that for example
12
+ # a PercentType of 100% will be `true` for {#on?}, etc.
13
+ #
9
14
  module ItemState
10
- #
11
- # Check if the state == {UNDEF}
12
- #
13
- # @return [true,false] True if the state is {UNDEF}, false otherwise
14
- #
15
- def undef?
16
- item_state == UNDEF
17
- end
15
+ # @!method undef?
16
+ # Check if {#state} is {UNDEF}
17
+ # @return [true, false]
18
18
 
19
- #
20
- # Check if the state == {NULL}
21
- #
22
- # @return [true,false] True if the state is {NULL}, false otherwise
23
- def null?
24
- item_state == NULL
25
- end
19
+ # @!method null?
20
+ # Check if {#state} is {NULL}
21
+ # @return [true, false]
22
+
23
+ # @!method on?
24
+ # Check if {#state} is (implicitly convertible to) {ON}
25
+ # @return [true, false]
26
+
27
+ # @!method off?
28
+ # Check if {#state} is (implicitly convertible to) {OFF}
29
+ # @return [true, false]
30
+
31
+ # @!method up?
32
+ # Check if {#state} is (implicitly convertible to) {UP}
33
+ # @return [true, false]
34
+
35
+ # @!method down?
36
+ # Check if {#state} is (implicitly convertible to) {DOWN}
37
+ # @return [true, false]
38
+
39
+ # @!method open?
40
+ # Check if {#state} is (implicitly convertible to) {OPEN}
41
+ # @return [true, false]
42
+
43
+ # @!method closed?
44
+ # Check if {#state} is (implicitly convertible to) {CLOSED}
45
+ # @return [true, false]
46
+
47
+ # @!method playing?
48
+ # Check if {#state} is {PLAY}
49
+ # @return [true, false]
50
+
51
+ # @!method paused?
52
+ # Check if {#state} is {PAUSE}
53
+ # @return [true, false]
26
54
 
27
55
  #
28
- # Check if the state is defined (not {UNDEF} or {NULL})
56
+ # Check if {#state} is defined (not {UNDEF} or {NULL})
29
57
  #
30
- # @return [true,false] True if state is not {UNDEF} or {NULL}
58
+ # @return [true, false]
31
59
  #
32
60
  def state?
33
61
  !item_state.is_a?(UnDefType)
@@ -35,7 +63,7 @@ module OpenHAB
35
63
 
36
64
  #
37
65
  # @!attribute [r] state
38
- # @return [State, nil] The state of the item if it is not {UNDEF} or {NULL}, `nil` otherwise.
66
+ # @return [State, nil] the state of the item if it is not {UNDEF} or {NULL}, `nil` otherwise.
39
67
  #
40
68
  def state
41
69
  item_state if state?
@@ -45,9 +45,10 @@ module OpenHAB
45
45
  # Time types need formatted as ISO8601
46
46
  # @!visibility private
47
47
  def format_type(command)
48
- return Types::DateTimeType.new(command) if command.is_a?(java.time.ZonedDateTime)
48
+ return command if command.is_a?(Types::DateTimeType)
49
+ return Types::DateTimeType.new(command.to_zoned_date_time) if command.respond_to?(:to_zoned_date_time)
50
+ return Types::DateTimeType.new(DSL.try_parse_time_like(command.to_str)) if command.respond_to?(:to_str)
49
51
 
50
- command = command.iso8601 if command.respond_to?(:iso8601)
51
52
  super
52
53
  end
53
54
  end
@@ -71,6 +71,34 @@ module OpenHAB
71
71
  !raw_state.is_a?(Types::UnDefType)
72
72
  end
73
73
 
74
+ # @!attribute [r] formatted_state
75
+ #
76
+ # Format the item's state according to its state description
77
+ #
78
+ # This may include running a transformation.
79
+ #
80
+ # @return [String]
81
+ #
82
+ # @example
83
+ # logger.info(Exterior_WindDirection.formatted_state) # => "NE (36°)"
84
+ #
85
+ def formatted_state
86
+ # use to_string, not to_s, to get the original openHAB toString(), instead of any overrides
87
+ # the JRuby library has defined
88
+ raw_state_string = raw_state.to_string
89
+
90
+ return raw_state_string unless (pattern = state_description&.pattern)
91
+
92
+ transformed_state_string = org.openhab.core.transform.TransformationHelper.transform(OSGi.bundle_context,
93
+ pattern,
94
+ raw_state_string)
95
+ return state.format(pattern) if transformed_state_string.nil? || transformed_state_string == raw_state_string
96
+
97
+ transformed_state_string
98
+ rescue org.openhab.core.transform.TransformationException
99
+ raw_state_string
100
+ end
101
+
74
102
  #
75
103
  # @!attribute [r] state
76
104
  # @return [State, nil]
@@ -153,7 +181,7 @@ module OpenHAB
153
181
  return state if state.is_a?(Types::State)
154
182
 
155
183
  state = state.to_s
156
- org.openhab.core.types.TypeParser.parse_state(getAcceptedDataTypes, state) || state
184
+ org.openhab.core.types.TypeParser.parse_state(getAcceptedDataTypes, state) || StringType.new(state)
157
185
  end
158
186
 
159
187
  # formats a {Types::Type} to send to the event bus
@@ -163,9 +191,99 @@ module OpenHAB
163
191
  # make sure to use Type, because this method is used for both
164
192
  # #update and #command
165
193
  return type if type.is_a?(Types::Type)
194
+ return NULL if type.nil?
166
195
 
167
196
  type.to_s
168
197
  end
198
+
199
+ #
200
+ # Defers notifying openHAB of modifications to multiple attributes until the block is complete.
201
+ #
202
+ # @param [true, false] force When true, allow modifications to file-based items.
203
+ # Normally a FrozenError is raised when attempting to modify file-based items, since
204
+ # they will then be out-of-sync with the definition on disk. Advanced users may do this
205
+ # knowingly and intentionally though, so an escape hatch is provided to allow runtime
206
+ # modifications.
207
+ # @yield
208
+ # @return [Object] the block's return value
209
+ #
210
+ # @example Modify label and tags for an item
211
+ # MySwitch.modify do
212
+ # MySwitch.label = "New Label"
213
+ # MySwitch.tags = :labeled
214
+ # end
215
+ #
216
+ def modify(force: false)
217
+ raise ArgumentError, "you must pass a block to modify" unless block_given?
218
+ return yield if instance_variable_defined?(:@modifying) && @modifying
219
+
220
+ begin
221
+ provider = self.provider
222
+ if provider && !provider.is_a?(org.openhab.core.common.registry.ManagedProvider)
223
+ raise FrozenError, "Cannot modify item #{name} from provider #{provider.inspect}." unless force
224
+
225
+ provider = nil
226
+ logger.debug("Forcing modifications to non-managed item #{name}")
227
+ end
228
+ @modified = false
229
+ @modifying = true
230
+
231
+ r = yield
232
+
233
+ provider&.update(self) if @modified
234
+ r
235
+ ensure
236
+ @modifying = false
237
+ end
238
+ end
239
+
240
+ # @!attribute [rw] label
241
+ # The item's descriptive label.
242
+ # @return [String]
243
+ def label=(value)
244
+ modify do
245
+ next if label == value
246
+
247
+ @modified = true
248
+ set_label(value)
249
+ end
250
+ end
251
+
252
+ # @!attribute [rw] category
253
+ # The item's category.
254
+ # @return [String]
255
+ def category=(value)
256
+ modify do
257
+ value = value&.to_s
258
+ next if category == value
259
+
260
+ @modified = true
261
+ set_category(value)
262
+ end
263
+ end
264
+
265
+ # @!attribute [rw] tags
266
+ # The item's tags
267
+ # @return [Array<String>]
268
+ # @overload tags
269
+ # Returns the item's tags.
270
+ # @return [Array<String>]
271
+ # @overload tags=(values)
272
+ # Sets the item's tags.
273
+ #
274
+ # To remove all tags, assign an empty array or nil.
275
+ # @param [Array<String,Symbol,Semantics::Tag>] values Tags to set.
276
+ # @return [void]
277
+ def tags=(values)
278
+ modify do
279
+ values = DSL::Items::ItemBuilder.normalize_tags(*values)
280
+ next if values.to_set == tags.to_set
281
+
282
+ @modified = true
283
+ remove_all_tags
284
+ add_tags(values)
285
+ end
286
+ end
169
287
  end
170
288
  end
171
289
  end