discorb 0.5.4 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62a9092a32b87c1edbb193c7b3de777b499257a9b08f92f88a741506ecef58fe
4
- data.tar.gz: 3df9d14c6c7ec041d9887b3479af2417295e17b148c1aea780230e84b5c0d799
3
+ metadata.gz: 4d2ef47227e1e5895bdcaf6a67641d22319909c0f6a461d72ab35be1e0c9a42b
4
+ data.tar.gz: 688a952b571421e8c43ca53b10f9404f6ba2abf8b9071222c35d3a10e34c5b7e
5
5
  SHA512:
6
- metadata.gz: f26088e7ce6f9a4bd5877263cc716722ca3523047df3623e49a082940251d3a97cea81c289239a3c9f0b456f9a21ee637f1adcd8e804084550b6af10c2aea02b
7
- data.tar.gz: bda9f44c79c089e7cf55eeef4e774c20e3891baf09e0eb73fd2faa6e9337e5abca02b66c0e5e2c2db386d136144441f34afdf306bb427b3fcf40fa8f85f875ae
6
+ metadata.gz: 9fd5eb78a1acda90e3c673a8745a2a9954ff8b8817c38210c5c609e6a85b16e4074b59bf8ae7bcc7725f7f45f22dfd785fb5edd321e9f61994bb071e4aa25a43
7
+ data.tar.gz: 4bee75498af33d4716e033f51103382d8931c079495d27234cf07cf5e5b288891b40fb7e00902d3c1d7150249d0c820701d9962130890005bea5378e46af5ac8
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: Bug Report
3
+ about: A bug report for discorb.
4
+ labels:
5
+ - bug
6
+ ---
7
+
8
+ <!--
9
+ Before submitting a bug report, please check that it is not already being, or has been, reported.
10
+ Don't forget to find closed issues and check if the bug is already fixed.
11
+ -->
12
+
13
+ ## What is the bug?
14
+
15
+ <!--
16
+ Please describe the bug in detail.
17
+ Ex:
18
+ I want to sleep, but I can't.
19
+ -->
20
+
21
+ ## What steps did you take to reproduce the bug?
22
+
23
+ <!--
24
+ Please describe the steps you took to reproduce the bug.
25
+ Ex:
26
+ 1. Go to bed
27
+ 2. Count sheeps
28
+ 3. Observe
29
+ -->
30
+
31
+ ## What did you expect to see?
32
+
33
+ <!--
34
+ Please describe what you expected to see.
35
+ Ex:
36
+ I can sleep.
37
+ -->
38
+
39
+ ## What did you see instead?
40
+
41
+ <!--
42
+ Please describe what you saw instead.
43
+ Ex:
44
+ I can't sleep.
45
+ -->
46
+
47
+ ## Environment information
48
+
49
+ <!--
50
+ Use `discorb show` to get the current machine.
51
+ -->
52
+
53
+ ## Other information
54
+
55
+ <!--
56
+ Please describe any other information you want to include as such as the screenshots you took, or the logs you generated.
57
+ -->
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Documentation
4
+ url: https://discorb-lib.github.io/
5
+ about: Read the documentation first.
6
+ - name: Official Guild
7
+ url: https://discord.gg/hCP6zq8Vpj
8
+ about: Join the official Guild.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Feature Request
3
+ labels:
4
+ - Feature Request
5
+ - Enhancement
6
+ about: Feature request for discorb's future.
7
+ ---
8
+ <!--
9
+ Before submitting a feature request, please check there is no existing feature request for the feature you are requesting.
10
+ -->
11
+
12
+
13
+ ## What is the feature you are requesting?
14
+
15
+ <!--
16
+ Please describe the feature you are requesting.
17
+ Ex: Create discorb-chan
18
+ -->
19
+
20
+ ## Why do you need the feature?
21
+
22
+ <!--
23
+ Please describe the reason for the feature you are requesting.
24
+ Ex: She's cute.
25
+ -->
26
+
27
+ ## Alternative considerations?
28
+
29
+ <!--
30
+ Please describe alternative considerations for the feature you are requesting.
31
+ Ex: Add discorb-kun
32
+ -->
33
+
34
+ ## Additional context
35
+
36
+ <!--
37
+ Please describe any additional context you have for the feature you are requesting.
38
+ -->
data/Changelog.md CHANGED
@@ -127,4 +127,26 @@
127
127
 
128
128
  ## 0.5.4
129
129
 
130
- - Fix: Fix issue of receiving component events
130
+ - Fix: Fix issue of receiving component events
131
+
132
+ ## 0.5.5
133
+
134
+ - Fix: Fix some bugs
135
+
136
+ ## 0.5.6
137
+
138
+ - Add: Raise error when intents are invalid
139
+ - Fix: Fix Emoji#==
140
+
141
+ ## 0.6.0
142
+
143
+ - Fix: Fix issue with client with no guilds
144
+ - Add: Add rbs (experimental)
145
+ - Add: Add `-t`, `--token` option to `discorb run`
146
+ - Add: Add `-g`, `--guild` option to `discorb setup`
147
+ - Change: Use `Async::Task<R>` instead of `R` in return value
148
+
149
+ ## 0.6.1
150
+
151
+ - Change: Rename `Event#discriminator` to `Event#metadata`
152
+ - Add: Add `:override` to `Client#on`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- discorb (0.5.4)
4
+ discorb (0.6.1)
5
5
  async (~> 1.30.1)
6
6
  async-http (~> 0.56.5)
7
7
  async-websocket (~> 0.19.0)
@@ -11,9 +11,9 @@ From: [Discord API docs](https://discord.com/developers/docs/interactions/applic
11
11
  ## How do I register an application command?
12
12
 
13
13
  Write to a your script:
14
- - {Discorb::Command::Handler.slash}, {Discorb::Command::Handler.slash_group} for slash commands,
15
- - {Discorb::Command::Handler.user_command} for user menu commands,
16
- - {Discorb::Command::Handler.message_command} for message menu commands.
14
+ - {Discorb::ApplicationCommand::Handler.slash}, {Discorb::ApplicationCommand::Handler.slash_group} for slash commands,
15
+ - {Discorb::ApplicationCommand::Handler.user_command} for user menu commands,
16
+ - {Discorb::ApplicationCommand::Handler.message_command} for message menu commands.
17
17
 
18
18
  And then run `discorb setup` to register your application commands.
19
19
  {file:docs/cli/setup.md Learn more about `discorb setup`}.
@@ -39,7 +39,7 @@ end
39
39
  client.run(ENV["DISCORD_BOT_TOKEN"])
40
40
  ```
41
41
 
42
- {Discorb::Command::Handler#slash} takes 5 arguments:
42
+ {Discorb::ApplicationCommand::Handler#slash} takes 5 arguments:
43
43
 
44
44
  | Argument | Description |
45
45
  |---------|-------------|
@@ -107,7 +107,7 @@ In `type`, You must use one of the following:
107
107
 
108
108
  ### Group Slash Commands
109
109
 
110
- To register a group of slash commands, use {Discorb::Command::Handler#slash_group}.
110
+ To register a group of slash commands, use {Discorb::ApplicationCommand::Handler#slash_group}.
111
111
 
112
112
  ```ruby
113
113
  group = client.slash_group("settings", "Set settings of bot.")
@@ -156,7 +156,7 @@ client.slash_group("settings", "Set settings of bot.") do
156
156
  end
157
157
  ```
158
158
 
159
- You can make subcommand group by using {Discorb::Command::Command::GroupCommand#group}.
159
+ You can make subcommand group by using {Discorb::ApplicationCommand::Command::GroupCommand#group}.
160
160
 
161
161
  ```ruby
162
162
  group = client.slash_group("permission", "Set/Get command permissions.")
@@ -244,7 +244,7 @@ client.user_command("hello") do |interaction, user|
244
244
  interaction.post("Hello, #{user.name}!")
245
245
  end
246
246
  ```
247
- {Discorb::Command::Handler.user_command} takes 3 arguments:
247
+ {Discorb::ApplicationCommand::Handler.user_command} takes 3 arguments:
248
248
 
249
249
  | Parameter | Description |
250
250
  | --- | --- |
@@ -268,7 +268,7 @@ client.message_command("Bookmark") do |interaction, message|
268
268
  end
269
269
  ```
270
270
 
271
- {Discorb::Command::Handler.message_command} takes 3 arguments:
271
+ {Discorb::ApplicationCommand::Handler.message_command} takes 3 arguments:
272
272
 
273
273
  | Parameter | Description |
274
274
  | --- | --- |
data/docs/cli/run.md CHANGED
@@ -17,6 +17,8 @@ discorb run [options] [script]
17
17
 
18
18
  The script to run. Defaults to `main.rb`.
19
19
 
20
+ ### Options
21
+
20
22
  #### `-d`, `--deamon`
21
23
 
22
24
  Run the client in deamon mode.
@@ -43,4 +45,12 @@ You can use `stdout` to write to the standard output, and `stderr` to write to t
43
45
  Whether to colorize the log output.
44
46
  If not specified, the default will be:
45
47
  - `true` if the file to write logs to is `stdout` or `stderr`.
46
- - `false` otherwise.
48
+ - `false` otherwise.
49
+
50
+ #### `-s`, `--setup`
51
+
52
+ Whether to setup application commands.
53
+
54
+ #### `-t`, `--token`
55
+
56
+ The name of the environment variable to use for token, or just `-t` or `--token` for intractive prompt.
data/docs/cli/setup.md CHANGED
@@ -7,7 +7,7 @@ This command will setup application commands.
7
7
  ## Usage
8
8
 
9
9
  ```
10
- discorb setup [script]
10
+ discorb setup [options] [script]
11
11
  ```
12
12
 
13
13
  ### Arguments
@@ -15,3 +15,9 @@ discorb setup [script]
15
15
  #### `script`
16
16
 
17
17
  The script to setup. Defaults to `main.rb`.
18
+
19
+ ### Options
20
+
21
+ #### `-g`, `--guild`
22
+
23
+ Guild IDs to use as default. Can be specified multiple IDs by using `,` as delimiter.
data/docs/events.md CHANGED
@@ -30,6 +30,35 @@ end
30
30
 
31
31
  If you want to seperate event handlers from the client, consider using {Discorb::Extension}. {file:docs/extension.md Learn more about extensions}.
32
32
 
33
+ Since v0.6.1, you can set `:override` to `true` to register overridable event handlers.
34
+
35
+ ```ruby
36
+ client.on :message, override: true do |event|
37
+ puts "This event handler is overrideable!"
38
+ end
39
+
40
+ client.on :message do |event|
41
+ puts "Override!"
42
+ end
43
+ ```
44
+
45
+ This example will print `Override!`, but not `This event handler is overrideable!`.
46
+ This is useful for registering event handlers for default behaviour on errors.
47
+
48
+ ```ruby
49
+ # In the library...
50
+
51
+ client.on :command_error, override: true do |event, error|
52
+ $stderr.puts "Command error:\n#{error.full_message}"
53
+ end
54
+
55
+ # In your code...
56
+
57
+ client.on :command_error do |event, error|
58
+ event.message.reply "An error occurred while executing that command!\n#{error.full_message}"
59
+ end
60
+ ```
61
+
33
62
  ## Event reference
34
63
 
35
64
  ### Client events
data/docs/extension.md CHANGED
@@ -36,7 +36,7 @@ end
36
36
 
37
37
  ## Register Command
38
38
 
39
- Since v0.5.2, {Discorb::Extension} includes {Discorb::Command::Handler} module, so you can register command with {Discorb::Command::Handler#slash} and {Discorb::Command::Handler#slash_group}.
39
+ Since v0.5.2, {Discorb::Extension} includes {Discorb::ApplicationCommand::Handler} module, so you can register command with {Discorb::ApplicationCommand::Handler#slash} and {Discorb::ApplicationCommand::Handler#slash_group}.
40
40
 
41
41
  ```ruby
42
42
  module MyExtension
@@ -4,9 +4,9 @@ module Discorb
4
4
  #
5
5
  # Handles application commands.
6
6
  #
7
- module Command
7
+ module ApplicationCommand
8
8
  #
9
- # Module to handle commands.
9
+ # Module to handle application commands.
10
10
  #
11
11
  module Handler
12
12
  #
@@ -24,15 +24,16 @@ module Discorb
24
24
  # | `:type` | `Object` | Type of the option. |
25
25
  # | `:choice` | `Hash{String => String, Integer, Float}` | Type of the option. |
26
26
  #
27
- # @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
27
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
28
28
  # @param [Proc] block Command block.
29
29
  #
30
- # @return [Discorb::Command::Command::SlashCommand]
30
+ # @return [Discorb::ApplicationCommand::Command::SlashCommand] Command object.
31
31
  #
32
32
  # @see file:docs/application_command.md#register-slash-command
33
+ # @see file:docs/cli/setup.md
33
34
  #
34
- def slash(command_name, description, options = {}, guild_ids: [], &block)
35
- command = Discorb::Command::Command::SlashCommand.new(command_name, description, options, guild_ids, block, 1, "")
35
+ def slash(command_name, description, options = {}, guild_ids: nil, &block)
36
+ command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, guild_ids, block, 1, "")
36
37
  @commands << command
37
38
  @bottom_commands << command
38
39
  command
@@ -43,17 +44,18 @@ module Discorb
43
44
  #
44
45
  # @param [String] command_name Command name.
45
46
  # @param [String] description Command description.
46
- # @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
47
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
47
48
  #
48
49
  # @yield Block to execute as the command. It can be used to define sub-commands.
49
- # @yieldself [Discorb::Command::Command::GroupCommand] Group command.
50
+ # @yieldself [Discorb::ApplicationCommand::Command::GroupCommand] Group command.
50
51
  #
51
- # @return [Discorb::Command::Command::GroupCommand] Command object.
52
+ # @return [Discorb::ApplicationCommand::Command::GroupCommand] Command object.
52
53
  #
53
54
  # @see file:docs/slash_command.md
55
+ # @see file:docs/cli/setup.md
54
56
  #
55
- def slash_group(command_name, description, guild_ids: [], &block)
56
- command = Discorb::Command::Command::GroupCommand.new(command_name, description, guild_ids, nil, self)
57
+ def slash_group(command_name, description, guild_ids: nil, &block)
58
+ command = Discorb::ApplicationCommand::Command::GroupCommand.new(command_name, description, guild_ids, nil, self)
57
59
  command.instance_eval(&block) if block_given?
58
60
  @commands << command
59
61
  command
@@ -63,16 +65,16 @@ module Discorb
63
65
  # Add message context menu command.
64
66
  #
65
67
  # @param [String] command_name Command name.
66
- # @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
68
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
67
69
  # @param [Proc] block Command block.
68
70
  # @yield [interaction, message] Block to execute.
69
- # @yieldparam [Discorb::CommandInteraction::UserMenuCommand] Interaction object.
70
- # @yieldparam [Discorb::Message] user Message object.
71
+ # @yieldparam [Discorb::ApplicationCommandInteraction::UserMenuCommand] interaction Interaction object.
72
+ # @yieldparam [Discorb::Message] message Message object.
71
73
  #
72
- # @return [Discorb::Command::Command] Command object.
74
+ # @return [Discorb::ApplicationCommand::Command] Command object.
73
75
  #
74
- def message_command(command_name, guild_ids: [], &block)
75
- command = Discorb::Command::Command.new(command_name, guild_ids, block, 3)
76
+ def message_command(command_name, guild_ids: nil, &block)
77
+ command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 3)
76
78
  @commands << command
77
79
  command
78
80
  end
@@ -81,16 +83,16 @@ module Discorb
81
83
  # Add user context menu command.
82
84
  #
83
85
  # @param [String] command_name Command name.
84
- # @param [Array<#to_s>] guild_ids Guild IDs to restrict the command to.
86
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
85
87
  # @param [Proc] block Command block.
86
88
  # @yield [interaction, user] Block to execute.
87
- # @yieldparam [Discorb::CommandInteraction::UserMenuCommand] Interaction object.
89
+ # @yieldparam [Discorb::ApplicationCommandInteraction::UserMenuCommand] interaction Interaction object.
88
90
  # @yieldparam [Discorb::User] user User object.
89
91
  #
90
- # @return [Discorb::Command::Command] Command object.
92
+ # @return [Discorb::ApplicationCommand::Command] Command object.
91
93
  #
92
- def user_command(command_name, guild_ids: [], &block)
93
- command = Discorb::Command::Command.new(command_name, guild_ids, block, 2)
94
+ def user_command(command_name, guild_ids: nil, &block)
95
+ command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 2)
94
96
  @commands << command
95
97
  command
96
98
  end
@@ -100,20 +102,32 @@ module Discorb
100
102
  # @see Client#initialize
101
103
  #
102
104
  # @param [String] token Bot token.
105
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to use as default. If `false` is given, it will be global command.
106
+ #
103
107
  # @note `token` parameter only required if you don't run client.
104
108
  #
105
- def setup_commands(token = nil)
109
+ def setup_commands(token = nil, guild_ids: nil)
106
110
  Async do
107
111
  @token ||= token
108
112
  @http = HTTP.new(self)
109
- global_commands = @commands.select { |c| c.guild_ids.empty? }
110
- guild_ids = Set[*@commands.map(&:guild_ids).flatten]
113
+ global_commands = @commands.select { |c| c.guild_ids == false or c.guild_ids == [] }
114
+ local_commands = @commands.select { |c| c.guild_ids.is_a?(Array) and c.guild_ids.any? }
115
+ default_commands = @commands.select { |c| c.guild_ids.nil? }
116
+ if guild_ids.is_a?(Array)
117
+ default_commands.each do |command|
118
+ command.instance_variable_set(:@guild_ids, guild_ids)
119
+ end
120
+ local_commands += default_commands
121
+ else
122
+ global_commands += default_commands
123
+ end
124
+ final_guild_ids = local_commands.map(&:guild_ids).flatten.map(&:to_s).uniq
111
125
  app_info = fetch_application.wait
112
126
  http.put("/applications/#{app_info.id}/commands", global_commands.map(&:to_hash)).wait unless global_commands.empty?
113
- guild_ids.each do |guild_id|
114
- commands = @commands.select { |c| c.guild_ids.include?(guild_id) }
127
+ final_guild_ids.each do |guild_id|
128
+ commands = local_commands.select { |c| c.guild_ids.include?(guild_id) }
115
129
  http.put("/applications/#{app_info.id}/guilds/#{guild_id}/commands", commands.map(&:to_hash)).wait
116
- end unless guild_ids.empty?
130
+ end unless final_guild_ids.empty?
117
131
  @log.info "Successfully setup commands"
118
132
  end
119
133
  end
@@ -146,10 +160,10 @@ module Discorb
146
160
  # @!visibility private
147
161
  def initialize(name, guild_ids, block, type)
148
162
  @name = name
149
- @guild_ids = guild_ids.map(&:to_s)
163
+ @guild_ids = guild_ids&.map(&:to_s)
150
164
  @block = block
151
165
  @raw_type = type
152
- @type = Discorb::Command::Command.types[type]
166
+ @type = Discorb::ApplicationCommand::Command.types[type]
153
167
  @type_raw = type
154
168
  @id_map = Discorb::Dictionary.new
155
169
  end
@@ -174,12 +188,8 @@ module Discorb
174
188
 
175
189
  # @!visibility private
176
190
  def initialize(name, description, options, guild_ids, block, type, parent)
191
+ super(name, guild_ids, block, type)
177
192
  @description = description
178
- @name = name
179
- @guild_ids = guild_ids.map(&:to_s)
180
- @block = block
181
- @type = Discorb::Command::Command.types[type]
182
- @type_raw = 1
183
193
  @options = options
184
194
  @id = nil
185
195
  @parent = parent
@@ -241,7 +251,7 @@ module Discorb
241
251
  # Represents the command with subcommands.
242
252
  #
243
253
  class GroupCommand < Command
244
- # @return [Array<Discorb::Command::Command::SlashCommand, Discorb::Command::Command::SubcommandGroup>] The subcommands of the command.
254
+ # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand, Discorb::ApplicationCommand::Command::SubcommandGroup>] The subcommands of the command.
245
255
  attr_reader :commands
246
256
  # @return [String] The description of the command.
247
257
  attr_reader :description
@@ -258,11 +268,11 @@ module Discorb
258
268
  #
259
269
  # Add new subcommand.
260
270
  #
261
- # @param (see Discorb::Command::Handler#slash)
262
- # @return [Discorb::Command::Command::SlashCommand] The added subcommand.
271
+ # @param (see Discorb::ApplicationCommand::Handler#slash)
272
+ # @return [Discorb::ApplicationCommand::Command::SlashCommand] The added subcommand.
263
273
  #
264
274
  def slash(command_name, description, options = {}, &block)
265
- command = Discorb::Command::Command::SlashCommand.new(command_name, description, options, [], block, 1, @name)
275
+ command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, [], block, 1, @name)
266
276
  @client.bottom_commands << command
267
277
  @commands << command
268
278
  command
@@ -275,14 +285,14 @@ module Discorb
275
285
  # @param [String] description Group description.
276
286
  #
277
287
  # @yield Block to execute as the command. It can be used to define sub-commands.
278
- # @yieldself [Discorb::Command::Command::SubcommandGroup] Group command.
288
+ # @yieldself [Discorb::ApplicationCommand::Command::SubcommandGroup] Group command.
279
289
  #
280
- # @return [Discorb::Command::Command::SubcommandGroup] Command object.
290
+ # @return [Discorb::ApplicationCommand::Command::SubcommandGroup] Command object.
281
291
  #
282
292
  # @see file:docs/slash_command.md
283
293
  #
284
294
  def group(command_name, description, &block)
285
- command = Discorb::Command::Command::SubcommandGroup.new(command_name, description, @name, @client)
295
+ command = Discorb::ApplicationCommand::Command::SubcommandGroup.new(command_name, description, @name, @client)
286
296
  command.instance_eval(&block) if block_given?
287
297
  @commands << command
288
298
  command
@@ -332,7 +342,7 @@ module Discorb
332
342
  # Represents the subcommand group.
333
343
  #
334
344
  class SubcommandGroup < GroupCommand
335
- # @return [Array<Discorb::Command::Command::SlashCommand>] The subcommands of the command.
345
+ # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand>] The subcommands of the command.
336
346
  attr_reader :commands
337
347
 
338
348
  # @!visibility private
@@ -349,11 +359,11 @@ module Discorb
349
359
 
350
360
  #
351
361
  # Add new subcommand.
352
- # @param (see Discorb::Command::Handler#slash)
353
- # @return [Discorb::Command::Command::SlashCommand] The added subcommand.
362
+ # @param (see Discorb::ApplicationCommand::Handler#slash)
363
+ # @return [Discorb::ApplicationCommand::Command::SlashCommand] The added subcommand.
354
364
  #
355
365
  def slash(command_name, description, options = {}, &block)
356
- command = Discorb::Command::Command::SlashCommand.new(command_name, description, options, [], block, 1, @parent + " " + @name)
366
+ command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, [], block, 1, @parent + " " + @name)
357
367
  @commands << command
358
368
  @client.bottom_commands << command
359
369
  command