mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
Make all SCMs inherit from SCM::Plugin
This makes it much easier (no hacks needed) to determine whether the user has installed an SCM plugin: simply check that the plugin responds to `scm?` and that it returns true. A new SCM::Plugin base class makes it easy to write such a plugin. This commit also updates the website docs that explain how to write SCM plugins so that they refer to this new technique.
This commit is contained in:
parent
ff686ef802
commit
e6ddd93ece
9 changed files with 46 additions and 26 deletions
|
@ -20,20 +20,20 @@ Capistrano checks out your application's source code. SCM plugins can be
|
|||
packaged as Ruby gems and distributed to other users.
|
||||
|
||||
This document is a short guide to writing your own plugin. *It applies to
|
||||
Capistrano 3.5.0 and newer.*
|
||||
Capistrano 3.7.0 and newer.*
|
||||
|
||||
### 1. Write a Ruby class that extends Capistrano::Plugin
|
||||
### 1. Write a Ruby class that extends Capistrano::SCM::Plugin
|
||||
|
||||
Let's say you want to create a "Foo" SCM. You'll need to write a plugin class,
|
||||
like this:
|
||||
|
||||
```ruby
|
||||
require "capistrano/plugin"
|
||||
require "capistrano/scm/plugin"
|
||||
|
||||
# By convention, Capistrano plugins are placed in the
|
||||
# Capistrano namespace. This is completely optional.
|
||||
module Capistrano
|
||||
class FooPlugin < ::Capistrano::Plugin
|
||||
class FooPlugin < ::Capistrano::SCM::Plugin
|
||||
def set_defaults
|
||||
# Define any variables needed to configure the plugin.
|
||||
# set_if_empty :myvar, "my-default-value"
|
||||
|
@ -42,11 +42,13 @@ module Capistrano
|
|||
end
|
||||
```
|
||||
|
||||
### 2. Implement the create_release task
|
||||
### 2. Implement a create_release task
|
||||
|
||||
When the user runs `cap deploy`, your SCM is responsible for creating the
|
||||
release directory and copying the application source code into it. You need to
|
||||
do this using a `create_release` task that is namespaced to your plugin.
|
||||
do this using a task that is registered to run after `deploy:new_release_path`.
|
||||
|
||||
By convention (not a requirement), this task is called `create_release`.
|
||||
|
||||
Inside your plugin class, use the `define_tasks` and `register_hooks` methods
|
||||
like this:
|
||||
|
@ -56,7 +58,6 @@ def define_tasks
|
|||
# The namespace can be whatever you want, but its best
|
||||
# to choose a name that matches your plugin name.
|
||||
namespace :foo do
|
||||
# The task *must* be named `create_release`
|
||||
task :create_release do
|
||||
# Your code to create the release directory and copy
|
||||
# the source code into it goes here.
|
||||
|
|
|
@ -140,6 +140,10 @@ module Capistrano
|
|||
load_immediately: load_immediately)
|
||||
end
|
||||
|
||||
def scm_plugin_installed?
|
||||
installer.scm_installed?
|
||||
end
|
||||
|
||||
def servers
|
||||
@servers ||= Servers.new
|
||||
end
|
||||
|
|
|
@ -26,6 +26,7 @@ module Capistrano
|
|||
|
||||
plugin.define_tasks
|
||||
plugin.register_hooks if load_hooks
|
||||
@scm_installed ||= provides_scm?(plugin)
|
||||
|
||||
if load_immediately
|
||||
plugin.set_defaults
|
||||
|
@ -35,6 +36,16 @@ module Capistrano
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def scm_installed?
|
||||
@scm_installed
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def provides_scm?(plugin)
|
||||
plugin.respond_to?(:scm?) && plugin.scm?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,8 @@ module Capistrano
|
|||
set(:scm, :git) if using_default_scm?
|
||||
|
||||
print_deprecation_warnings_if_applicable
|
||||
return if scm_plugin_loaded?
|
||||
# Note that `scm_plugin_installed?` comes from Capistrano::DSL
|
||||
return if scm_plugin_installed?
|
||||
|
||||
if built_in_scm_name?
|
||||
load_built_in_scm
|
||||
|
@ -47,13 +48,6 @@ module Capistrano
|
|||
@using_default_scm = (fetch(:scm) == DEFAULT_GIT)
|
||||
end
|
||||
|
||||
# This is somewhat of a hack, because there is no guarantee that a third-
|
||||
# party SCM will necessarily implement the typical SCM tasks. But it works
|
||||
# well enough for the built-in SCMs.
|
||||
def scm_plugin_loaded?
|
||||
Rake::Task.tasks.any? { |t| t.name =~ /^[^:]+:create_release/ }
|
||||
end
|
||||
|
||||
def scm_name
|
||||
fetch(:scm)
|
||||
end
|
||||
|
@ -102,7 +96,7 @@ module Capistrano
|
|||
|
||||
def print_deprecation_warnings_if_applicable
|
||||
if using_default_scm?
|
||||
warn_add_git_to_capfile unless scm_plugin_loaded?
|
||||
warn_add_git_to_capfile unless scm_plugin_installed?
|
||||
elsif built_in_scm_name?
|
||||
warn_set_scm_is_deprecated
|
||||
elsif third_party_scm_name?
|
||||
|
|
|
@ -8,7 +8,7 @@ module Capistrano
|
|||
:configure_backend, :fetch, :set, :set_if_empty, :delete,
|
||||
:ask, :role, :server, :primary, :validate, :append,
|
||||
:remove, :dry_run?, :install_plugin, :any?, :is_question?,
|
||||
:configure_scm
|
||||
:configure_scm, :scm_plugin_installed?
|
||||
|
||||
def roles(*names)
|
||||
env.roles_for(names.flatten)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
require "capistrano/plugin"
|
||||
require "capistrano/scm"
|
||||
require "capistrano/scm/plugin"
|
||||
|
||||
class Capistrano::SCM::Git < Capistrano::Plugin
|
||||
class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
||||
def set_defaults
|
||||
set_if_empty :git_shallow_clone, false
|
||||
set_if_empty :git_wrapper_path, lambda {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
require "capistrano/plugin"
|
||||
require "capistrano/scm"
|
||||
require "capistrano/scm/plugin"
|
||||
|
||||
class Capistrano::SCM::Hg < Capistrano::Plugin
|
||||
class Capistrano::SCM::Hg < Capistrano::SCM::Plugin
|
||||
def register_hooks
|
||||
after "deploy:new_release_path", "hg:create_release"
|
||||
before "deploy:check", "hg:check"
|
||||
|
|
13
lib/capistrano/scm/plugin.rb
Normal file
13
lib/capistrano/scm/plugin.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
require "capistrano/plugin"
|
||||
require "capistrano/scm"
|
||||
|
||||
# Base class for all built-in and third-party SCM plugins. Notice that this
|
||||
# class doesn't really do anything other than provide an `scm?` predicate. This
|
||||
# tells Capistrano that the plugin provides SCM functionality. All other plugin
|
||||
# features are inherited from Capistrano::Plugin.
|
||||
#
|
||||
class Capistrano::SCM::Plugin < Capistrano::Plugin
|
||||
def scm?
|
||||
true
|
||||
end
|
||||
end
|
|
@ -1,7 +1,6 @@
|
|||
require "capistrano/plugin"
|
||||
require "capistrano/scm"
|
||||
require "capistrano/scm/plugin"
|
||||
|
||||
class Capistrano::SCM::Svn < Capistrano::Plugin
|
||||
class Capistrano::SCM::Svn < Capistrano::SCM::Plugin
|
||||
def register_hooks
|
||||
after "deploy:new_release_path", "svn:create_release"
|
||||
before "deploy:check", "svn:check"
|
||||
|
|
Loading…
Reference in a new issue