Class: Chef::Knife::CookbookSCMRepo

Inherits:
Object
  • Object
show all
Includes:
Mixin::ShellOut
Defined in:
lib/chef/knife/core/cookbook_scm_repo.rb

Constant Summary collapse

DIRTY_REPO =
/^[\s]+M/

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ShellOut

#shell_out, #shell_out!

Constructor Details

#initialize(repo_path, ui, opts = {}) ⇒ CookbookSCMRepo



33
34
35
36
37
38
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 33

def initialize(repo_path, ui, opts={})
  @repo_path = repo_path
  @ui = ui
  @default_branch = 'master'
  apply_opts(opts)
end

Instance Attribute Details

#default_branchObject (readonly)

Returns the value of attribute default_branch



30
31
32
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 30

def default_branch
  @default_branch
end

#repo_pathObject (readonly)

Returns the value of attribute repo_path



29
30
31
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 29

def repo_path
  @repo_path
end

#uiObject (readonly)

Returns the value of attribute ui



31
32
33
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 31

def ui
  @ui
end

Instance Method Details

#branch_exists?(branch_name) ⇒ Boolean



116
117
118
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 116

def branch_exists?(branch_name)
  git("branch --no-color").stdout.lines.any? {|l| l =~ /\s#{Regexp.escape(branch_name)}(?:\s|$)/ }
end

#finalize_updates_to(cookbook_name, version) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 83

def finalize_updates_to(cookbook_name, version)
  if update_count = updated?(cookbook_name)
    ui.info "#{update_count} files updated, committing changes"
    git("add #{cookbook_name}")
    git("commit -m 'Import #{cookbook_name} version #{version}' -- #{cookbook_name}")
    ui.info("Creating tag cookbook-site-imported-#{cookbook_name}-#{version}")
    git("tag -f cookbook-site-imported-#{cookbook_name}-#{version}")
    true
  else
    ui.info("No changes made to #{cookbook_name}")
    false
  end
end

#merge_updates_from(cookbook_name, version) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 97

def merge_updates_from(cookbook_name, version)
  branch = "chef-vendor-#{cookbook_name}"
  Dir.chdir(repo_path) do
    if system("git merge #{branch}")
      ui.info("Cookbook #{cookbook_name} version #{version} successfully installed")
    else
      ui.error("You have merge conflicts - please resolve manually")
      ui.info("Merge status (cd #{repo_path}; git status):")
      system("git status")
      exit 3
    end
  end
end

#prepare_to_import(cookbook_name) ⇒ Object



72
73
74
75
76
77
78
79
80
81
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 72

def prepare_to_import(cookbook_name)
  branch = "chef-vendor-#{cookbook_name}"
  if branch_exists?(branch)
    ui.info("Pristine copy branch (#{branch}) exists, switching to it.")
    git("checkout #{branch}")
  else
    ui.info("Creating pristine copy branch #{branch}")
    git("checkout -b #{branch}")
  end
end

#reset_to_default_stateObject



67
68
69
70
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 67

def reset_to_default_state
  ui.info("Checking out the #{default_branch} branch.")
  git("checkout #{default_branch}")
end

#sanity_checkObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 40

def sanity_check
  unless ::File.directory?(repo_path)
    ui.error("The cookbook repo path #{repo_path} does not exist or is not a directory")
    exit 1
  end
  unless git_repo?(repo_path)
    ui.error "The cookbook repo #{repo_path} is not a git repository."
    ui.info("Use `git init` to initialize a git repo")
    exit 1
  end
  unless branch_exists?(default_branch)
    ui.error "The default branch '#{default_branch}' does not exist"
    ui.info "If this is a new git repo, make sure you have at least one commit before installing cookbooks"
    exit 1
  end
  cmd = git('status --porcelain')
  if cmd.stdout =~ DIRTY_REPO
    ui.error "You have uncommitted changes to your cookbook repo (#{repo_path}):"
    ui.msg cmd.stdout
    ui.info "Commit or stash your changes before importing cookbooks"
    exit 1
  end
  # TODO: any untracked files in the cookbook directory will get nuked later
  # make this an error condition also.
  true
end

#updated?(cookbook_name) ⇒ Boolean



111
112
113
114
# File 'lib/chef/knife/core/cookbook_scm_repo.rb', line 111

def updated?(cookbook_name)
  update_count = git("status --porcelain -- #{cookbook_name}").stdout.strip.lines.count
  update_count == 0 ? nil : update_count
end