summaryrefslogtreecommitdiff
path: root/lib/chef/knife/delete.rb
blob: 0030c450266856a73d3b2338dac47a9ba9146923 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
require 'chef/chef_fs/knife'

class Chef
  class Knife
    class Delete < Chef::ChefFS::Knife
      banner "knife delete [PATTERN1 ... PATTERNn]"

      category "path-based"

      deps do
        require 'chef/chef_fs/file_system'
      end

      option :recurse,
        :short => '-r',
        :long => '--[no-]recurse',
        :boolean => true,
        :default => false,
        :description => "Delete directories recursively."
      option :both,
        :long => '--both',
        :boolean => true,
        :default => false,
        :description => "Delete both the local and remote copies."
      option :local,
        :long => '--local',
        :boolean => true,
        :default => false,
        :description => "Delete the local copy (leave the remote copy)."

      def run
        if name_args.length == 0
          show_usage
          ui.fatal("Must specify at least one argument.  If you want to delete everything in this directory, type \"knife delete --recurse .\"")
          exit 1
        end

        # Get the matches (recursively)
        error = false
        if config[:local]
          pattern_args.each do |pattern|
            Chef::ChefFS::FileSystem.list(local_fs, pattern).each do |result|
              if delete_result(result)
                error = true
              end
            end
          end
        elsif config[:both]
          pattern_args.each do |pattern|
            Chef::ChefFS::FileSystem.list_pairs(pattern, chef_fs, local_fs).each do |chef_result, local_result|
              if delete_result(chef_result, local_result)
                error = true
              end
            end
          end
        else # Remote only
          pattern_args.each do |pattern|
            Chef::ChefFS::FileSystem.list(chef_fs, pattern).each do |result|
              if delete_result(result)
                error = true
              end
            end
          end
        end

        if error
          exit 1
        end
      end

      def format_path_with_root(entry)
        root = entry.root == chef_fs ? " (remote)" : " (local)"
        "#{format_path(entry)}#{root}"
      end

      def delete_result(*results)
        deleted_any = false
        found_any = false
        error = false
        results.each do |result|
          begin
            result.delete(config[:recurse])
            deleted_any = true
            found_any = true
          rescue Chef::ChefFS::FileSystem::NotFoundError
            # This is not an error unless *all* of them were not found
          rescue Chef::ChefFS::FileSystem::MustDeleteRecursivelyError => e
            ui.error "#{format_path_with_root(e.entry)} must be deleted recursively!  Pass -r to knife delete."
            found_any = true
            error = true
          rescue Chef::ChefFS::FileSystem::OperationNotAllowedError => e
            ui.error "#{format_path_with_root(e.entry)} #{e.reason}."
            found_any = true
            error = true
          end
        end
        if deleted_any
          output("Deleted #{format_path(results[0])}")
        elsif !found_any
          ui.error "#{format_path(results[0])}: No such file or directory"
          error = true
        end
        error
      end
    end
  end
end