Skip to content

Commit 9fd4838

Browse files
initial comimt
0 parents  commit 9fd4838

11 files changed

+322
-0
lines changed

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/.bundle/
2+
/.yardoc
3+
/Gemfile.lock
4+
/_yardoc/
5+
/coverage/
6+
/doc/
7+
/pkg/
8+
/spec/reports/
9+
/tmp/

CODE_OF_CONDUCT.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Contributor Code of Conduct
2+
3+
As contributors and maintainers of this project, and in the interest of
4+
fostering an open and welcoming community, we pledge to respect all people who
5+
contribute through reporting issues, posting feature requests, updating
6+
documentation, submitting pull requests or patches, and other activities.
7+
8+
We are committed to making participation in this project a harassment-free
9+
experience for everyone, regardless of level of experience, gender, gender
10+
identity and expression, sexual orientation, disability, personal appearance,
11+
body size, race, ethnicity, age, religion, or nationality.
12+
13+
Examples of unacceptable behavior by participants include:
14+
15+
* The use of sexualized language or imagery
16+
* Personal attacks
17+
* Trolling or insulting/derogatory comments
18+
* Public or private harassment
19+
* Publishing other's private information, such as physical or electronic
20+
addresses, without explicit permission
21+
* Other unethical or unprofessional conduct
22+
23+
Project maintainers have the right and responsibility to remove, edit, or
24+
reject comments, commits, code, wiki edits, issues, and other contributions
25+
that are not aligned to this Code of Conduct, or to ban temporarily or
26+
permanently any contributor for other behaviors that they deem inappropriate,
27+
threatening, offensive, or harmful.
28+
29+
By adopting this Code of Conduct, project maintainers commit themselves to
30+
fairly and consistently applying these principles to every aspect of managing
31+
this project. Project maintainers who do not follow or enforce the Code of
32+
Conduct may be permanently removed from the project team.
33+
34+
This code of conduct applies both within project spaces and in public spaces
35+
when an individual is representing the project or its community.
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
38+
reported by contacting a project maintainer at [email protected]. All
39+
complaints will be reviewed and investigated and will result in a response that
40+
is deemed necessary and appropriate to the circumstances. Maintainers are
41+
obligated to maintain confidentiality with regard to the reporter of an
42+
incident.
43+
44+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45+
version 1.3.0, available at
46+
[http://contributor-covenant.org/version/1/3/0/][version]
47+
48+
[homepage]: http://contributor-covenant.org
49+
[version]: http://contributor-covenant.org/version/1/3/0/

Gemfile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
source 'https://rubygems.org'
2+
3+
# Specify your gem's dependencies in ruby-puppetfiles.gemspec
4+
gemspec

LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Luca De Vitis
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Ruby::Puppetfiles
2+
3+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ruby/puppetfiles`. To experiment with that code, run `bin/console` for an interactive prompt.
4+
5+
TODO: Delete this and the text above, and describe your gem
6+
7+
## Installation
8+
9+
Add this line to your application's Gemfile:
10+
11+
```ruby
12+
gem 'ruby-puppetfiles'
13+
```
14+
15+
And then execute:
16+
17+
$ bundle
18+
19+
Or install it yourself as:
20+
21+
$ gem install ruby-puppetfiles
22+
23+
## Usage
24+
25+
TODO: Write usage instructions here
26+
27+
## Development
28+
29+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30+
31+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32+
33+
## Contributing
34+
35+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ruby-puppetfiles. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36+
37+
38+
## License
39+
40+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41+

Rakefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require "bundler/gem_tasks"
2+
task :default => :spec

bin/check-puppetfiles.rb

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# rubocop:disable Style/FileName
2+
# @author Luca De Vitis <luca.devitis at moneysupermarket.com>
3+
require 'sensu-plugin/check/cli'
4+
require 'puppetfiles/check'
5+
6+
# See `Puppetfiles::Repo.load_all`
7+
include Puppetfiles::Mock
8+
9+
# This class implements a CLI to `CheckPuppetfiles`. `Sensu::Plugin::CLI` is a
10+
# pretty handy CLI library.
11+
class CheckPuppetfiles < Sensu::Plugin::CLI
12+
option :exclude,
13+
long: '--exclude PATHS',
14+
short: '-x PATHS',
15+
description: 'Exclude paths matching regexp',
16+
required: false,
17+
default: %r{/dev2(-[a-z]+)?/},
18+
proc: proc { |a| /#{a}/ }
19+
20+
option :known,
21+
long: '--known LOCATION',
22+
short: '-k LOCATION',
23+
description: 'Repositories known location regexp',
24+
required: false,
25+
default: /^git@github\.com:MSMFG/,
26+
proc: proc { |a| /#{a}/ }
27+
28+
option :prefix,
29+
long: '--prefix PATH',
30+
short: '-p PATH',
31+
description: 'Puppetfile search base path',
32+
required: false,
33+
default: '.'
34+
35+
include Puppetfiles::Check
36+
37+
def run
38+
load_all_puppetfiles
39+
check_modules_version
40+
check_modules_repo_location
41+
exit
42+
end
43+
end

lib/puppetfiles.rb

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
require 'puppetfiles/version'
2+
require 'singleton'
3+
# @author Luca De Vitis <luca.devitis at moneysupermarket.com>
4+
5+
module Puppetfiles
6+
# The methods in this module basically mock the `Puppetfile`'s syntax, so we
7+
# don't need to parse it: just load the file and let Ruby do the rest.
8+
# Luca's Lazy Bastard Approach.
9+
module Mock
10+
# Mock the `Puppetfile`'s `mod` function call. It actually builds
11+
# `Repo.puppetfiles.loaded` data structure about loaded `Puppetfile`s and
12+
# their modules.
13+
def mod(name, *args)
14+
version = args[0].is_a?(String) ? args[0] : nil
15+
options = args[-1].is_a?(Hash) ? args[-1] : {}
16+
Repo.puppetfiles.loaded[-1][:modules] << {
17+
name: name,
18+
version: version,
19+
options: options
20+
}
21+
end
22+
23+
# Mock the `Puppetfile`'s `forge` function call.
24+
# We are not interested in supporting multiple forges right now.
25+
# @param _ discarded
26+
def forge(_)
27+
yield if block_given?
28+
end
29+
30+
# Mock the `Puppetfile`'s `exclusion` function call.
31+
# @param * discarded
32+
def exclusion(*)
33+
end
34+
35+
# Mock the `Puppetfile`'s `metadata` function call.
36+
def metadata
37+
end
38+
end
39+
40+
# This class provides the methods to work on a repository of `Puppetfile`s.
41+
class Repo
42+
# There must be a single instance only.
43+
include Singleton
44+
45+
# @return [Array] The details of loaded files
46+
def loaded
47+
@loaded ||= []
48+
end
49+
50+
class << self
51+
# Just for readability...
52+
alias puppetfiles instance
53+
54+
# Load all the `Puppetfiles` from the list. If a block is given, then
55+
# load all files for which the block returns `true`. You must include
56+
# `Puppetfiles::Mock` module at script level so that loaded `Puppetfile`s
57+
# do not raise `NoMethodError`.
58+
#
59+
# @param puppetfiles [Array<String>] The list of paths to load from
60+
def load_all(files)
61+
files.each do |file|
62+
if !block_given? || yield(file)
63+
puppetfiles.loaded << { path: file, modules: [] }
64+
load(file)
65+
end
66+
end
67+
end
68+
69+
# Prints error messages for each `Puppetfile` with a module that fails to
70+
# comply the ckeck in the given block.
71+
#
72+
# @param message [String] The error message to print
73+
# @param output [#<<] The output handler
74+
# @param failing A block to yield to, for compliance checking
75+
def check_modules(message, output = $stdout, &failing)
76+
puppetfiles.loaded.each do |puppetfile|
77+
puppetfile[:modules].select(&failing).each do |details|
78+
# Easy to read if sorted. `output` can be mocked for testing.
79+
output << "E: #{puppetfile[:path]}: #{message}: #{details}\n"
80+
end
81+
end
82+
end
83+
end
84+
end
85+
end

lib/puppetfiles/check.rb

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require 'puppetfiles'
2+
# @author Luca De Vitis <luca.devitis at moneysupermarket.com>
3+
module Puppetfiles
4+
# This (MixIn) module contains the logic to be performed on loaded
5+
# `Puppetfile`s. All methods work assuming there is a `config` method (an
6+
# `attr_accessor`, for example) that can return a `Hash` of options `:name
7+
# => value`.
8+
module Check
9+
# Load all `Puppetfile`s from configured `config[:prefix]`
10+
def load_all_puppetfiles
11+
Repo.load_all Dir.glob("#{config[:prefix]}/**/Puppetfile.*") do |file|
12+
!file.match(config[:exclude])
13+
end
14+
end
15+
16+
# Print all `Puppetfile`s that load modules with no version information
17+
def check_modules_version
18+
Repo.check_modules('No version') do |mod_|
19+
!(mod_[:version] || (mod_[:options][:git] && mod_[:options][:ref]))
20+
end
21+
end
22+
23+
# Print all `Puppetfile`s that download a module from an unknown repo
24+
def check_modules_repo_location
25+
Repo.check_modules('Unknown repo') do |mod_|
26+
repo = mod_[:options][:git]
27+
!(repo.nil? || repo.match(config[:known]))
28+
end
29+
end
30+
end
31+
end

lib/puppetfiles/version.rb

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Ruby
2+
module Puppetfiles
3+
VERSION = '0.1.0'.freeze
4+
end
5+
end

ruby-puppetfiles.gemspec

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# coding: utf-8
2+
lib = File.expand_path('../lib', __FILE__)
3+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4+
require 'ruby/puppetfiles/version'
5+
6+
Gem::Specification.new do |spec|
7+
spec.name = "ruby-puppetfiles"
8+
spec.version = Ruby::Puppetfiles::VERSION
9+
spec.authors = ["Luca De Vitis"]
10+
spec.email = ["[email protected]"]
11+
12+
spec.summary = %q{TODO: Write a short summary, because Rubygems requires one.}
13+
spec.description = %q{TODO: Write a longer description or delete this line.}
14+
spec.homepage = "TODO: Put your gem's website or public repo URL here."
15+
spec.license = "MIT"
16+
17+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18+
# delete this section to allow pushing this gem to any host.
19+
if spec.respond_to?(:metadata)
20+
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21+
else
22+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23+
end
24+
25+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26+
spec.bindir = "exe"
27+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28+
spec.require_paths = ["lib"]
29+
30+
spec.add_development_dependency "bundler", "~> 1.11"
31+
spec.add_development_dependency "rake", "~> 10.0"
32+
end

0 commit comments

Comments
 (0)