poise-archive 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +46 -16
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +1 -1
  5. data/README.md +7 -3
  6. data/Rakefile +1 -1
  7. data/chef/attributes/default.rb +18 -0
  8. data/lib/poise_archive.rb +1 -1
  9. data/lib/poise_archive/archive_providers.rb +4 -2
  10. data/lib/poise_archive/archive_providers/base.rb +1 -1
  11. data/lib/poise_archive/archive_providers/gnu_tar.rb +8 -2
  12. data/lib/poise_archive/archive_providers/seven_zip.rb +188 -0
  13. data/lib/poise_archive/archive_providers/tar.rb +1 -1
  14. data/lib/poise_archive/archive_providers/zip.rb +1 -1
  15. data/lib/poise_archive/cheftie.rb +1 -1
  16. data/lib/poise_archive/resources.rb +1 -1
  17. data/lib/poise_archive/resources/poise_archive.rb +1 -1
  18. data/lib/poise_archive/version.rb +2 -2
  19. data/poise-archive.gemspec +2 -1
  20. data/test/cookbook/files/myapp-1.0.0.tar.xz +0 -0
  21. data/test/cookbook/files/myapp-1.0.0/LICENSE +1 -0
  22. data/test/cookbook/files/myapp-1.0.0/README +2 -0
  23. data/test/cookbook/files/myapp-1.0.0/bin/run.sh +2 -0
  24. data/test/cookbook/files/myapp-1.0.0/src/main.c +5 -0
  25. data/test/cookbook/metadata.rb +1 -1
  26. data/test/cookbook/recipes/default.rb +20 -3
  27. data/test/gemfiles/chef-12.1.gemfile +4 -1
  28. data/test/gemfiles/chef-12.10.gemfile +22 -0
  29. data/test/gemfiles/chef-12.11.gemfile +22 -0
  30. data/test/gemfiles/chef-12.12.gemfile +21 -0
  31. data/test/gemfiles/chef-12.13.gemfile +21 -0
  32. data/test/gemfiles/chef-12.14.gemfile +19 -0
  33. data/test/gemfiles/chef-12.15.gemfile +19 -0
  34. data/test/gemfiles/chef-12.16.gemfile +19 -0
  35. data/test/gemfiles/chef-12.17.gemfile +19 -0
  36. data/test/gemfiles/chef-12.18.gemfile +19 -0
  37. data/test/gemfiles/chef-12.2.gemfile +4 -1
  38. data/test/gemfiles/chef-12.3.gemfile +4 -1
  39. data/test/gemfiles/chef-12.4.gemfile +5 -3
  40. data/test/gemfiles/chef-12.5.gemfile +4 -1
  41. data/test/gemfiles/chef-12.6.gemfile +4 -1
  42. data/test/gemfiles/chef-12.7.gemfile +22 -0
  43. data/test/gemfiles/chef-12.8.gemfile +22 -0
  44. data/test/gemfiles/chef-12.9.gemfile +22 -0
  45. data/test/gemfiles/chef-12.gemfile +2 -2
  46. data/test/gemfiles/master.gemfile +1 -1
  47. data/test/integration/default/serverspec/default_spec.rb +36 -6
  48. data/test/spec/archive_providers/gnu_tar_spec.rb +1 -3
  49. data/test/spec/archive_providers/seven_zip_spec.rb +151 -0
  50. data/test/spec/archive_providers/tar_spec.rb +2 -1
  51. data/test/spec/archive_providers/zip_spec.rb +1 -1
  52. data/test/spec/resources/poise_archive_spec.rb +1 -1
  53. data/test/spec/spec_helper.rb +1 -1
  54. metadata +54 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4242f7231038390f4f5fe3cbbffc7fc396ac5192
4
- data.tar.gz: 52c718b6e9bef94592ca87e0eca89b5dd9d42929
3
+ metadata.gz: 01c2f0093ff82b490d384f28383e9001be1f3d86
4
+ data.tar.gz: f03d4873224d55c6d543ca6584fc03fbf95a514d
5
5
  SHA512:
6
- metadata.gz: 986c52a2da5d576ecde9094a7362443a9ddb4bd2f50f05f7a58ef39d8a4e597c00c6e9a1f0dbd6805d27ce9c66fd9e82f1955f10e425edced02343d83009ef74
7
- data.tar.gz: a35ad89c3af875f794553c898266a0a6e5f7676d486e1796b47ed0b240d43f379fe897e9cc9fd817c32de5693af245cd50e8818141bc485f0bc1c34d0193e515
6
+ metadata.gz: e2362ecf6f347995dd967b7a07294a40fd6e455a9fc122a22618314fcc3418a3a05e31f32810cbf3b383a4a51e58d58450d1b0ca32c3d98038253961838df288
7
+ data.tar.gz: 104cc37a957cc08eeebe6db7e982b59ae6ab6e12fd8adea6ca33f0b7b9a60710862766bfa1aecbb2bd923e7f84f4cf5c2362523ed12fd3bf154026f3cb537606
@@ -1,22 +1,52 @@
1
- ---
2
1
  sudo: false
3
2
  cache: bundler
4
3
  language: ruby
5
- rvm:
6
- - 2.3.1
7
4
  env:
8
5
  global:
9
- - secure: OIVa/hlztLT/hICbouLmXu9F6x0ntFzUnfJbhG3LNVQk3s3YmeI8QPLh1bIxGULry+a3pLykDESYya6gpC+f+Si3FSI7VLpFds5EVIbptMVPRVHjDSNSHFjoAgjzX36HCxvWGJdb0jKZ5EUNBGBqDtnBPFAp3FcwknhkRpOAzKemzXnSZVMyxLiuNBMynLycFPjSSDZt0uSq/yvXnBAb0FXov84Zh0K+OoTEQ1J2AWSS9jXkBZncZD4rdSBqJSZwMxN9+3w6IONyWO3BMCg1QBcA0fCdcqk5ZlbGOfpt0n/FkYfUvB3Ypei+4+QT3wg9f63R14HtM1ZK/VHOrjx/h0rAC0haq2OEWmEAyrZF+pSm5l46ngWlHnifVURjOOabXg6TLNqN0JN8zjXyGYB6rb3RDeG8U0dJrdoVUQW02A4v8Fpo2wACHcz+h0cipWxh2RPOfl7/5PtDZ/ZKFaR73Ci2SXOG9Q9gTCdFDbXmEgEB8PtyoDS5gkm4QiY3Ffi1YXD46yU0YHxTVnw7S63g7gmHf4G30NAKdoSl1Zke6IvZYA5fl7vcx6Dl1ZQWJMxJgsTx7KVRENeCzpJDkty04bs1MCAy6vEWcAxYApket7TXvnAIEAQzxnp/r82zWVwanLdVcbBVvFDWNlsMquRXRwOVkcs12esLY6Wj6WBZCyQ=
10
- before_install: "gem install bundler"
11
- bundler_args: "--binstubs=$PWD/bin --jobs 3 --retry 3"
6
+ - secure: OIVa/hlztLT/hICbouLmXu9F6x0ntFzUnfJbhG3LNVQk3s3YmeI8QPLh1bIxGULry+a3pLykDESYya6gpC+f+Si3FSI7VLpFds5EVIbptMVPRVHjDSNSHFjoAgjzX36HCxvWGJdb0jKZ5EUNBGBqDtnBPFAp3FcwknhkRpOAzKemzXnSZVMyxLiuNBMynLycFPjSSDZt0uSq/yvXnBAb0FXov84Zh0K+OoTEQ1J2AWSS9jXkBZncZD4rdSBqJSZwMxN9+3w6IONyWO3BMCg1QBcA0fCdcqk5ZlbGOfpt0n/FkYfUvB3Ypei+4+QT3wg9f63R14HtM1ZK/VHOrjx/h0rAC0haq2OEWmEAyrZF+pSm5l46ngWlHnifVURjOOabXg6TLNqN0JN8zjXyGYB6rb3RDeG8U0dJrdoVUQW02A4v8Fpo2wACHcz+h0cipWxh2RPOfl7/5PtDZ/ZKFaR73Ci2SXOG9Q9gTCdFDbXmEgEB8PtyoDS5gkm4QiY3Ffi1YXD46yU0YHxTVnw7S63g7gmHf4G30NAKdoSl1Zke6IvZYA5fl7vcx6Dl1ZQWJMxJgsTx7KVRENeCzpJDkty04bs1MCAy6vEWcAxYApket7TXvnAIEAQzxnp/r82zWVwanLdVcbBVvFDWNlsMquRXRwOVkcs12esLY6Wj6WBZCyQ=
7
+ before_install: gem install bundler
8
+ bundler_args: '--binstubs=$PWD/bin --jobs 3 --retry 3'
12
9
  script:
13
- - "./bin/rake travis"
14
- gemfile:
15
- - test/gemfiles/chef-12.gemfile
16
- - test/gemfiles/chef-12.1.gemfile
17
- - test/gemfiles/chef-12.2.gemfile
18
- - test/gemfiles/chef-12.3.gemfile
19
- - test/gemfiles/chef-12.4.gemfile
20
- - test/gemfiles/chef-12.5.gemfile
21
- - test/gemfiles/chef-12.6.gemfile
22
- - test/gemfiles/master.gemfile
10
+ - ./bin/rake travis
11
+ matrix:
12
+ include:
13
+ - rvm: 2.3.1
14
+ gemfile: test/gemfiles/chef-12.gemfile
15
+ - rvm: 2.1.4
16
+ gemfile: test/gemfiles/chef-12.1.gemfile
17
+ - rvm: 2.1.4
18
+ gemfile: test/gemfiles/chef-12.2.gemfile
19
+ - rvm: 2.1.4
20
+ gemfile: test/gemfiles/chef-12.3.gemfile
21
+ - rvm: 2.1.6
22
+ gemfile: test/gemfiles/chef-12.4.gemfile
23
+ - rvm: 2.1.6
24
+ gemfile: test/gemfiles/chef-12.5.gemfile
25
+ - rvm: 2.1.6
26
+ gemfile: test/gemfiles/chef-12.6.gemfile
27
+ - rvm: 2.1.6
28
+ gemfile: test/gemfiles/chef-12.7.gemfile
29
+ - rvm: 2.1.6
30
+ gemfile: test/gemfiles/chef-12.8.gemfile
31
+ - rvm: 2.1.8
32
+ gemfile: test/gemfiles/chef-12.9.gemfile
33
+ - rvm: 2.1.8
34
+ gemfile: test/gemfiles/chef-12.10.gemfile
35
+ - rvm: 2.1.8
36
+ gemfile: test/gemfiles/chef-12.11.gemfile
37
+ - rvm: 2.1.8
38
+ gemfile: test/gemfiles/chef-12.12.gemfile
39
+ - rvm: 2.1.9
40
+ gemfile: test/gemfiles/chef-12.13.gemfile
41
+ - rvm: 2.3.1
42
+ gemfile: test/gemfiles/chef-12.14.gemfile
43
+ - rvm: 2.3.1
44
+ gemfile: test/gemfiles/chef-12.15.gemfile
45
+ - rvm: 2.3.1
46
+ gemfile: test/gemfiles/chef-12.16.gemfile
47
+ - rvm: 2.3.1
48
+ gemfile: test/gemfiles/chef-12.17.gemfile
49
+ - rvm: 2.3.1
50
+ gemfile: test/gemfiles/chef-12.18.gemfile
51
+ - rvm: 2.3.1
52
+ gemfile: test/gemfiles/master.gemfile
@@ -1,5 +1,10 @@
1
1
  # Poise-Archive Changelog
2
2
 
3
+ ## v1.4.0
4
+
5
+ * Added support for using 7-Zip on Windows.
6
+ * Fixed handling of `.tar.xz` archives on RHEL and CentOS.
7
+
3
8
  ## v1.3.0
4
9
 
5
10
  * Add support for unpacking directly from a URL.
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -21,10 +21,14 @@ poise_archive 'https://example.com/myapp.tgz' do
21
21
  end
22
22
  ```
23
23
 
24
+ ## Requirements
25
+
26
+ Chef 12.1 or newer is required.
27
+
24
28
  ## Platforms
25
29
 
26
- This cookbook supports all platforms (including Windows) but non-Linux platforms
27
- may see very slow tar file unpacking when using the pure-Ruby fallback
30
+ This cookbook supports all platforms (including Windows) but some Unix platforms
31
+ (Solaris, AIX) may see very slow tar file unpacking when using the pure-Ruby fallback
28
32
  implementation.
29
33
 
30
34
  ## Resources
@@ -81,7 +85,7 @@ The Poise test server infrastructure is sponsored by [Rackspace](https://rackspa
81
85
 
82
86
  ## License
83
87
 
84
- Copyright 2016, Noah Kantrowitz
88
+ Copyright 2016-2017, Noah Kantrowitz
85
89
 
86
90
  Licensed under the Apache License, Version 2.0 (the "License");
87
91
  you may not use this file except in compliance with the License.
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,18 @@
1
+ #
2
+ # Copyright 2017, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ default['poise-archive']['seven_zip']['version'] = '16.04'
18
+ default['poise-archive']['seven_zip']['url'] = 'http://www.7-zip.org/a/7z%{version_tag}%{arch_tag}.exe'
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
17
17
  require 'chef/platform/provider_priority_map'
18
18
 
19
19
  require 'poise_archive/archive_providers/gnu_tar'
20
+ require 'poise_archive/archive_providers/seven_zip'
20
21
  require 'poise_archive/archive_providers/tar'
21
22
  require 'poise_archive/archive_providers/zip'
22
23
 
@@ -28,9 +29,10 @@ module PoiseArchive
28
29
  module ArchiveProviders
29
30
  # Set up priority maps
30
31
  Chef::Platform::ProviderPriorityMap.instance.priority(:poise_archive, [
32
+ PoiseArchive::ArchiveProviders::Zip,
31
33
  PoiseArchive::ArchiveProviders::GnuTar,
34
+ PoiseArchive::ArchiveProviders::SevenZip,
32
35
  PoiseArchive::ArchiveProviders::Tar,
33
- PoiseArchive::ArchiveProviders::Zip,
34
36
  ])
35
37
  end
36
38
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -52,7 +52,13 @@ module PoiseArchive
52
52
  def install_prereqs
53
53
  utils = ['tar']
54
54
  utils << 'bzip2' if new_resource.absolute_path =~ /\.t?bz/
55
- utils << 'xz-utils' if new_resource.absolute_path =~ /\.t?xz/
55
+ if new_resource.absolute_path =~ /\.t?xz/
56
+ xz_package = node.value_for_platform_family(
57
+ debian: 'xz-utils',
58
+ rhel: 'xz',
59
+ )
60
+ utils << xz_package if xz_package
61
+ end
56
62
  # This is a resource.
57
63
  package utils
58
64
  end
@@ -0,0 +1,188 @@
1
+ #
2
+ # Copyright 2017, Noah Kantrowitz
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fileutils'
18
+ require 'tmpdir'
19
+
20
+
21
+ require 'poise_archive/archive_providers/base'
22
+
23
+
24
+ module PoiseArchive
25
+ module ArchiveProviders
26
+ # The `seven_zip` provider class for `poise_archive` to upack archives
27
+ # using 7-Zip.
28
+ #
29
+ # @since 1.4.0
30
+ # @see PoiseArchive::Resources::PoiseArchive::Resource
31
+ # @provides poise_archive
32
+ class SevenZip < Base
33
+ provides_extension(/\.(t(ar|gz|bz|xz)|zip|7z)/)
34
+
35
+ # Only works on Windows, because use less silly things elsewhere.
36
+ #
37
+ # @api private
38
+ def self.provides?(node, _resource)
39
+ super && node['platform_family'] == 'windows'
40
+ end
41
+
42
+ private
43
+
44
+ def unpack_archive
45
+ notifying_block do
46
+ install_seven_zip
47
+ end
48
+ # Create a temp directory to unpack in to. Do I want to try and force
49
+ # this to be on the same filesystem as the target?
50
+ self.class.mktmpdir do |tmpdir|
51
+ unpack_using_seven_zip(tmpdir)
52
+ chown_files(tmpdir) if new_resource.user || new_resource.group
53
+ move_files(tmpdir)
54
+ end
55
+ end
56
+
57
+ # Install 7-Zip to a cache folder.
58
+ #
59
+ # @api private
60
+ # @return [void]
61
+ def install_seven_zip
62
+ url = seven_zip_url
63
+ path = "#{Chef::Config[:file_cache_path]}/#{url.split(/\//).last}"
64
+
65
+ install = execute "#{windows_path(path)} /S /D=#{seven_zip_home}" do
66
+ action :nothing
67
+ end
68
+
69
+ remote_file path do
70
+ source url
71
+ notifies :run, install, :immediately
72
+ end
73
+ end
74
+
75
+ # Unpack the whole archive to a temp directory.
76
+ #
77
+ # @api private
78
+ # @param tmpdir [String] Temp directory to unpack to.
79
+ # @return [void]
80
+ def unpack_using_seven_zip(tmpdir)
81
+ if new_resource.absolute_path =~ /\.t(ar\.)?(gz|bz(2)?|xz)$/
82
+ # 7-Zip doesn't know to unpack both levels of the archive on its own
83
+ # so we need to handle this more explicitly.
84
+ shell_out!("#{seven_zip_home}\\7z.exe x -so \"#{windows_path(new_resource.absolute_path)}\" | #{seven_zip_home}\\7z.exe x -si -ttar -o\"#{windows_path(tmpdir)}\"")
85
+ else
86
+ shell_out!("#{seven_zip_home}\\7z.exe x -o\"#{windows_path(tmpdir)}\" \"#{windows_path(new_resource.absolute_path)}\"")
87
+ end
88
+ end
89
+
90
+ # Fix file ownership if requested.
91
+ #
92
+ # @api private
93
+ # @param tmpdir [String] Temp directory to change ownership in.
94
+ # @return [void]
95
+ def chown_files(tmpdir)
96
+ notifying_block do
97
+ Dir["#{tmpdir}/**/*"].each do |path|
98
+ declare_resource(::File.directory?(path) ? :directory : :file, path) do
99
+ owner new_resource.user if new_resource.user
100
+ group new_resource.group if new_resource.group
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ # Manual implementation of --strip-components since 7-Zip doesn't support
107
+ # it internally.
108
+ #
109
+ # @api private
110
+ # @param tmpdir [String] Temp directory to move from.
111
+ # @return [void]
112
+ def move_files(tmpdir)
113
+ entries_at_depth(tmpdir, new_resource.strip_components).each do |source|
114
+ target = ::File.join(new_resource.destination, ::File.basename(source))
115
+ # If we are in keep_existing mode, the target might exist already.
116
+ # This is not a great solution and won't have exactly the same behavior
117
+ # as the other providers, but it's something at least.
118
+ FileUtils.rm_rf(target) if ::File.exist?(target)
119
+ # At some point this might need to fall back to a real copy.
120
+ ::File.rename(source, target)
121
+ end
122
+ end
123
+
124
+ # Compute the URL to download the 7-Zip installer from.
125
+ #
126
+ # @api private
127
+ # @return [String]
128
+ def seven_zip_url
129
+ node['poise-archive']['seven_zip']['url'] % {
130
+ version: node['poise-archive']['seven_zip']['version'],
131
+ version_tag: node['poise-archive']['seven_zip']['version'].gsub(/\./, ''),
132
+ arch: node['kernel']['machine'],
133
+ arch_tag: node['kernel']['machine'] == 'x86_64' ? '-x64' : '',
134
+ }
135
+ end
136
+
137
+ # Path to install 7-Zip in to.
138
+ #
139
+ # @api private
140
+ # @return [String]
141
+ def seven_zip_home
142
+ "#{windows_path(Chef::Config[:file_cache_path])}\\seven_zip_#{node['poise-archive']['seven_zip']['version']}"
143
+ end
144
+
145
+ # Flip the slashes in a path because 7z wants "normal" paths.
146
+ #
147
+ # @api private
148
+ # @param path [String] Path to convert.
149
+ # @return [String]
150
+ def windows_path(path)
151
+ path.gsub(/\//, '\\')
152
+ end
153
+
154
+ # Find the absolute paths for entries under a path at a depth.
155
+ #
156
+ # @api private
157
+ # @param path [String] Base path to search under.
158
+ # @param depth [Integer] Number of intermediary directories to skip.
159
+ # @return [Array<String>]
160
+ def entries_at_depth(path, depth)
161
+ entries = [path]
162
+ current_depth = 0
163
+ while current_depth <= depth
164
+ entries.map! do |ent|
165
+ if ::File.directory?(ent)
166
+ Dir.entries(ent).select {|e| e != '.' && e != '..' }.map {|e| ::File.join(ent, e) }
167
+ else
168
+ []
169
+ end
170
+ end
171
+ entries.flatten!
172
+ current_depth += 1
173
+ end
174
+ entries
175
+ end
176
+
177
+ # Indirection so I can stub this for testing without breaking RSpec.
178
+ #
179
+ # @api private
180
+ def self.mktmpdir(*args, &block)
181
+ # :nocov:
182
+ Dir.mktmpdir(*args, &block)
183
+ # :nocov:
184
+ end
185
+
186
+ end
187
+ end
188
+ end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016, Noah Kantrowitz
2
+ # Copyright 2016-2017, Noah Kantrowitz
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.