cartage 1.2 → 2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,106 @@
1
+ ### 2.0 / 2016-05-DD
2
+
3
+ * Rewrite! Over the last year, a number of deficiencies have been found,
4
+ especially related to the extensibility and the execution of various
5
+ phases. Cartage 2.0 is a rewrite of major parts of the system and is
6
+ intentionally not backwards compatible with Cartage 1.0. Documentation for
7
+ upgrading is provided.
8
+
9
+ * Changed from CmdParse to GLI for providing CLI interface structure.
10
+
11
+ * Removed the -E/--environment flag and support for environment-tagged
12
+ configuration.
13
+
14
+ * Added compression configuration. Supported types are bzip2, gzip, and
15
+ none. The default remains bzip2.
16
+
17
+ * The release_hashref file is no longer created. It has been replaced
18
+ with release_metadata.json. This contains more information and requires
19
+ cartage-rack 2.0 to display.
20
+
21
+ * Plug-ins have changed:
22
+
23
+ * Plug-in capabilities must be provided in the gem path
24
+ <tt>lib/cartage/plugins</tt>.
25
+
26
+ * Plug-ins declare their feature support to indicate the points that
27
+ they will be called during the packaging process.
28
+
29
+ * Plug-in commands must be provided in the gem path
30
+ <tt>lib/cartage/commands</tt>. These commands are always available.
31
+
32
+ * Plug-ins are currently automatically enabled on discovery and may
33
+ be explicitly disabled in configuration. Future versions of Cartage
34
+ will support explicit plug-in selection in configuration.
35
+
36
+ * Made more functions public for use by plug-ins.
37
+
38
+ * Removed support for default configuration files outside of a project
39
+ directory. Only <tt>config/cartage.yml</tt>, <tt>.cartage.yml</tt>, and
40
+ <tt>cartage.yml</tt> will be read now.
41
+ <tt>$HOME/.config/cartage.yml</tt>, <tt>$HOME/.cartage.yml</tt>, and
42
+ <tt>/etc/cartage.yml</tt> are no longer read. The previous behaviour
43
+ can be obtained with ERB insertion into one of the project-specific
44
+ files, as shown below. This pattern is not recommended.
45
+
46
+ ---
47
+ # cartage.yml
48
+ % candidates = []
49
+ % candidates << "#{ENV['HOME']}/.config/cartage.yml"
50
+ % candidates << "#{ENV['HOME']}/.cartage.yml"
51
+ % candidates << '/etc/cartage.yml'
52
+ % global = candidate.select { |c| File.exist?(c) }
53
+ <%= Cartage::Config.import(global) %>
54
+
55
+ * Extracted bundler support as a new gem,
56
+ [cartage-bundler]{https://github.com/KineticCafe/cartage-bundler}.
57
+
58
+ * Extracted tarball building as a built-in plug-in,
59
+ Cartage::BuildTarball.
60
+
61
+ * Added Cartage::Minitest to provide methods to assist with testing Cartage
62
+ and plug-ins using Minitest.
63
+
64
+ ### 1.2 / 2015-05-27
65
+
66
+ * 1 minor enhancement:
67
+
68
+ * Added the chosen timestamp as the second line of the release hashref
69
+ files.
70
+
71
+ * 2 minor bugfixes:
72
+
73
+ * Fixed {#3}[https://github.com/KineticCafe/issues/3] so that spec and
74
+ feature directories are excluded by default. Provided by @jsutlovic.
75
+ * Fixed {#5}[https://github.com/KineticCafe/pulls/5] so that the manifest
76
+ * is deduplicated prior to write. Provided by @jsutlovic.
77
+
78
+ ### 1.1.1 / 2015-03-26
79
+
80
+ * 1 minor bugfix
81
+
82
+ * Fixed a Ruby syntax issue with Ruby 2.0.
83
+
84
+ ### 1.1 / 2015-03-26
85
+
86
+ * 1 major enhancement
87
+
88
+ * Added a Cartage::StatusError with an exitstatus support.
89
+ Cartage::QuietError is now based on this.
90
+
91
+ * 1 minor bugfix
92
+
93
+ * Restored an accidentally removed method,
94
+ Cartage::#create_bundle_cache.
95
+
96
+ * 2 documentation improvements
97
+
98
+ * Identified postbuild script stages.
99
+
100
+ * Improved the Slack notifier example postbuild script.
101
+
102
+ ### 1.0 / 2015-03-24
103
+
104
+ * 1 major enhancement
105
+
106
+ * Birthday!
@@ -1,8 +1,8 @@
1
- == Licence
1
+ ## Licence
2
2
 
3
3
  This software is available under an MIT-style licence.
4
4
 
5
- * Copyright 2015 Kinetic Cafe
5
+ * Copyright 2015–2016 Kinetic Cafe
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy of
8
8
  this software and associated documentation files (the "Software"), to deal in
@@ -11,9 +11,9 @@ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
11
  of the Software, and to permit persons to whom the Software is furnished to do
12
12
  so, subject to the following conditions:
13
13
 
14
- * The names of its contributors may not be used to endorse or promote
15
- products derived from this software without specific prior written
16
- permission.
14
+ * The names of its contributors may not be used to endorse or promote
15
+ products derived from this software without specific prior written
16
+ permission.
17
17
 
18
18
  The above copyright notice and this permission notice shall be included in all
19
19
  copies or substantial portions of the Software.
@@ -1,25 +1,32 @@
1
- .autotest
2
- .gemtest
3
- .minitest.rb
4
- .travis.yml
5
1
  Cartage.yml.rdoc
6
- Contributing.rdoc
7
- Gemfile
8
- History.rdoc
9
- Licence.rdoc
2
+ Contributing.md
3
+ Extending.md
4
+ History.md
5
+ Licence.md
10
6
  Manifest.txt
11
7
  README.rdoc
12
8
  Rakefile
13
9
  bin/cartage
10
+ cartage-cli.md
14
11
  cartage.yml.sample
15
12
  lib/cartage.rb
16
- lib/cartage/command.rb
13
+ lib/cartage/backport.rb
14
+ lib/cartage/cli.rb
15
+ lib/cartage/commands/echo.rb
16
+ lib/cartage/commands/info.rb
17
+ lib/cartage/commands/manifest.rb
18
+ lib/cartage/commands/pack.rb
17
19
  lib/cartage/config.rb
18
- lib/cartage/manifest.rb
19
- lib/cartage/manifest/commands.rb
20
- lib/cartage/pack_command.rb
20
+ lib/cartage/core.rb
21
+ lib/cartage/gli_ext.rb
22
+ lib/cartage/minitest.rb
21
23
  lib/cartage/plugin.rb
24
+ lib/cartage/plugins/build_tarball.rb
25
+ lib/cartage/plugins/manifest.rb
22
26
  test/minitest_config.rb
23
27
  test/test_cartage.rb
28
+ test/test_cartage_build_tarball.rb
24
29
  test/test_cartage_config.rb
30
+ test/test_cartage_core.rb
25
31
  test/test_cartage_manifest.rb
32
+ test/test_cartage_plugin.rb
@@ -7,18 +7,20 @@ continuous integration :: {<img src="https://travis-ci.org/KineticCafe/cartage.s
7
7
 
8
8
  == Description
9
9
 
10
- Cartage provides a plug-in based tool to reliably create a package for a
11
- Bundler-based Ruby application that can be used in deployment with a
12
- configuration tool like Ansible, Chef, Puppet, or Salt. The package is created
13
- with its dependencies bundled in +vendor/bundle+, so it can be deployed in
14
- environments with strict access control rules and without requiring development
15
- tool access.
16
-
17
- Cartage has learned its tricks from Heroku, Capistrano, and Hoe. From Hoe, it
18
- learned to keep a manifest to control what is packaged (as well as its plug-in
19
- system). From Heroku, it learned to keep a simple ignore file. From Capistrano,
20
- it learned to mark the Git hashref as a file in its built package, and to
21
- timestamp the packages.
10
+ Cartage provides a repeatable means to create a package for a server-side
11
+ application that can be used in deployment with a configuration tool like
12
+ Ansible, Chef, Puppet, or Salt. The package is created with vendored
13
+ dependencies so that it can be deployed in environments with strict access
14
+ control rules and without requiring development tool presence on the target
15
+ server(s).
16
+
17
+ === Overview
18
+
19
+ Cartage has learned its tricks from Heroku’s build process, Capistrano
20
+ deployments, and Hoe. From Hoe, it learned to keep a manifest to control what
21
+ is packaged (as well as its plug-in system). From Heroku, it learned to keep a
22
+ simple ignore file. From Capistrano, it learned to mark the Git hashref as a
23
+ file in its built package, and to timestamp the packages.
22
24
 
23
25
  Cartage follows a relatively simple set of steps when creating a package:
24
26
 
@@ -29,117 +31,61 @@ Cartage follows a relatively simple set of steps when creating a package:
29
31
  list. To override the use of this exclusion list, an empty +.cartignore+
30
32
  file must be present.
31
33
 
32
- 2. The Git hashref is written to the work area (as +release_hashref+) and to
34
+ 2. The Git hashref is written to the work area (as +release_manifest.json+) and to
33
35
  the package staging area.
34
36
 
35
37
  3. Files that have been modified are restored to pristine condition in the
36
- work area. The source files are not touched. (This ensures that
38
+ work area. The source files are not touched. (This ensures that a Rails
37
39
  +config/database.yml+, for example, will not be the version used by a
38
40
  continuous integration system.)
39
41
 
40
- 4. Bundler is fetched into the work area, and the bundle is installed into the
41
- work area’s +vendor/bundle+ without the +development+ and +test+
42
- environments. If a bundle cache is kept (by default, one is), the resulting
43
- +vendor/bundle+ will be put into a bundle cache so that future bundle
44
- installs are faster.
42
+ 4. Dependencies are vendored using installed and enabled plug-ins. Vendored
43
+ dependencies will be cached for speeding up future installations.
45
44
 
46
45
  5. A timestamped tarball is created from the contents of the work area. It can
47
46
  then be copied to a more permanent or accessible location.
48
47
 
49
48
  Cartage is extremely opinionated about its tools and environment:
50
49
 
51
- * The packages are created with +tar+ and +bzip2+ using <tt>tar cfj</tt>.
52
- * Cartage only understands +git+, which is used for creating
53
- <tt>release_hashref</tt>s, +Manifest.txt+ creation and comparison, and even
54
- default application name detection (from the name of the origin remote).
50
+ * The packages are created with +tar+ and +bzip2+ using <tt>tar cfj</tt>.
51
+ (The compression method is configurable, but defaults to +bzip2+.)
52
+ * Cartage only understands +git+, which is used for creating
53
+ <tt>release_manifest.json</tt>s, +Manifest.txt+ creation and comparison, and even
54
+ default application name detection (from the name of the origin remote).
55
55
 
56
56
  == Synopsis
57
57
 
58
58
  # Build a package from the current machine, using the Manifest.txt.
59
- cartage pack
59
+ cartage pack # or cartage build
60
60
 
61
61
  # Create or update a Manifest.txt from the current repository.
62
- cartage manifest
62
+ cartage manifest generate # or cartage manifest update
63
63
  # Check the current Manifest against the files that should be there.
64
- cartage check
64
+ cartage manifest check
65
+
66
+ # Show the files that will be included in the package.
67
+ cartage manifest show
65
68
 
66
69
  # Create a .cartignore file for use.
67
- cartage install-ignore
70
+ cartage manifest cartignore
68
71
  # Overwrite the current .cartignore with the default.
69
- cartage install-ignore --force
72
+ cartage manifest cartignore --force # or --mode overwrite
70
73
  # Merge the current .cartignore with the default. Merging automatically
71
74
  # removes any comments.
72
- cartage install-ignore --merge
75
+ cartage manifest cartignore --merge # or --mode merge
73
76
 
74
77
  == Install
75
78
 
76
79
  Add cartage to your Gemfile:
77
80
 
78
- gem 'cartage', '~> 1.0', groups: [ :development, :test ]
81
+ gem 'cartage', '~> 2.0', groups: [ :development, :test ]
79
82
 
80
83
  Or manually install:
81
84
 
82
- % gem install cartage
83
-
84
- == Cartage Plug-Ins
85
-
86
- Cartage is extensible by plug-ins. This version of the plug-in system provides
87
- one integration point, subcommands. Cartage is implemented with
88
- {cmdparse}[http://cmdparse.gettalong.org/], and plug-ins implement a class that
89
- performs the work (nested under the Cartage namespace) and one or more commands
90
- that execute on the work. Plug-in files are discovered immediately relative to
91
- the +cartage+ directory, and are registered on inheritance from
92
- Cartage::Plugin. This plug-in would be found in <tt>'cartage/info.rb'</tt>.
93
- Each plug-in will get a lazy-instantiation constructor added to Cartage itself
94
- that provides a reference to the owning Cartage instance.
95
-
96
- Below is an example of a Cartage plug-in to provide a <tt>cartage info</tt>
97
- command. This command isn’t very useful, since most values used in Cartage
98
- packaging are lazily resolved, but it demonstrates how simple a plug-in can be.
99
-
100
- require 'cartage/plugin'
101
- require 'cartage/command'
102
-
103
- # An instance of this will be created lazily by calling Cartage#info.
104
- class Cartage::Info < Cartage::Plugin
105
- # It does not matter what this method is. It’s just a public instance
106
- # method used by the command.
107
- def run
108
- @cartage.instance_variables.sort.each { |ivar|
109
- puts "#{ivar}: #{@cartage.instance_variable_get(ivar)}"
110
- }
111
- end
112
-
113
- # This will create a CmdParse command that responds to 'info' and takes
114
- # no subcommands. If the plug-in provides a number of features, it is
115
- # recommended that subcommands be used.
116
- class InfoCommand < Cartage::Command
117
- # The Cartage::Command objects are initialized with the cartage
118
- # instance. Set the command name with the string here.
119
- def initialize(cartage)
120
- super(cartage, 'info', takes_commands: false)
121
- short_desc('Shows configuration information about Cartage.')
122
- end
123
-
124
- # This is run by Cartage::Command#execute to make the command happen.
125
- # An exception should be thrown on failure, as return values do not
126
- # affect the status code of the application.
127
- def perform
128
- @cartage.info.run
129
- end
130
- end
131
-
132
- # This returns the command(s) created by this plug-in.
133
- def self.commands
134
- [ Cartage::Info::InfoCommand ]
135
- end
136
- end
137
-
138
- For a more comprehensive example, see the implementation of Manifest
139
- (<tt>lib/cartage/manifest.rb</tt>) and its commands
140
- (<tt>lib/cartage/manifest/commands.rb</tt>).
141
-
142
- Future releases of Cartage will offer additional ways to extend Cartage.
85
+ % gem install cartage
86
+
87
+ Cartage should not be part of your production environment; its purpose is to
88
+ *create* production-ready packages.
143
89
 
144
90
  == Alternate Projects
145
91
 
@@ -150,31 +96,36 @@ CentOS 6, SLES 12, and Fedora 20.
150
96
  Both Cartage and Pkgr provide isolated builds with all in-application
151
97
  dependencies included.
152
98
 
153
- Pkgr offers several advantages over Cartage:
99
+ Pkgr offers some advantages over Cartage:
100
+
101
+ * It includes language interpreters local to the deployed application, as
102
+ appropriate.
154
103
 
155
- * It supports more languages than just Ruby (suport for Go and Node.js are
156
- confirmed and more are in progress). Cartage will probably have more language
157
- support in the future, but it is not an immediate priority. For Ruby and
158
- Node.js, the interpreters are included locally to the application.
104
+ * It has built-in support for Ruby, Go, and Node.js.
159
105
 
160
- * It creates a distribution package, meaning that you can just use +apt-get+ to
161
- install or upgrade your package.
106
+ * It creates an OS distribution package, meaning that you can just use
107
+ +apt-get+ or +yum+ to install or upgrade your package.
162
108
 
163
- * It reuses Heroku buildpacks (this requires that your application behave a bit
164
- more like a Heroku application, which may be a bit more
109
+ * It reuses Heroku buildpacks. This requires that your application behave like
110
+ a <del>Twelve Factor</del>Heroku application, including the use of STDOUT and
111
+ STDERR for various aspects. Pkgr has some tooling that reduces the negative
112
+ impact that this has for application configuration, but the changes are still
113
+ unavoidably present.
165
114
 
166
115
  Cartage offers advantages over Pkgr:
167
116
 
168
- * Cartage offers a plug-in based extension system. While the plug-in system is
169
- currently limited to adding new +cartage+ commands, this is not its only
170
- possible use. Existing plug-ins are +cartage-s3+ (upload the resulting
171
- package to S3), +cartage-remote+ (build on a remote machine), and
172
- +cartage-rack+ (provide a Rack application to read the +release_hashref+ over
173
- an API call).
117
+ * Cartage offers plug-in based extensions. Support for remote builds
118
+ (+cartage-remote+), uploads to S3 (+cartage-s3+), and bundler
119
+ (+cartage-bundler+) already exist and new plug-ins are not hard to add
120
+ (+cartage-npm+ is in development).
121
+
122
+ * Cartage offers more accessible information about *what* was built into the
123
+ release package. There is a Rack application (+cartage-rack+) that will
124
+ render the +release_manifest.json+ file over an API call.
174
125
 
175
126
  * Cartage makes it easier to integrate into a workflow translated from
176
127
  Capistrano, as it essentially replaces the source control checkout stage.
177
- This process makes it really easy to integrate into an Ansible playbook (as
128
+ This process makes it easy to integrate into an Ansible playbook (as
178
129
  we have done at Kinetic Cafe).
179
130
 
180
131
  == Cartage Semantic Versioning
@@ -187,6 +138,10 @@ significant change:
187
138
  Additionally, the major version will generally be reserved for plug-in
188
139
  infrastructure changes.
189
140
 
190
- :include: Contributing.rdoc
141
+ == Community and Contributing
191
142
 
192
- :include: Licence.rdoc
143
+ Cartage welcomes your contributions as described in
144
+ {Contributing.md}[https://github.com/KineticCafe/cartage/blob/master/Contributing.md].
145
+ This project, like all Kinetic Cafe {open source
146
+ projects}[https://github.com/KineticCafe], is under the Kinetic Cafe Open
147
+ Source {Code of Conduct}[https://github.com/KineticCafe/code-of-conduct].
data/Rakefile CHANGED
@@ -1,11 +1,11 @@
1
- # -*- ruby -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
- require 'pathname'
5
+ require 'rake/clean'
6
6
 
7
7
  Hoe.plugin :doofus
8
- Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS']
8
+ Hoe.plugin :email unless ENV['CI'] || ENV['TRAVIS']
9
9
  Hoe.plugin :gemspec2
10
10
  Hoe.plugin :git
11
11
  Hoe.plugin :minitest
@@ -15,47 +15,52 @@ Hoe.plugin :travis
15
15
  spec = Hoe.spec 'cartage' do
16
16
  developer('Austin Ziegler', 'aziegler@kineticcafe.com')
17
17
 
18
- self.history_file = 'History.rdoc'
18
+ self.history_file = 'History.md'
19
19
  self.readme_file = 'README.rdoc'
20
- self.extra_rdoc_files = FileList['*.rdoc'].to_a
21
20
 
22
21
  license 'MIT'
23
22
 
24
- self.extra_deps << ['cmdparse', '~> 3.0']
25
-
26
- self.extra_dev_deps << ['rake', '~> 10.0']
27
- self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
28
- self.extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
29
- self.extra_dev_deps << ['hoe-git', '~> 1.5']
30
- self.extra_dev_deps << ['hoe-travis', '~> 1.2']
31
- self.extra_dev_deps << ['minitest', '~> 5.4']
32
- self.extra_dev_deps << ['minitest-autotest', '~> 1.0']
33
- self.extra_dev_deps << ['minitest-bisect', '~> 1.2']
34
- self.extra_dev_deps << ['minitest-focus', '~> 1.1']
35
- self.extra_dev_deps << ['minitest-moar', '~> 0.0']
36
- self.extra_dev_deps << ['minitest-pretty_diff', '~> 0.1']
37
- self.extra_dev_deps << ['simplecov', '~> 0.7']
23
+ ruby20!
24
+
25
+ extra_deps << ['gli', '~> 2.13']
26
+
27
+ extra_dev_deps << ['rake', '>= 10.0']
28
+ extra_dev_deps << ['rdoc', '~> 4.2']
29
+ extra_dev_deps << ['hoe-doofus', '~> 1.0']
30
+ extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
31
+ extra_dev_deps << ['hoe-git', '~> 1.5']
32
+ extra_dev_deps << ['hoe-travis', '~> 1.2']
33
+ extra_dev_deps << ['minitest', '~> 5.4']
34
+ extra_dev_deps << ['minitest-autotest', '~> 1.0']
35
+ extra_dev_deps << ['minitest-bisect', '~> 1.2']
36
+ extra_dev_deps << ['minitest-bonus-assertions', '~> 2.0']
37
+ extra_dev_deps << ['minitest-focus', '~> 1.1']
38
+ extra_dev_deps << ['minitest-moar', '~> 0.0']
39
+ extra_dev_deps << ['minitest-pretty_diff', '~> 0.1']
40
+ extra_dev_deps << ['simplecov', '~> 0.7']
38
41
  end
39
42
 
40
- module Hoe::Publish
41
- alias_method :original_make_rdoc_cmd, :make_rdoc_cmd
43
+ ENV['RUBYOPT'] = '-W0'
44
+
45
+ module Hoe::Publish #:nodoc:
46
+ alias __make_rdoc_cmd__cartage__ make_rdoc_cmd
42
47
 
43
48
  def make_rdoc_cmd(*extra_args) # :nodoc:
44
- spec.extra_rdoc_files.reject! { |f| f == 'Manifest.txt' }
45
- original_make_rdoc_cmd(*extra_args)
49
+ spec.extra_rdoc_files.delete_if { |f| f == 'Manifest.txt' }
50
+ __make_rdoc_cmd__cartage__(*extra_args)
46
51
  end
47
52
  end
48
53
 
49
54
  namespace :test do
50
- task :coverage do
51
- prelude = <<-EOS
52
- require 'simplecov'
53
- SimpleCov.start('test_frameworks') { command_name 'Minitest' }
54
- gem 'minitest'
55
- EOS
56
- spec.test_prelude = prelude.split($/).join('; ')
57
- Rake::Task['test'].execute
55
+ if File.exist?('.simplecov-prelude.rb')
56
+ task :coverage do
57
+ spec.test_prelude = 'load ".simplecov-prelude.rb"'
58
+
59
+ Rake::Task['test'].execute
60
+ end
58
61
  end
62
+
63
+ CLOBBER << 'coverage'
59
64
  end
60
65
 
61
- # vim: syntax=ruby
66
+ CLOBBER << 'tmp'