From 425d53f4618d472ec88c4308845461694584b588 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Thu, 3 Oct 2013 11:48:29 -0400 Subject: [PATCH] Add Travis CI, ChefSpec, Foodcritic, RuboCop, Test Kitchen, and fix existing warnings Signed-off-by: Seth Vargo --- .kitchen.yml | 54 ++-- .rubocop.yml | 14 + .travis.yml | 7 + Berksfile | 4 +- CONTRIBUTING | 29 -- CONTRIBUTING.md | 257 ++++++++++++++++++ Gemfile | 11 + README.md | 180 ++++++------ TESTING.md | 58 +++- attributes/default.rb | 19 +- files/default/tests/minitest/test_test.rb | 54 ---- metadata.rb | 25 +- providers/default.rb | 40 +-- recipes/default.rb | 16 +- recipes/test.rb | 82 ------ resources/default.rb | 25 +- spec/spec_helper.rb | 6 + spec/support/matchers/ark_matchers.rb | 6 + spec/unit/recipes/default_spec.rb | 24 ++ test/fixtures/cookbooks/fake/metadata.rb | 4 + .../cookbooks/fake/recipes/default.rb | 78 ++++++ .../maven2/serverspec/maven_spec.rb | 39 +++ .../maven3/serverspec/maven_spec.rb | 39 +++ 23 files changed, 695 insertions(+), 376 deletions(-) create mode 100644 .rubocop.yml create mode 100644 .travis.yml delete mode 100644 CONTRIBUTING create mode 100644 CONTRIBUTING.md create mode 100644 Gemfile delete mode 100644 files/default/tests/minitest/test_test.rb delete mode 100644 recipes/test.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/support/matchers/ark_matchers.rb create mode 100644 spec/unit/recipes/default_spec.rb create mode 100644 test/fixtures/cookbooks/fake/metadata.rb create mode 100644 test/fixtures/cookbooks/fake/recipes/default.rb create mode 100644 test/integration/maven2/serverspec/maven_spec.rb create mode 100644 test/integration/maven3/serverspec/maven_spec.rb diff --git a/.kitchen.yml b/.kitchen.yml index a62404d..0f87ad2 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -1,44 +1,26 @@ ---- driver_plugin: vagrant driver_config: require_chef_omnibus: true customize: - memory: 512 + memory: 1024 platforms: -- name: ubuntu-12.04 - driver_config: - box: opscode-ubuntu-12.04 - box_url: https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box - run_list: ["recipe[apt]"] - -- name: ubuntu-10.04 - driver_config: - box: opscode-ubuntu-10.04 - box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-10.04_provisionerless.box - run_list: ["recipe[apt]"] - -- name: centos-6.4 - driver_config: - box: opscode-centos-6.4 - box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_centos-6.4_provisionerless.box - -- name: centos-5.9 - driver_config: - box: opscode-centos-5.9 - box_url: http://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_centos-5.9_provisionerless.box + - name: ubuntu-12.04 + run_list: + - recipe[apt::default] + - name: ubuntu-10.04 + run_list: + - recipe[apt::default] + - name: centos-6.4 + - name: centos-5.9 suites: -- name: maven2 - run_list: - - recipe[minitest-handler] - - recipe[maven] - - recipe[maven::test] - attributes: { maven: { version: 2 } } - -- name: maven3 - run_list: - - recipe[minitest-handler] - - recipe[maven] - - recipe[maven::test] - attributes: {} + - name: maven2 + run_list: + - recipe[fake::default] + attributes: + maven: + version: 2 + - name: maven3 + run_list: + - recipe[fake::default] diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..e11136d --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,14 @@ +AllCops: + Excludes: + - vendor/** + +AlignParameters: + Enabled: false +Encoding: + Enabled: false +HashSyntax: + Enabled: false +LineLength: + Enabled: false +MethodLength: + Max: 30 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..eaa2385 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +rvm: + - 1.9.3 + - 2.0.0 +script: + - bundle exec foodcritic -f any . + - bundle exec rspec --color --format progress + - bundle exec rubocop diff --git a/Berksfile b/Berksfile index 4e41c34..c4543c7 100644 --- a/Berksfile +++ b/Berksfile @@ -2,6 +2,6 @@ site :opscode metadata group :integration do - cookbook "apt" - cookbook "minitest-handler" + cookbook 'apt', '~> 2.0' + cookbook 'fake', path: 'test/fixtures/cookbooks/fake' end diff --git a/CONTRIBUTING b/CONTRIBUTING deleted file mode 100644 index 89ac873..0000000 --- a/CONTRIBUTING +++ /dev/null @@ -1,29 +0,0 @@ -If you would like to contribute, please open a ticket in JIRA: - -* http://tickets.opscode.com - -Create the ticket in the COOK project and use the cookbook name as the -component. - -For all code contributions, we ask that contributors sign a -contributor license agreement (CLA). Instructions may be found here: - -* http://wiki.opscode.com/display/chef/How+to+Contribute - -When contributing changes to individual cookbooks, please do not -modify the version number in the metadata.rb. Also please do not -update the CHANGELOG.md for a new version. Not all changes to a -cookbook may be merged and released in the same versions. Opscode will -handle the version updates during the release process. You are welcome -to correct typos or otherwise make updates to documentation in the -README. - -If a contribution adds new platforms or platform versions, indicate -such in the body of the commit message(s), and update the relevant -COOK ticket. When writing commit messages, it is helpful for others if -you indicate the COOK ticket. For example: - - git commit -m '[COOK-1041] Updated pool resource to correctly delete.' - -In the ticket itself, it is also helpful if you include log output of -a successful Chef run, but this is not absolutely required. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3a99897 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,257 @@ +# Contributing to Opscode Cookbooks + +We are glad you want to contribute to Opscode Cookbooks! The first +step is the desire to improve the project. + +You can find the answers to additional frequently asked questions +[on the wiki](http://wiki.opscode.com/display/chef/How+to+Contribute). + +You can find additional information about +[contributing to cookbooks](http://wiki.opscode.com/display/chef/How+to+Contribute+to+Opscode+Cookbooks) +on the wiki as well. + +## Quick-contribute + +* Create an account on our [bug tracker](http://tickets.opscode.com) +* Sign our contributor agreement (CLA) +[ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L) +(keep reading if you're contributing on behalf of your employer) +* Create a ticket for your change on the + [bug tracker](http://tickets.opscode.com) +* Link to your patch as a rebased git branch or pull request from the + ticket +* Resolve the ticket as fixed + +We regularly review contributions and will get back to you if we have +any suggestions or concerns. + +## The Apache License and the CLA/CCLA + +Licensing is very important to open source projects, it helps ensure +the software continues to be available under the terms that the author +desired. Chef uses the Apache 2.0 license to strike a balance between +open contribution and allowing you to use the software however you +would like to. + +The license tells you what rights you have that are provided by the +copyright holder. It is important that the contributor fully +understands what rights they are licensing and agrees to them. +Sometimes the copyright holder isn't the contributor, most often when +the contributor is doing work for a company. + +To make a good faith effort to ensure these criteria are met, Opscode +requires a Contributor License Agreement (CLA) or a Corporate +Contributor License Agreement (CCLA) for all contributions. This is +without exception due to some matters not being related to copyright +and to avoid having to continually check with our lawyers about small +patches. + +It only takes a few minutes to complete a CLA, and you retain the +copyright to your contribution. + +You can complete our contributor agreement (CLA) +[ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L). +If you're contributing on behalf of your employer, have your employer +fill out our +[Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856) +instead. + +## Ticket Tracker (JIRA) + +The [ticket tracker](http://tickets.opscode.com) is the most important +documentation for the code base. It provides significant historical +information, such as: + +* Which release a bug fix is included in +* Discussion regarding the design and merits of features +* Error output to aid in finding similar bugs + +Each ticket should aim to fix one bug or add one feature. + +## Using git + +You can get a quick copy of the repository for this cookbook by +running `git clone +git://github.com/opscode-coobkooks/COOKBOOKNAME.git`. + +For collaboration purposes, it is best if you create a Github account +and fork the repository to your own account. Once you do this you will +be able to push your changes to your Github repository for others to +see and use. + +If you have another repository in your GitHub account named the same +as the cookbook, we suggest you suffix the repository with -cookbook. + +### Branches and Commits + +You should submit your patch as a git branch named after the ticket, +such as COOK-1337. This is called a _topic branch_ and allows users to +associate a branch of code with the ticket. + +It is a best practice to have your commit message have a _summary +line_ that includes the ticket number, followed by an empty line and +then a brief description of the commit. This also helps other +contributors understand the purpose of changes to the code. + + [COOK-1757] - platform_family and style + + * use platform_family for platform checking + * update notifies syntax to "resource_type[resource_name]" instead of + resources() lookup + * COOK-692 - delete config files dropped off by packages in conf.d + * dropped debian 4 support because all other platforms have the same + values, and it is older than "old stable" debian release + +Remember that not all users use Chef in the same way or on the same +operating systems as you, so it is helpful to be clear about your use +case and change so they can understand it even when it doesn't apply +to them. + +### Github and Pull Requests + +All of Opscode's open source cookbook projects are available on +[Github](http://www.github.com/opscode-cookbooks). + +We don't require you to use Github, and we will even take patch diffs +attached to tickets on the tracker. However Github has a lot of +convenient features, such as being able to see a diff of changes +between a pull request and the main repository quickly without +downloading the branch. + +If you do choose to use a pull request, please provide a link to the +pull request from the ticket __and__ a link to the ticket from the +pull request. Because pull requests only have two states, open and +closed, we can't easily filter pull requests that are waiting for a +reply from the author for various reasons. + +### More information + +Additional help with git is available on the +[Working with Git](http://wiki.opscode.com/display/chef/Working+with+Git) +wiki page. + +## Functional and Unit Tests + +This cookbook is set up to run tests under +[Opscode's test-kitchen](https://github.com/opscode/test-kitchen). It +uses minitest-chef to run integration tests after the node has been +converged to verify that the state of the node. + +Test kitchen should run completely without exception using the default +[baseboxes provided by Opscode](https://github.com/opscode/bento). +Because Test Kitchen creates VirtualBox machines and runs through +every configuration in the Kitchenfile, it may take some time for +these tests to complete. + +If your changes are only for a specific recipe, run only its +configuration with Test Kitchen. If you are adding a new recipe, or +other functionality such as a LWRP or definition, please add +appropriate tests and ensure they run with Test Kitchen. + +If any don't pass, investigate them before submitting your patch. + +Any new feature should have unit tests included with the patch with +good code coverage to help protect it from future changes. Similarly, +patches that fix a bug or regression should have a _regression test_. +Simply put, this is a test that would fail without your patch but +passes with it. The goal is to ensure this bug doesn't regress in the +future. Consider a regular expression that doesn't match a certain +pattern that it should, so you provide a patch and a test to ensure +that the part of the code that uses this regular expression works as +expected. Later another contributor may modify this regular expression +in a way that breaks your use cases. The test you wrote will fail, +signalling to them to research your ticket and use case and accounting +for it. + +If you need help writing tests, please ask on the Chef Developer's +mailing list, or the #chef-hacking IRC channel. + +## Code Review + +Opscode regularly reviews code contributions and provides suggestions +for improvement in the code itself or the implementation. + +We find contributions by searching the ticket tracker for _resolved_ +tickets with a status of _fixed_. If we have feedback we will reopen +the ticket and you should resolve it again when you've made the +changes or have a response to our feedback. When we believe the patch +is ready to be merged, we will tag the _Code Reviewed_ field with +_Reviewed_. + +Depending on the project, these tickets are then merged within a week +or two, depending on the current release cycle. + +## Release Cycle + +The versioning for Opscode Cookbook projects is X.Y.Z. + +* X is a major release, which may not be fully compatible with prior + major releases +* Y is a minor release, which adds both new features and bug fixes +* Z is a patch release, which adds just bug fixes + +A released version of a cookbook will end in an even number, e.g. +"1.2.4" or "0.8.0". When development for the next version of the +cookbook begins, the "Z" patch number is incremented to the next odd +number, however the next release of the cookbook may be a major or +minor incrementing version. + +Releases of Opscode's cookbooks are usually announced on the Chef user +mailing list. Releases of several cookbooks may be batched together +and announced on the [Opscode Blog](http://www.opscode.com/blog). + +## Working with the community + +These resources will help you learn more about Chef and connect to +other members of the Chef community: + +* [chef](http://lists.opscode.com/sympa/info/chef) and + [chef-dev](http://lists.opscode.com/sympa/info/chef-dev) mailing + lists +* #chef and #chef-hacking IRC channels on irc.freenode.net +* [Community Cookbook site](http://community.opscode.com) +* [Chef wiki](http://wiki.opscode.com/display/chef) +* Opscode Chef [product page](http://www.opscode.com/chef) + + +## Cookbook Contribution Do's and Don't's + +Please do include tests for your contribution. If you need help, ask +on the +[chef-dev mailing list](http://lists.opscode.com/sympa/info/chef-dev) +or the +[#chef-hacking IRC channel](http://community.opscode.com/chat/chef-hacking). +Not all platforms that a cookbook supports may be supported by Test +Kitchen. Please provide evidence of testing your contribution if it +isn't trivial so we don't have to duplicate effort in testing. Chef +10.14+ "doc" formatted output is sufficient. + +Please do indicate new platform (families) or platform versions in the +commit message, and update the relevant ticket. + +If a contribution adds new platforms or platform versions, indicate +such in the body of the commit message(s), and update the relevant +COOK ticket. When writing commit messages, it is helpful for others if +you indicate the COOK ticket. For example: + + git commit -m '[COOK-1041] - Updated pool resource to correctly + delete.' + +Please do use [foodcritic](http://acrmp.github.com/foodcritic) to +lint-check the cookbook. Except FC007, it should pass all correctness +rules. FC007 is okay as long as the dependent cookbooks are *required* +for the default behavior of the cookbook, such as to support an +uncommon platform, secondary recipe, etc. + +Please do ensure that your changes do not break or modify behavior for +other platforms supported by the cookbook. For example if your changes +are for Debian, make sure that they do not break on CentOS. + +Please do not modify the version number in the metadata.rb, Opscode +will select the appropriate version based on the release cycle +information above. + +Please do not update the CHANGELOG.md for a new version. Not all +changes to a cookbook may be merged and released in the same versions. +Opscode will update the CHANGELOG.md when releasing a new version of +the cookbook. diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..6f5b9fe --- /dev/null +++ b/Gemfile @@ -0,0 +1,11 @@ +source 'https://rubygems.org' + +gem 'berkshelf', '~> 2.0' +gem 'chefspec', '~> 2.0' +gem 'foodcritic', '~> 3.0' +gem 'rubocop', '~> 0.12' + +group :integration do + gem 'test-kitchen', '~> 1.0.0.beta' + gem 'kitchen-vagrant', '~> 0.11' +end diff --git a/README.md b/README.md index eb89dee..0cb92c5 100644 --- a/README.md +++ b/README.md @@ -1,127 +1,106 @@ -Description -=========== +maven Cookbook +============== +Install and configure maven2 and maven3 from the binaries provided by the maven project. -Install and configure maven2 and maven3 from the binaries provided by -the maven project. +Provides the `maven` LWRP for pulling a maven artifact from a mave repository and placing it in an arbitrary location. -Provides the `maven` LWRP for pulling a maven artifact from a maven -repository and placing it in an arbitrary location. Requirements -============ - -Platform: - -* Debian, Ubuntu, CentOS, Red Hat, Fedora +------------ +### Platforms +- Debian +- Ubuntu +- CentOS +- Red Hat +- Fedora The following Opscode cookbooks are dependencies: +- java - this cookbook not only depends on the java virtual machine but it also depends on the java_ark LWRP present in the java cookbooks +- ark - used to unpack the maven tarball -* java - this cookbook not only depends on the java virtual machine - but it also depends on the java_ark LWRP present in the java cookbooks -* ark - used to unpack the maven tarball Attributes -========== - -* `node['maven']['version']` defaults to 3, specifies the major - version of maven to install. -* `node['maven']['m2_home']` defaults to '/usr/local/maven/' -* `node['maven']['2']['url']` the download url for maven2 -* `node['maven']['2']['checksum']` the checksum, which you will have - to recalculate if you change the download url using shasum -a 256 -* `node['maven']['3']['url']` download url for maven3 -* `node['maven']['3']['checksum']` the checksum, which you will have - to recalculate if you change the download url using shasum -a 256 - -* `node['maven']['repositories']` - an array of maven repositories to - use; must be specified as an array. Used in the maven LWRP. -* `node['maven']['setup_bin']` Whether or not to put mvn on your - system path, defaults to false -* `node['maven']['mavenrc']['opts']` Value of `MAVEN_OPTS` environment variable - exported via `/etc/mavenrc` template, - defaults to `-Dmaven.repo.local=$HOME/.m2/repository -Xmx384m -XX:MaxPermSize=192m` - -Recipes -======= +---------- +* `node['maven']['version']` - defaults to 3, specifies the major version of maven to install. +* `node['maven']['m2_home']` - defaults to '/usr/local/maven/' +* `node['maven']['2']['url']` - the download url for maven2 +* `node['maven']['2']['checksum']` - the checksum, which you will have to recalculate if you change the download url using shasum -a 256 +* `node['maven']['3']['url']` - download url for maven3 +* `node['maven']['3']['checksum']` - the checksum, which you will have to recalculate if you change the download url using shasum -a 256 +* `node['maven']['repositories']` - an array of maven repositories to use; must be specified as an array. Used in the maven LWRP. +* `node['maven']['setup_bin']` - Whether or not to put mvn on your system path, defaults to false +* `node['maven']['mavenrc']['opts']` - Value of `MAVEN_OPTS` environment variable exported via `/etc/mavenrc` template, defaults to `-Dmaven.repo.local=$HOME/.m2/repository -Xmx384m -XX:MaxPermSize=192m` -## default -Includes the java recipe, and then installs maven according to the -version specified by the `node['maven']['version']` attribute. +Recipes +------- +### default +Includes the java recipe, and then installs maven according to the version specified by the `node['maven']['version']` attribute. -## test +### test +**For testing only**. From the development repository, use test-kitchen to test that the LWRP is operating with this recipe. Also contains example usage of the LWRP. -**For testing only**. From the development repository, use test-kitchen to -test that the LWRP is operating with this recipe. Also contains -example usage of the LWRP. Usage -===== - +----- Simply include the recipe where you want Apache Maven installed. -The maven lwrp has two actions, `:install` and `:put`. They are -essentially the same accept that the install action will name the the -downloaded file `artifact_id-version.packaging`. For example, the -mysql jar would be named mysql-5.1.19.jar. +The maven lwrp has two actions, `:install` and `:put`. They are essentially the same accept that the install action will name the the downloaded file `artifact_id-version.packaging`. For example, the mysql jar would be named mysql-5.1.19.jar. -Use the put action when you want to explicitly control the name of the -downloaded file. This is useful when you download an artifact and then -want to have Chef resources act on files within that the artifact. The -put action will creat a file named `name.packaging` where name -corresponds to the name attribute. +Use the put action when you want to explicitly control the name of the downloaded file. This is useful when you download an artifact and then want to have Chef resources act on files within that the artifact. The put action will creat a file named `name.packaging` where name corresponds to the name attribute. -Providers/Resources -=================== - -## maven - -* artifact_id: if this is not specified, the resource's name is used -* group_id: group_id for the artifact -* version: version of the artifact -* dest: the destination folder for the jar and its dependencies -* packaging: defaults to 'jar' -* classifier: distinguishes artifacts that were built from the same POM but differ in context -* repositories: array of maven repositories to use, defaults to - ["http://repo1.maven.apache.org/maven2"] -* owner: the owner of the resulting file, default is root -* mode: integer value for file permissions, default is 0644 -* transitive: whether to resolve dependencies transitively, defaults to false. Please note: Event true will only place one artifact in dest. All others are downloaded to the local repository. - -### Examples - - maven "mysql-connector-java" do - group_id "mysql" - version "5.1.19" - dest "/usr/local/tomcat/lib/" - end - # The artifact will be downloaded to /usr/local/tomcat/lib/mysql-connector-java-5.1.19.jar - - maven "solr" do - group_id "org.apache.solr" - version "3.6.1" - packaging "war" - dest "/usr/local/tomcat/webapps/" - action :put - end - # The artifact will be downloaded to /usr/local/tomcat/webapps/solr.war - - maven "custom-application" do - group_id "com.company.name" - version "2.0.0" - dest "/usr/local/tomcat/lib" - classifier "client" - action :put - end - # The artifact will be downloaded to /usr/local/tomcat/lib/custom-application-2.0.0-client.jar - -License and Author -================== +Providers/Resources +------------------- +### maven +- `artifact_id` - if this is not specified, the resource's name is used +- `group_id` - group_id for the artifact +- `version` - version of the artifact +- `dest` - the destination folder for the jar and its dependencies +- `packaging` - defaults to 'jar' +- `classifier` - distinguishes artifacts that were built from the same POM but differ in context +- `repositories` - array of maven repositories to use, defaults to ["http://repo1.maven.apache.org/maven2"] +- `owner` - the owner of the resulting file, default is root +- `mode` - integer value for file permissions, default is 0644 +- `transitive` - whether to resolve dependencies transitively, defaults to false. Please note: Event true will only place one artifact in dest. All others are downloaded to the local repository. + +#### Examples + +```ruby +maven 'mysql-connector-java' do + group_id 'mysql' + version '5.1.19' + dest '/usr/local/tomcat/lib/' +end +# The artifact will be downloaded to /usr/local/tomcat/lib/mysql-connector-java-5.1.19.jar + +maven 'solr' do + group_id 'org.apache.solr' + version '3.6.1' + packaging 'war' + dest '/usr/local/tomcat/webapps/' + action :put +end +# The artifact will be downloaded to /usr/local/tomcat/webapps/solr.war + +maven 'custom-application' do + group_id 'com.company.name' + version '2.0.0' + dest '/usr/local/tomcat/lib' + classifier 'client' + action :put +end +# The artifact will be downloaded to /usr/local/tomcat/lib/custom-application-2.0.0-client.jar +``` + + +License & Authors +----------------- - Author:: Seth Chisamore () - Author:: Bryan W. Berry () - Author:: Leif Madsen () +```text Copyright 2010-2013, Opscode, Inc. Licensed under the Apache License, Version 2.0 (the "License"); @@ -135,3 +114,4 @@ 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. +``` diff --git a/TESTING.md b/TESTING.md index e29ff7c..b4102e3 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,25 +1,53 @@ -This cookbook includes support for running tests via Test Kitchen (1.0). This has some requirements. +This cookbook uses a variety of testing components: -1. You must be using the Git repository, rather than the downloaded cookbook from the Chef Community Site. -2. You must have Vagrant 1.1 installed. -3. You must have a "sane" Ruby 1.9.3 environment. +- Unit tests: [ChefSpec](https://github.com/acrmp/chefspec) +- Integration tests: [Test Kitchen](https://github.com/opscode/test-kitchen) +- Chef Style lints: [Foodcritic](https://github.com/acrmp/foodcritic) +- Ruby Style lints: [Rubocop](https://github.com/bbatsov/rubocop) -Once the above requirements are met, install the additional requirements: -Install the berkshelf plugin for vagrant, and berkshelf to your local Ruby environment. +Prerequisites +------------- +To develop on this cookbook, you must have a sane Ruby 1.9+ environment. Given the nature of this installation process (and it's variance across multiple operating systems), we will leave this installation process to the user. - vagrant plugin install vagrant-berkshelf - gem install berkshelf +You must also have `bundler` installed: -Install Test Kitchen 1.0 (unreleased yet, use the alpha / prerelease version). + $ gem install bundler - gem install test-kitchen --pre +You must also have Vagrant and VirtualBox installed: -Install the Vagrant driver for Test Kitchen. +- [Vagrant](https://vagrantup.com) +- [VirtualBox](https://virtualbox.org) - gem install kitchen-vagrant +Once installed, you must install the `vagrant-berkshelf` plugin: -Once the above are installed, you should be able to run Test Kitchen: + $ vagrant plugin install vagrant-berkshelf - kitchen list - kitchen test + +Development +----------- +1. Clone the git repository from GitHub: + + $ git clone git@github.com:opscode-cookbooks/COOKBOOK.git + +2. Install the dependencies using bundler: + + $ bundle install + +3. Create a branch for your changes: + + $ git checkout -b my_bug_fix + +4. Make any changes +5. Write tests to support those changes. It is highly recommended you write both unit and integration tests. +6. Run the tests: + - `bundle exec rspec` + - `bundle exec foodcritic .` + - `bundle exec rubocop` + - `bundle exec kitchen test` + +7. Assuming the tests pass, open a Pull Request on GitHub +8. Open a JIRA ticket for this compontent, linking the JIRA ticket to the Pull Request and visa versa. +9. Mark the JIRA ticket as "Fix Provided" + +For more information, see [Opscode's Contribution Guidelines](https://wiki.opscode.com/display/chef/How+to+Contribute). diff --git a/attributes/default.rb b/attributes/default.rb index 551ccdc..ff8d951 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -1,10 +1,11 @@ +# # Cookbook Name:: maven # Attributes:: default # # Author:: Seth Chisamore () # Author:: Bryan W. Berry () # -# Copyright:: Copyright (c) 2010-2012, Opscode, Inc. +# Copyright:: Copyright (c) 2010-2013, Opscode, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,14 +23,14 @@ default['maven']['version'] = 3 default['maven']['m2_home'] = '/usr/local/maven' -default['maven']['mavenrc']['opts'] = "-Dmaven.repo.local=$HOME/.m2/repository -Xmx384m -XX:MaxPermSize=192m" -default['maven']['2']['version'] = "2.2.1" +default['maven']['mavenrc']['opts'] = '-Dmaven.repo.local=$HOME/.m2/repository -Xmx384m -XX:MaxPermSize=192m' +default['maven']['2']['version'] = '2.2.1' default['maven']['2']['url'] = "http://apache.mirrors.tds.net/maven/maven-2/#{node['maven']['2']['version']}/binaries/apache-maven-#{node['maven']['2']['version']}-bin.tar.gz" -default['maven']['2']['checksum'] = "b9a36559486a862abfc7fb2064fd1429f20333caae95ac51215d06d72c02d376" -default['maven']['2']['plugin_version'] = "2.4" -default['maven']['3']['version'] = "3.1.0" +default['maven']['2']['checksum'] = 'b9a36559486a862abfc7fb2064fd1429f20333caae95ac51215d06d72c02d376' +default['maven']['2']['plugin_version'] = '2.4' +default['maven']['3']['version'] = '3.1.0' default['maven']['3']['url'] = "http://apache.mirrors.tds.net/maven/maven-3/#{node['maven']['3']['version']}/binaries/apache-maven-#{node['maven']['3']['version']}-bin.tar.gz" -default['maven']['3']['checksum'] = "59088c62c14b996d597bbd55e720866b0e13e36daed8a46a81c01058ee74bd54" -default['maven']['3']['plugin_version'] = "2.4" -default['maven']['repositories'] = ["http://repo1.maven.apache.org/maven2"] +default['maven']['3']['checksum'] = '59088c62c14b996d597bbd55e720866b0e13e36daed8a46a81c01058ee74bd54' +default['maven']['3']['plugin_version'] = '2.4' +default['maven']['repositories'] = ['http://repo1.maven.apache.org/maven2'] default['maven']['setup_bin'] = false diff --git a/files/default/tests/minitest/test_test.rb b/files/default/tests/minitest/test_test.rb deleted file mode 100644 index 9b1eb06..0000000 --- a/files/default/tests/minitest/test_test.rb +++ /dev/null @@ -1,54 +0,0 @@ -class TestMaven < MiniTest::Chef::TestCase - - def path - "/usr/local/foobar/lib/" - end - - def test_mysql_jar_unpacked - assert File.exists? "#{path}/mysql-connector-java-5.1.19.jar" - end - - def test_mysql_jar_perms - file_mode = File.stat("#{path}/mysql-connector-java-5.1.19.jar").mode - octal_mode = sprintf("%o", file_mode)[-4..-1] - assert octal_mode == "0755" - end - - def test_mysql_jar_owner - require 'etc' - assert File.stat("#{path}/mysql-connector-java-5.1.19.jar").uid == Etc.getpwnam("foobarbaz").uid - assert File.stat("#{path}/mysql-connector-java-5.1.19.jar").gid == Etc.getpwnam("foobarbaz").gid - end - - def test_javax_persistence_from_alt_repo - assert File.exists? "#{path}/javax.persistence-2.0.0.jar" - end - - def test_with_multiple_repos - assert File.exists? "#{path}/postgresql-9.0-801.jdbc4.jar" - end - - def test_alt_packaging - assert File.exists? "#{path}/mm-mysql-2.0.13.pom" - end - - def test_CamelCaseAliases - assert File.exists? "#{path}/mm-mysql-2.0.13.pom" - end - - def test_PutAction - assert File.exists? "#{path}/solr-foo.war" - end - - def test_mavenrc - assert File.exists? "/etc/mavenrc" - end - - def test_notifies - assert File.exists? "/usr/local/notifyOne" - end - - def test_is_idempotent - assert !(File.exists? "/usr/local/notifyTwo") - end -end diff --git a/metadata.rb b/metadata.rb index 636190d..8fcaa9e 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,15 +1,16 @@ -name "maven" -maintainer "Opscode, Inc." -maintainer_email "cookbooks@opscode.com" -license "Apache 2.0" -description "Installs maven 2 or 3 and includes a maven resource." +name 'maven' +maintainer 'Opscode, Inc.' +maintainer_email 'cookbooks@opscode.com' +license 'Apache 2.0' +description 'Installs maven 2 or 3 and includes a maven resource.' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version "0.16.5" +version '0.16.5' -depends "java" -depends "ark" - -%w{ debian ubuntu centos redhat fedora }.each do |os| - supports os -end +depends 'ark', '~> 0.4' +depends 'java', '~> 1.13' +supports 'centos' +supports 'debian' +supports 'fedora' +supports 'redhat' +supports 'ubuntu' diff --git a/providers/default.rb b/providers/default.rb index 3b9bf31..43179ba 100644 --- a/providers/default.rb +++ b/providers/default.rb @@ -1,8 +1,9 @@ # # Cookbook Name:: maven -# Provider:: default +# Provider:: default +# # Author:: Bryan W. Berry -# Copyright 2011, Opscode Inc. +# Copyright 2011-2013, Opscode Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,28 +17,30 @@ # See the License for the specific language governing permissions and # limitations under the License. # + require 'chef/mixin/shell_out' require 'chef/mixin/checksum' require 'fileutils' + include Chef::Mixin::ShellOut include Chef::Mixin::Checksum def create_command_string(artifact_file, new_resource) - group_id = "-DgroupId=" + new_resource.group_id - artifact_id = "-DartifactId=" + new_resource.artifact_id - version = "-Dversion=" + new_resource.version - dest = "-Ddest=" + artifact_file - repos = "-DremoteRepositories=" + new_resource.repositories.join(',') - packaging = "-Dpackaging=" + new_resource.packaging - classifier = "-Dclassifier=" + new_resource.classifier if new_resource.classifier + group_id = '-DgroupId=' + new_resource.group_id + artifact_id = '-DartifactId=' + new_resource.artifact_id + version = '-Dversion=' + new_resource.version + dest = '-Ddest=' + artifact_file + repos = '-DremoteRepositories=' + new_resource.repositories.join(',') + packaging = '-Dpackaging=' + new_resource.packaging + classifier = '-Dclassifier=' + new_resource.classifier if new_resource.classifier plugin_version = '2.4' plugin = "org.apache.maven.plugins:maven-dependency-plugin:#{plugin_version}:get" - transitive = "-Dtransitive=" + new_resource.transitive.to_s() + transitive = '-Dtransitive=' + new_resource.transitive.to_s %Q{mvn #{plugin} #{group_id} #{artifact_id} #{version} #{packaging} #{classifier} #{dest} #{repos} #{transitive}} end def get_mvn_artifact(action, new_resource) - if action == "put" + if action == 'put' artifact_file_name = "#{new_resource.name}.#{new_resource.packaging}" else artifact_file_name = if new_resource.classifier.nil? @@ -47,16 +50,15 @@ def get_mvn_artifact(action, new_resource) end end - - Dir.mktmpdir("chef_maven_lwrp") do |tmp_dir| + Dir.mktmpdir('chef_maven_lwrp') do |tmp_dir| tmp_file = ::File.join(tmp_dir, artifact_file_name) shell_out!(create_command_string(tmp_file, new_resource)) dest_file = ::File.join(new_resource.dest, artifact_file_name) - unless (::File.exists?(dest_file) && (checksum(tmp_file) == (checksum(dest_file)))) + unless ::File.exists?(dest_file) && checksum(tmp_file) == checksum(dest_file) directory new_resource.dest do recursive true - mode 00755 + mode '0755' end.run_action(:create) FileUtils.cp(tmp_file, dest_file, :preserve => true) @@ -73,9 +75,13 @@ def get_mvn_artifact(action, new_resource) end action :install do - get_mvn_artifact("install", new_resource) + converge_by("Install #{new_resource}") do + get_mvn_artifact('install', new_resource) + end end action :put do - get_mvn_artifact("put", new_resource) + converge_by("Put #{new_resource}") do + get_mvn_artifact('put', new_resource) + end end diff --git a/recipes/default.rb b/recipes/default.rb index 32885dc..f86f44e 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -20,20 +20,20 @@ # limitations under the License. # -include_recipe "java" -include_recipe "ark" +include_recipe 'java::default' +include_recipe 'ark::default' mvn_version = node['maven']['version'].to_s -ark "maven" do - url node['maven'][mvn_version]['url'] +ark 'maven' do + url node['maven'][mvn_version]['url'] checksum node['maven'][mvn_version]['checksum'] home_dir node['maven']['m2_home'] - version node['maven'][mvn_version]['version'] + version node['maven'][mvn_version]['version'] append_env_path true end -template "/etc/mavenrc" do - source "mavenrc.erb" - mode 00755 +template '/etc/mavenrc' do + source 'mavenrc.erb' + mode '0755' end diff --git a/recipes/test.rb b/recipes/test.rb deleted file mode 100644 index e990aa1..0000000 --- a/recipes/test.rb +++ /dev/null @@ -1,82 +0,0 @@ -include_recipe "maven" - -user "foobarbaz" - -%w(/usr/local/notifyOne /usr/local/notifyTwo /usr/local/foobar/lib/mysql-connector-java-5.1.19.jar).each do |fname| - file fname do - action :delete - ignore_failure true - end -end - - -file "/usr/local/notifyOne" do - content "I was notified" - action :nothing -end - -file "/usr/local/notifyTwo" do - content "I was notified" - action :nothing -end - - -# basic test -maven "mysql-connector-java" do - group_id "mysql" - version "5.1.19" - mode 0755 - owner "foobarbaz" - dest "/usr/local/foobar/lib/" - notifies :create, "file[/usr/local/notifyOne]" -end - -maven "otherNameThanBefore" do - artifact_id "mysql-connector-java" - group_id "mysql" - version "5.1.19" - mode 0755 - owner "foobarbaz" - dest "/usr/local/foobar/lib/" - notifies :create, "file[/usr/local/notifyTwo]" -end - - -# test from alternate repo -maven "java persistence library" do - artifact_id "javax.persistence" - group_id "org.eclipse.persistence" - version "2.0.0" - repositories [ "http://mirrors.ibiblio.org/pub/mirrors/maven2/" ] - dest "/usr/local/foobar/lib" -end - -# test from multiple repositories -maven "postgresql" do - group_id "postgresql" - version "9.0-801.jdbc4" - repositories [ - "http://mirrors.ibiblio.org/pub/mirrors/maven2/", - "http://repo1.maven.apache.org/maven2" - ] - dest "/usr/local/foobar/lib" -end - - -# test downloading hudson plugin and use old alias -maven "mm-mysql" do - groupId "mm-mysql" - version "2.0.13" - packaging "pom" - dest "/usr/local/foobar/lib" -end - -maven "solr-foo" do - artifact_id "solr" - groupId "org.apache.solr" - version "3.6.1" - packaging "war" - dest "/usr/local/foobar/lib" - action :put - transitive true -end diff --git a/resources/default.rb b/resources/default.rb index 6d1de9e..699edb6 100644 --- a/resources/default.rb +++ b/resources/default.rb @@ -1,6 +1,7 @@ # # Cookbook Name:: maven -# Resource:: default +# Resource:: default +# # Author:: Bryan W. Berry # Copyright 2012, Opscode Inc. # @@ -19,19 +20,19 @@ actions :install, :put -attribute :artifact_id, :kind_of => String -attribute :group_id, :kind_of => String, :required => true -attribute :dest, :kind_of => String -attribute :version, :kind_of => String, :required => true -attribute :packaging, :kind_of => String, :default => "jar" -attribute :classifier, :kind_of => String -attribute :owner, :kind_of => String, :default => "root" -attribute :mode, :kind_of => Integer, :default => 0644 +attribute :artifact_id, :kind_of => String +attribute :group_id, :kind_of => String, :required => true +attribute :dest, :kind_of => String +attribute :version, :kind_of => String, :required => true +attribute :packaging, :kind_of => String, :default => 'jar' +attribute :classifier, :kind_of => String +attribute :owner, :kind_of => String, :default => 'root' +attribute :mode, :kind_of => [Integer, String], :default => '0644' attribute :repositories, :kind_of => Array -attribute :transitive, :kind_of => [ TrueClass, FalseClass ], :default => false +attribute :transitive, :kind_of => [TrueClass, FalseClass], :default => false -alias :artifactId :artifact_id -alias :groupId :group_id +alias_method :artifactId, :artifact_id # rubocop:disable SymbolName +alias_method :groupId, :group_id # rubocop:disable SymbolName def initialize(*args) super diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..a349ba4 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,6 @@ +require 'chefspec' +require_relative 'support/matchers/ark_matchers' + +Berkshelf.ui.mute do + Berkshelf::Berksfile.from_file('Berksfile').install(path: 'vendor/cookbooks') +end diff --git a/spec/support/matchers/ark_matchers.rb b/spec/support/matchers/ark_matchers.rb new file mode 100644 index 0000000..945ab80 --- /dev/null +++ b/spec/support/matchers/ark_matchers.rb @@ -0,0 +1,6 @@ +module ChefSpec + # Custom matchers for ark + module Matchers + define_resource_matchers([:install], [:ark], :name) + end +end diff --git a/spec/unit/recipes/default_spec.rb b/spec/unit/recipes/default_spec.rb new file mode 100644 index 0000000..8b1e7d4 --- /dev/null +++ b/spec/unit/recipes/default_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe 'maven::default' do + let(:chef_run) { ChefSpec::ChefRunner.new(cookbook_path: ['vendor/cookbooks']).converge(described_recipe) } + + it 'includes the java recipe' do + expect(chef_run).to include_recipe('java::default') + end + + it 'includes the ark recipe' do + expect(chef_run).to include_recipe('ark::default') + end + + it 'downloads ark' do + expect(chef_run).to install_ark('maven') + end + + it 'writes the `/etc/mavenrc`' do + template = chef_run.template('/etc/mavenrc') + expect(template).to be + expect(template.source).to eq('mavenrc.erb') + expect(template.mode).to eq('0755') + end +end diff --git a/test/fixtures/cookbooks/fake/metadata.rb b/test/fixtures/cookbooks/fake/metadata.rb new file mode 100644 index 0000000..112a01b --- /dev/null +++ b/test/fixtures/cookbooks/fake/metadata.rb @@ -0,0 +1,4 @@ +name 'fake' +version '1.0.0' + +depends 'maven' diff --git a/test/fixtures/cookbooks/fake/recipes/default.rb b/test/fixtures/cookbooks/fake/recipes/default.rb new file mode 100644 index 0000000..98311bf --- /dev/null +++ b/test/fixtures/cookbooks/fake/recipes/default.rb @@ -0,0 +1,78 @@ +include_recipe 'maven::default' + +user 'foobarbaz' + +%w(/usr/local/notifyOne /usr/local/notifyTwo /usr/local/foobar/lib/mysql-connector-java-5.1.19.jar).each do |fname| + file fname do + action :delete + ignore_failure true + end +end + +file '/usr/local/notifyOne' do + content 'I was notified' + action :nothing +end + +file '/usr/local/notifyTwo' do + content 'I was notified' + action :nothing +end + +# Basic test +maven 'mysql-connector-java' do + group_id 'mysql' + version '5.1.19' + mode '0755' + owner 'foobarbaz' + dest '/usr/local/foobar/lib/' + notifies :create, 'file[/usr/local/notifyOne]' +end + +maven 'otherNameThanBefore' do + artifact_id 'mysql-connector-java' + group_id 'mysql' + version '5.1.19' + mode '0755' + owner 'foobarbaz' + dest '/usr/local/foobar/lib/' + notifies :create, 'file[/usr/local/notifyTwo]' +end + +# Test from alternate repo +maven 'java persistence library' do + artifact_id 'javax.persistence' + group_id 'org.eclipse.persistence' + version '2.0.0' + repositories %w(http://mirrors.ibiblio.org/pub/mirrors/maven2/) + dest '/usr/local/foobar/lib' +end + +# test from multiple repositories +maven 'postgresql' do + group_id 'postgresql' + version '9.0-801.jdbc4' + dest '/usr/local/foobar/lib' + repositories [ + 'http://mirrors.ibiblio.org/pub/mirrors/maven2/', + 'http://repo1.maven.apache.org/maven2' + ] +end + +# Test downloading hudson plugin and use old alias +maven 'mm-mysql' do + groupId 'mm-mysql' + version '2.0.13' + packaging 'pom' + dest '/usr/local/foobar/lib' +end + +maven 'solr-foo' do + artifact_id 'solr' + groupId 'org.apache.solr' + version '3.6.1' + packaging 'war' + dest '/usr/local/foobar/lib' + action :put + transitive true +end diff --git a/test/integration/maven2/serverspec/maven_spec.rb b/test/integration/maven2/serverspec/maven_spec.rb new file mode 100644 index 0000000..958cc66 --- /dev/null +++ b/test/integration/maven2/serverspec/maven_spec.rb @@ -0,0 +1,39 @@ +require 'serverspec' +include Serverspec::Helper::Exec + +describe 'Maven LWRP' do + describe file('/usr/local/foobar/lib/mysql-connector-java-5.1.19.jar') do + it { should be_a_file } + it { should be_mode('755') } + it { should be_owned_by('foobarbaz') } + it { should be_grouped_into('foobarbaz') } + end + + describe file('/usr/local/foobar/lib/javax.persistence-2.0.0.jar') do + it { should be_a_file } + end + + describe file('/usr/local/foobar/lib/postgresql-9.0-801.jdbc4.jar') do + it { should be_a_file } + end + + describe file('/usr/local/foobar/lib/mm-mysql-2.0.13.pom') do + it { should be_a_file } + end + + describe file('/usr/local/foobar/lib/solr-foo.war') do + it { should be_a_file } + end + + describe file('/etc/mavenrc') do + it { should be_a_file } + end + + describe file('/usr/local/notifyOne') do + it { should be_a_file } + end + + describe file('/usr/local/notifyTwo') do + it { should be_a_file } + end +end diff --git a/test/integration/maven3/serverspec/maven_spec.rb b/test/integration/maven3/serverspec/maven_spec.rb new file mode 100644 index 0000000..958cc66 --- /dev/null +++ b/test/integration/maven3/serverspec/maven_spec.rb @@ -0,0 +1,39 @@ +require 'serverspec' +include Serverspec::Helper::Exec + +describe 'Maven LWRP' do + describe file('/usr/local/foobar/lib/mysql-connector-java-5.1.19.jar') do + it { should be_a_file } + it { should be_mode('755') } + it { should be_owned_by('foobarbaz') } + it { should be_grouped_into('foobarbaz') } + end + + describe file('/usr/local/foobar/lib/javax.persistence-2.0.0.jar') do + it { should be_a_file } + end + + describe file('/usr/local/foobar/lib/postgresql-9.0-801.jdbc4.jar') do + it { should be_a_file } + end + + describe file('/usr/local/foobar/lib/mm-mysql-2.0.13.pom') do + it { should be_a_file } + end + + describe file('/usr/local/foobar/lib/solr-foo.war') do + it { should be_a_file } + end + + describe file('/etc/mavenrc') do + it { should be_a_file } + end + + describe file('/usr/local/notifyOne') do + it { should be_a_file } + end + + describe file('/usr/local/notifyTwo') do + it { should be_a_file } + end +end