lib/chef/knife/github_deploy.rb in knife-github-0.0.6 vs lib/chef/knife/github_deploy.rb in knife-github-0.0.7
- old
+ new
@@ -1,69 +1,59 @@
-#
-# Author:: Sander Botman (<sbotman@schubergphilis.com>)
-# Copyright:: Copyright (c) 2013 Sander Botman.
-# License:: Apache License, Version 2.0
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# ---------------------------------------------------------------------------- #
-# Abstract
-# ---------------------------------------------------------------------------- #
-# This code is specific to our company workflow
-# When a cookbook is released it is tagged to a specific version
-# This version should match the cookbook version (from the metadata)
-# This version is then pinned against specific environments
-#
-# This class expects you to have pushed all your changes to github
-# It will then do the rest
-#
-# All modes presume you have used github download to download a cookbook or
-# are creating a new cookbook
-#
-# There are two modes of operation
-# Development (default)
-#
-# This will take a cookbook name
-# Do some basic version checks (if the current cookbook is frozen) and
-# upload it
-#
-# If the cookbook is frozen it will force you to choose a new version
-# and update the metadata accordingly
-#
-# Final (-f)
-#
-# You will be forced to select a new version.
-# You can choose via the options whether to increment the Major/minor or patch
-# revision numbers
-# The version will be tagged
-# Uploaded to the Chef server and frozen
-#
-# Version numbers
-#
-# You can choose a specific version number by specifying it on the command
-# line.
-#
-# If you do not specify a version, the version will be the version in your
-# cookbook's metadata
-#
-# A warning is issued if the version is lower than the version in github
-# ---------------------------------------------------------------------------- #
require 'chef/knife'
class Chef
class Knife
-
+ # Implements the knife github deploy function
+ # @author:: Ian Southam (<isoutham@schubergphilis.com>)
+ # Copyright:: Copyright (c) 2013 Ian Southam.
+ # This code is specific to our company workflow
+ #
+ # == Overview
+ # All modes presume you have used github download to download a cookbook or
+ # are creating a new cookbook
+ #
+ # === Examples
+ # Deploy a development version of cookbook to your chef server
+ # knife github deploy cookbook_name
+ #
+ # Deploy a release version of cookbook to your chef server
+ # knife github deploy cookbook_name -f
+ #
+ # === Options
+ # -f Operate in final release mode
+ # -p Update the patch component of the version
+ # -m Update the minor component of the version
+ # -M Update the minor component of the version
+ #
+ # == Operation Modes
+ # Development (default)
+ #
+ # This will take a cookbook name
+ # Do some basic version checks (if the current cookbook is frozen) and
+ # upload it
+ #
+ # If the cookbook is frozen it will force you to choose a new version
+ # and update the metadata accordingly
+ #
+ # Release (-f)
+ #
+ # You will be forced to select a new version.
+ # You can choose via the options whether to increment the Major/minor or patch
+ # revision numbers
+ # The version will be tagged
+ # Uploaded to the Chef server and frozen
+ #
+ # == Version numbers
+ #
+ # You can choose a specific version number by specifying it on the command
+ # line.
+ #
+ # If you do not specify a version, the version will be the version in your
+ # cookbook's metadata
+ #
+ # A warning is issued if the version is lower than the version in github
+ #
class GithubDeploy < Knife
deps do
require 'chef/knife/github_base'
include Chef::Knife::GithubBase
require 'chef/cookbook_loader'
@@ -100,15 +90,14 @@
:description => "In final mode, increase the minor version ie. x.x.X (Default)",
:boolean => true,
:default => true
def run
+ # Main run entry point for the class
- # validate base options from base module.
validate_base_options
- # Display information if debug mode is on.
display_debug_info
# Gather all repo information from github.
get_all_repos = get_all_repos(@github_organizations.reverse)
@@ -133,11 +122,11 @@
end
# is the cookbook in the cookbook_path?
if cookbook_path_valid?(@cookbook_name, false).nil?
Chef::Log.error("Cookbook is not in cookbook path")
- ui.info("HINT: knife github download #{@cookbook_name}")
+ ui.info("HINT: knife github clone #{@cookbook_name}")
exit 1
end
# ----------------------------- #
# The version can come
@@ -159,10 +148,13 @@
inChef = true
isFrozen = false
if (config[:major] || config[:minor])
config[:patch] = false
end
+ if (config[:major] && config[:minor])
+ config[:minor] = false
+ end
begin
isFrozen = rest.get_rest("cookbooks/#{@cookbook_name}/#{cookbook_version}").frozen_version?
rescue
ui.warn "#{@cookbook_name} is not yet in chef"
@@ -188,10 +180,11 @@
ui.info("Cookbook #{cookbook_version} has no tag in Git")
ui.confirm("Shall I add a tag for you?")
set_cookbook_version(cookbook_version)
add_tag(cookbook_version)
else
+ ui.confirm("Tag #{cookbook_version} exists - did you make this for this release?")
checkout_tag(cookbook_version)
set_cookbook_version(cookbook_version)
end
do_commit(cookbook_version, true)
@@ -208,28 +201,42 @@
# If we have gotten this far we can just upload the cookbook
cookbook_upload()
end
+ # Ask user to increment current/desired version number
+ # Method will exit if the user chooses not to increment the version
+ #
+ # @param version [String] Version
+ # @return [String] New version number
+ #
def up_version(version)
while true do
ui.info("Trying to deploy version #{version}")
if @versions.include?(version)
ui.info("Version #{version} is already in chef")
- ui.confirm("Shall I bump the version (No to Cancel)")
+ vt = choose_version(version)
+ ui.confirm("Shall I bump the version to #{vt} (No to Cancel)")
version = choose_version(version)
else
break
end
end
version
end
+ # Increment the current version according to the config
+ # options config[major] config[minor] config[patch]
+ # Method will exit if the user chooses not to increment the version
+ #
+ # @param version [String] Version
+ # @return [String] New version number
+ #
def choose_version(version)
if version =~ /(\d+)\.(\d+)\.(\d+)/
major = $1
- minor = $1
+ minor = $2
patch = $3
major = major.to_i + 1 if config[:major]
minor = minor.to_i + 1 if config[:minor]
patch = patch.to_i + 1 if config[:patch]
version = "#{major}.#{minor}.#{patch}"
@@ -239,10 +246,12 @@
exit 1
end
version
end
+ # Upload the cookbook to chef server
+ # If mode is final, freeze the cookbook
def cookbook_upload()
# Git meuk should not be uploaded use chefignore file instead
# FileUtils.remove_entry("#{@github_tmp}/git/#{@cookbook_name}/.git")
args = ['cookbook', 'upload', @cookbook_name ]
if config[:final]
@@ -252,10 +261,14 @@
#upload.config[:cookbook_path] = "#{@github_tmp}/git"
# plugin will throw its own errors
upload.run
end
+ # If a tag is available in github check it out
+ # Potentially quite dangerous as it could cause code to
+ # get rolled back
+ # @param version [String] Version
def checkout_tag(version)
ui.info "Checking out tag #{version}"
cpath = get_cookbook_path(@cookbook_name)
Dir.chdir(cpath);
`git checkout -b #{version}`
@@ -263,20 +276,20 @@
ui.error("Failed to checkout branch #{version} of #{@cookbook_name}")
exit 1
end
end
+ # Get a sorted array of version for the cookbook
def get_cookbook_chef_versions ()
cookbooks = rest.get_rest("/cookbooks/#{@cookbook_name}?num_version=all")
cookbooks[@cookbook_name]['versions'].each do |v|
@versions.push v['version']
end
end
- # ---------------------------------------------------------------------- #
# Get the version number in the git version of the cookbook
- # ---------------------------------------------------------------------- #
+ # @param version [String] Version
def get_cookbook_version()
version = nil
cpath = get_cookbook_path(@cookbook_name)
File.foreach("#{cpath}/metadata.rb") do |line|
if line =~ /version.*"(.*)"/i
@@ -289,14 +302,21 @@
exit 1
end
version
end
+ # Determine if the current cookbook path is valid and that there
+ # is a cookbook of the correct name in there
+ # @param cookbook [String] cookbook name
+ # @return [String] Path to cookbook
def get_cookbook_path(cookbook)
return cookbook_path_valid?(cookbook, false)
end
+ # Commit changes in git
+ # @param version [String] cookbook version
+ # @param push [Bool] true is the cookbook should also be pushed
def do_commit(version, push)
cpath = get_cookbook_path(@cookbook_name)
Dir.chdir("#{cpath}")
puts cpath
output = `git commit -a -m "Deploy #{version}" 2>&1`
@@ -316,9 +336,11 @@
output = `git push 2>&1`
end
end
+ # Set the version in metadata.rb
+ # @param version [String] cookbook version
def set_cookbook_version(version)
return unless get_cookbook_version() != version
contents = ''
cpath = get_cookbook_path(@cookbook_name)
File.foreach("#{cpath}/metadata.rb") do |line|