Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Starting a New Command

Kevin O'Sullivan edited this page Jun 29, 2021 · 4 revisions

Creating a command in your ProjectType

So we have our project type defined, and I will use the Node project type for example. We can add a run command by making the following changes.

# lib/project_types/node/cli.rb
module Node
  class Command < ShopifyCli::ProjectCommands
    subcommand :Run, "run", Project.project_filepath("commands/run") # specify where the command is being loaded from
  end
end

So now we have defined the shopify node run command that will be available in node projects. The command will call the Node::Command::Run class for the functionality. So we can define this functionality by creating the file lib/project_types/node/commands/run.rb

# lib/project_types/node/commands/run.rb
module Node
  class Command
    class Run < ShopifyCli::SubCommand
      options do |parser, flags|
        parser.on('--host=HOST') { |h| flags[:host] = h.gsub('"', '') }
      end

      def call(*)
        puts "running on #{options.flags[:host]}"
      end

      # help is shown when the user runs `shopify help` in the list
      def self.help
        <<~HELP
          Run the service
            Usage: {{command:#{ShopifyCli::TOOL_NAME} node run}}
        HELP
      end

      # extended_help is shown when the user wants more specific help `shopify node run --help`
      def self.extended_help
        <<~HELP
          {{bold:Options:}}
            {{cyan:--host=HOST}}: The host where the service runs.
        HELP
      end
    end
  end
end

So now if we run shopify node run --host=http://google.com inside a node project it will output running on http://google.com

Adding a sub-sub-command

So if we want to add a shopify node run install command, then we can simply amend the start of the run command as follows:

# lib/project_types/node/commands/run.rb
module Node
  class Command
    class Run < ShopifyCli::subCommand
      prerequisite_task ensure_project_type: :node

      autoload :Install, Project.project_filepath('commands/run/install')

      INSTALL = "install"

      def call(args, _name)
        subcommand = args.shift
        case subcommand
        when INSTALL
          Node::Command::Run::Install.call(@ctx)
        else
          @ctx.puts(self.class.help)
        end
      end

      ...

So now we have declared (via the autoload) that the Node project-type run sub-command has a install sub-sub-command, and that the class Node::Command::Run::Install will be loaded and called for that command.

module Node
  class Command
    class Run
      class Install
        def call(*)
        end
      end
    end
  end
end
Clone this wiki locally