Skip to content

Commit

Permalink
Fixes #105: Add CLI hooks to mechanisms and plugins, implement --igno…
Browse files Browse the repository at this point in the history
…re-app-stop-failures for CodeDeploy. (#184)

Fixes #105: Add CLI hooks to mechanisms and plugins.
  • Loading branch information
askreet committed Nov 26, 2016
1 parent 43f1384 commit 8f1b42a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
35 changes: 34 additions & 1 deletion docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,40 @@ retreive the name of the stack, stack parameters and stack outputs. This support
should be expanded in the future to provide Plugins with more control over the
CloudFormation stack.

## Adding a plugin to a CLI tool.
## Manipulating CLI options with Plugins

If you wish to modify the options accepted by a core Moonshot command
in order to affect the pre/post hooks defined in your plugin,
implement a method called `<action>_cli_hook`. This hook will be
passed an instance of OptionParser, which you can manipulate and
return. For example:

```ruby
class MyPlugin
def pre_build(_)
puts "FULL SPEED AHEAD!!!!" if @hyperdrive
end

def build_cli_hook(parser)
parser.on('--foo', '-F', TrueClass, 'ENABLE HYPERDRIVE') do |v|
@hyperdrive = v
end
end
end
```

With this plugin, the output of `moonshot build --help` reflects the
new command line option:

```
Usage: moonshot build VERSION
-v, --[no-]verbose Show debug logging
-n, --environment=NAME Which environment to operate on.
--[no-]interactive-logger Enable or disable fancy logging
-F, --foo ENABLE HYPERDRIVE
```

## Adding a plugin to Moonshot

Once you have defined or included your plugin class, you can add a
plugin by modifying your `Moonfile.rb` file, like so:
Expand Down
33 changes: 32 additions & 1 deletion lib/moonshot/command_line_dispatcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ def dispatch!
# Look to see if we're allowed only to run in certain accounts, or
# not allowed to run in specific accounts.
check_account_restrictions

# Allow any mechanisms or plugins to hook into this CLI command.
handler = @klass.new
handler.parser.parse!
parser = build_parser(handler)
parser.parse!

unless @args.size == handler.method(:execute).arity
warn handler.parser.help
Expand All @@ -36,5 +39,33 @@ def check_account_restrictions

raise 'Command account restriction violation.'
end

def build_parser(handler)
parser = handler.parser

# Each mechanism / plugin may manipulate the OptionParser object
# associated with this command.
[:build_mechanism, :deployment_mechanism, :artifact_repository].each do |prov|
provider = Moonshot.config.send(prov)

if provider.respond_to?(hook_func_name(@command))
parser = provider.send(hook_func_name(@command), parser)
end
end

Moonshot.config.plugins.each do |plugin|
if plugin.respond_to?(hook_func_name(@command))
parser = plugin.send(hook_func_name(@command), parser)
end
end

parser
end

# Name of the function a plugin or mechanism could define to manipulate
# the parser for a command.
def hook_func_name(command)
command.tr('-', '_') << '_cli_hook'
end
end
end
31 changes: 24 additions & 7 deletions lib/moonshot/deployment_mechanism/code_deploy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def initialize(
@group_name = group_name
@codedeploy_role = role
@codedeploy_config = config_name
@ignore_app_stop_failures = false
end

def post_create_hook
Expand Down Expand Up @@ -70,13 +71,7 @@ def deploy_hook(artifact_repo, version_name)
deployment_id = nil

ilog.start_threaded 'Creating Deployment' do |s|
res = cd_client.create_deployment(
application_name: app_name,
deployment_group_name: group_name,
revision: revision_for_artifact_repo(artifact_repo, version_name),
deployment_config_name: @codedeploy_config,
description: "Deploying version #{version_name}"
)
res = create_deployment(artifact_repo, version_name)
deployment_id = res.deployment_id
s.continue "Created Deployment #{deployment_id.blue}."
success = wait_for_deployment(deployment_id, s)
Expand All @@ -96,6 +91,17 @@ def post_delete_hook
end
end

def deploy_cli_hook(parser)
parser.on('--ignore-app-stop-failures', TrueClass, 'Continue deployment on ApplicationStop failures') do |v| # rubocop:disable LineLength
puts "ignore = #{v}"
@ignore_app_stop_failures = v
end

parser
end

alias push_cli_hook deploy_cli_hook

private

# By default, use the stack name as the application name, unless one has been
Expand Down Expand Up @@ -333,6 +339,17 @@ def s3_revision_for(artifact_repo, version_name)
}
end

def create_deployment(artifact_repo, version_name)
cd_client.create_deployment(
application_name: app_name,
deployment_group_name: group_name,
revision: revision_for_artifact_repo(artifact_repo, version_name),
deployment_config_name: @codedeploy_config,
description: "Deploying version #{version_name}",
ignore_application_stop_failures: @ignore_app_stop_failures
)
end

def doctor_check_code_deploy_role
iam_client.get_role(role_name: @codedeploy_role).role
success("#{@codedeploy_role} exists.")
Expand Down

0 comments on commit 8f1b42a

Please sign in to comment.