summaryrefslogtreecommitdiff
path: root/lib/chef/deprecated.rb
blob: 4a2ac69b04eb602a0a154749ce67b059835f0ddc (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#--
# Copyright:: Copyright (c) Chef Software Inc.
# 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.
#

require_relative "mixin/convert_to_class_name"

# Structured deprecations have a unique URL associated with them, which must exist before the deprecation is merged.
class Chef
  class Deprecated

    class << self
      include Chef::Mixin::ConvertToClassName

      def create(type, message, location)
        Chef::Deprecated.const_get(convert_to_class_name(type.to_s)).new(message, location)
      end
    end

    class Base
      BASE_URL = "https://docs.chef.io/deprecations_".freeze

      attr_reader :message, :location

      def initialize(msg = nil, location = nil)
        @message = msg
        @location = location
      end

      def link
        "Please see #{url} for further details and information on how to correct this problem."
      end

      # Render the URL for the deprecation documentation page.
      #
      # @return [String]
      def url
        "#{BASE_URL}#{self.class.doc_page}/"
      end

      # Render the user-visible message for this deprecation.
      #
      # @return [String]
      def to_s
        "Deprecation CHEF-#{self.class.deprecation_id} from #{location}\n\n  #{message}\n\n#{link}"
      end

      # Check if this deprecation has been silenced.
      #
      # @return [Boolean]
      def silenced?
        # Check if all warnings have been silenced.
        return true if Chef::Config[:silence_deprecation_warnings] == true
        # Check if this warning has been silenced by the config.
        return true if Chef::Config[:silence_deprecation_warnings].any? do |silence_spec|
          if silence_spec.is_a? Integer
            # Integers can end up matching the line number in the `location` string
            silence_spec = "CHEF-#{silence_spec}"
          else
            # Just in case someone uses a symbol in the config by mistake.
            silence_spec = silence_spec.to_s
          end
          # Check for a silence by deprecation name, or by location.
          self.class.deprecation_key == silence_spec || self.class.deprecation_id.to_s == silence_spec || "chef-#{self.class.deprecation_id}" == silence_spec.downcase || location.include?(silence_spec)
        end
        # check if this warning has been silenced by inline comment.
        return true if location =~ /^(.*?):(\d+):in/ && begin
          # Don't buffer the whole file in memory, so read it one line at a time.
          line_no = $2.to_i
          location_file = ::File.open($1)
          (line_no - 1).times { location_file.readline } # Read all the lines we don't care about.
          relevant_line = location_file.readline
          relevant_line.match?(/#.*chef:silence_deprecation($|[^:]|:#{self.class.deprecation_key})/)
        end

        false
      end

      class << self
        attr_reader :deprecation_id, :doc_page

        # Return the deprecation key as would be used with {Chef::Deprecated.create}.
        #
        # @return [String]
        def deprecation_key
          Chef::Mixin::ConvertToClassName.convert_to_snake_case(name, "Chef::Deprecated")
        end

        # Set the ID and documentation page path for this deprecation.
        #
        # Used in subclasses to set the data for each type of deprecation.
        #
        # @example
        #   class MyDeprecation < Base
        #     target 123, "my_deprecation"
        #   end
        # @param id [Integer] Deprecation ID number. This must be unique among
        #   all deprecations.
        # @param page [String, nil] Optional documentation page path. If not
        #   specified, the deprecation key is used.
        # @return [void]
        def target(id, page = nil)
          @deprecation_id = id
          @doc_page = page || "#{deprecation_key}"
        end
      end
    end

    class InternalApi < Base
      target 0
    end

    class JsonAutoInflate < Base
      target 1
    end

    class ExitCode < Base
      target 2
    end

    # id 3 has been deleted

    class Attributes < Base
      target 4
    end

    class CustomResource < Base
      target 5, "custom_resource_cleanups"
    end

    class EasyInstall < Base
      target 6
    end

    class VerifyFile < Base
      target 7
    end

    class SupportsProperty < Base
      target 8
    end

    class ChefRest < Base
      target 9
    end

    class DnfPackageAllowDowngrade < Base
      target 10
    end

    class PropertyNameCollision < Base
      target 11
    end

    class LaunchdHashProperty < Base
      target 12
    end

    class ChefPlatformMethods < Base
      target 13
    end

    class RunCommand < Base
      target 14
    end

    class PackageMisc < Base
      target 15
    end

    class MultiresourceMatch < Base
      target 16
    end

    class UseInlineResources < Base
      target 17
    end

    class LocalListen < Base
      target 18
    end

    class NamespaceCollisions < Base
      target 19
    end

    class DeployResource < Base
      target 21
    end

    class ErlResource < Base
      target 22
    end

    class FreebsdPkgProvider < Base
      target 23
    end

    # id 25 was deleted

    # id 3694 was deleted

    # Returned when using the deprecated option on a property
    class Property < Base
      target 24

      def to_s
        "Deprecated resource property used from #{location}\n\n  #{message}\n\nPlease consult the resource documentation for more information."
      end
    end

    class ShellOut < Base
      target 26
    end

    class LocaleLcAll < Base
      target 27
    end

    class ChefSugar < Base
      target 28
    end

    class KnifeBootstrapApis < Base
      target 29
    end

    class ArchiveFileIntegerFileMode < Base
      target 30
    end

    class ResourceNameWithoutProvides < Base
      target 31
    end

    class Generic < Base
      def url
        "https://docs.chef.io/chef_deprecations_client/"
      end

      def to_s
        "Deprecation from #{location}\n\n  #{message}\n\n#{link}"
      end
    end
  end
end