cupper 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +16 -0
  5. data/Gemfile +18 -0
  6. data/README.md +30 -0
  7. data/Rakefile +6 -0
  8. data/bin/cupper +1 -1
  9. data/cupper.gemspec +28 -0
  10. data/lib/cupper.rb +18 -1
  11. data/lib/cupper/cli.rb +63 -0
  12. data/lib/cupper/collect.rb +51 -0
  13. data/lib/cupper/cookbook.rb +71 -0
  14. data/lib/cupper/cookbook_file.rb +10 -0
  15. data/lib/cupper/cupperfile.rb +22 -0
  16. data/lib/cupper/entity.rb +63 -0
  17. data/lib/cupper/environment.rb +177 -0
  18. data/lib/cupper/errors.rb +84 -0
  19. data/lib/cupper/ohai_plugins.rb +13 -0
  20. data/lib/cupper/platform_collector.rb +40 -0
  21. data/lib/cupper/plugins/cupper/arch.rb +43 -0
  22. data/lib/cupper/plugins/cupper/debian.rb +48 -0
  23. data/lib/cupper/plugins/ohai/dpci.rb +30 -0
  24. data/lib/cupper/plugins/ohai/files.rb +68 -0
  25. data/lib/cupper/plugins/ohai/init_system.rb +14 -0
  26. data/lib/cupper/plugins/ohai/pacman.rb +31 -0
  27. data/lib/cupper/plugins/ohai/pkg_deps.rb +30 -0
  28. data/lib/cupper/plugins/ohai/pkg_manager.rb +31 -0
  29. data/lib/cupper/plugins/ohai/services.rb +20 -0
  30. data/lib/cupper/project.rb +40 -0
  31. data/lib/cupper/recipe.rb +240 -0
  32. data/lib/cupper/templates/CupperFile.erb +1 -0
  33. data/lib/cupper/templates/_cookbook_file.erb +9 -0
  34. data/lib/cupper/templates/_groups.erb +10 -0
  35. data/lib/cupper/templates/_links.erb +10 -0
  36. data/lib/cupper/templates/_package.erb +19 -0
  37. data/lib/cupper/templates/_services.erb +7 -0
  38. data/lib/cupper/templates/_templates.erb +11 -0
  39. data/lib/cupper/templates/_users.erb +10 -0
  40. data/lib/cupper/templates/cookbook_file.erb +1 -0
  41. data/lib/cupper/templates/recipe.erb +7 -0
  42. data/lib/cupper/version.rb +3 -0
  43. data/templates/locales/en.yml +17 -0
  44. metadata +125 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2987796a753b3738ed695df15aa19fe0ae21881
4
- data.tar.gz: 1ac44330efe68aa62f0151e654132227f9f55125
3
+ metadata.gz: 4cb1f5ee3842ee97e25770577a390f8547a47e3a
4
+ data.tar.gz: c2e64363e16d0d940d9a542fec515b1524d93b1c
5
5
  SHA512:
6
- metadata.gz: bb25e0972fb24b3467dc476c3052a01731cf5b70ce88f1287ea214a00714d210106c1d9bfa57d4afdf44dab93e01945d7d0561cb089096aa5ba24030e7025094
7
- data.tar.gz: c08a8b850643e6857324d198df1b9f5cbf8bf0e16c52c2db3440a916b48343f5ac7da4eb3843f5d5535dd6bcb1182e51fce30614d17d8bd0feb5e492e36aa733
6
+ metadata.gz: c4216eeb5b6377d1e1240b15dde4b585fc347a1e34d1188529b0e7ffc0a8337626e80f24dc1cb35153e11080f4b1e4ac267590660591744343a9103499581fda
7
+ data.tar.gz: 394040efd699a88b89d51ff7361abc483f93b9b034fb90929d79c033201bdbac469425819c6c15a75274677285b4d5673d25ea404b09f4863e555d1e290bcb84
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ sudo: false
3
+ branches:
4
+ - master
5
+ - dev
6
+
7
+ rvm:
8
+ - 2.2.1
9
+ - 2.3.0
10
+
11
+ before_install:
12
+ - gem update --system
13
+ - gem install bundler
14
+
15
+ after_success:
16
+ - coveralls
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cupper.gemspec
4
+ gemspec
5
+
6
+ gem 'ohai'
7
+ gem 'thor'
8
+ gem 'i18n'
9
+ gem 'colorize'
10
+ gem 'coveralls', require: false
11
+
12
+ group :development do
13
+ gem 'rubocop'
14
+ end
15
+
16
+ group :test do
17
+ gem 'rspec'
18
+ end
@@ -0,0 +1,30 @@
1
+ # Cupper
2
+
3
+ [![Join the chat at https://gitter.im/cupper-reverse-recipe/cupper](https://badges.gitter.im/cupper-reverse-recipe/cupper.svg)](https://gitter.im/cupper-reverse-recipe/cupper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+ [![Coverage Status](https://coveralls.io/repos/github/cupper-reverse-recipe/cupper/badge.svg?branch=master)](https://coveralls.io/github/cupper-reverse-recipe/cupper?branch=master)
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'cupper'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install cupper
21
+
22
+ ## Usage
23
+
24
+
25
+ ## Development
26
+
27
+
28
+ ## Contributing
29
+
30
+
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/cupper CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'cupper'
4
-
4
+ Cupper::Cli.start
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cupper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cupper'
8
+ spec.version = Cupper::VERSION
9
+ spec.authors = ['Paulo Tada', 'Lucas Severo']
10
+ spec.email = ['paulohtfs@gmail.com', 'lucassalves65@gmail.com']
11
+
12
+ spec.summary = 'Reverse recipe'
13
+ spec.description = 'Taste your system and create a recipe'
14
+ spec.homepage = 'https://github.com/cupper-reverse-recipe/cupper'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = 'bin'
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|featires)/)
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.12'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+
26
+ spec.add_runtime_dependency 'thor', '~> 0.19.1'
27
+ spec.add_runtime_dependency 'ohai', '~> 8.15', '>= 8.15.1'
28
+ end
@@ -1,3 +1,20 @@
1
+ require 'cupper/version'
2
+ require 'cupper/project'
3
+ require 'cupper/cli'
4
+ require 'cupper/ohai_plugins'
5
+ require 'cupper/collect'
6
+ require 'cupper/cookbook'
7
+ require 'cupper/entity'
1
8
 
2
- class Cupper
9
+
10
+ module Cupper
11
+ CUPPER_ROOT = File.expand_path(File.dirname(__FILE__))
12
+ OHAI_PLUGINS_PATH = CUPPER_ROOT + '/cupper/plugins/ohai'
13
+ CUPPER_PLUGINS_PATH = CUPPER_ROOT + '/cupper/plugins/cupper'
14
+ TEMPLATE_PATH = CUPPER_ROOT + '/cupper/templates'
15
+
16
+ # REVIEW: maybe there is a better way and place to load all plugins
17
+ # Loading all cupper plugins
18
+ Dir["#{CUPPER_PLUGINS_PATH}/*.rb"].each { |file| require file }
3
19
  end
20
+
@@ -0,0 +1,63 @@
1
+ # This module defines all the class responsable for the command line tool
2
+ # It should call all the others module and classes to provides for the user
3
+ # all the features avaible
4
+ #
5
+
6
+ require 'thor'
7
+ require 'cupper/project'
8
+ require 'cupper/cookbook'
9
+ require 'cupper/ohai_plugins'
10
+
11
+ module Cupper
12
+ class Cli < Thor
13
+ desc 'create [PROJECT_NAME]', 'Create the project structure'
14
+ def create(project_name)
15
+ project = Project.new(project_name)
16
+ project.create
17
+ end
18
+
19
+ desc 'ohai', 'List Ohai plugins'
20
+ def ohai_plugins
21
+ ohai_plugins = OhaiPlugin.new
22
+ plugins = ohai_plugins.list
23
+ puts "Ohai Plugins"
24
+ puts "------------"
25
+ plugins.each do |plugin|
26
+ puts plugin
27
+ end
28
+ end
29
+
30
+ desc 'generate', 'Extract configuration and create a cookbook'
31
+ method_option :verbose, :aliases => '-v', :desc => 'Enable output log'
32
+ def generate
33
+ puts "Generating the Cookbook"
34
+ cookbook = Cookbook.new
35
+ if options.verbose?
36
+ puts "Verbose mode enabled"
37
+ cookbook.generate
38
+ else
39
+ Cupper.suppress_output{ cookbook.generate }
40
+ end
41
+ end
42
+ end
43
+
44
+ # When necessary, use this method to supress outputs
45
+ # don't suppress Exeptions
46
+ def self.suppress_output
47
+ begin
48
+ origin_stderr = $stderr.clone
49
+ origin_stdout = $stdout.clone
50
+ $stderr.reopen(File.new('/dev/null', 'w'))
51
+ $stdout.reopen(File.new('/dev/null', 'w'))
52
+ retval = yield
53
+ rescue Exception => e
54
+ $stderr.reopen(origin_stderr)
55
+ $stdout.reopen(origin_stdout)
56
+ raise e
57
+ ensure
58
+ $stderr.reopen(origin_stderr)
59
+ $stdout.reopen(origin_stdout)
60
+ end
61
+ retval
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ require 'ohai'
2
+ require 'cupper/ohai_plugins'
3
+
4
+ module Cupper
5
+ class Collect
6
+ ADDITIONAL_OHAI_PLUGINS = [
7
+ 'packages',
8
+ 'platform_family',
9
+ 'etc'
10
+ ]
11
+
12
+ def initialize
13
+ @data_extraction = Hash.new('No data!')
14
+ @ohai = Ohai::System.new
15
+ @ohai_plugin = OhaiPlugin.new
16
+
17
+ # TODO: Ohai::Config[:plugin_path] is decrepted
18
+ @plugins_path = Cupper::OHAI_PLUGINS_PATH
19
+ Ohai::Config[:plugin_path] << @plugins_path
20
+ end
21
+
22
+ def extract(attribute)
23
+ begin
24
+ object = 'Cupper::'.concat self.platform.capitalize
25
+ platform = Object.const_get(object).new
26
+ extract = platform.method attribute
27
+ extract.call @data_extraction
28
+ rescue NameError
29
+ puts 'Not supported platform' # TODO: treat this better
30
+ end
31
+ end
32
+
33
+ def setup
34
+ plugins = @ohai_plugin.list
35
+ plugins.concat ADDITIONAL_OHAI_PLUGINS
36
+ plugins.each do |plugin|
37
+ extract = @ohai.all_plugins(plugin)
38
+ @data_extraction.update({ plugin => extract.first.data }) # Assuming that the first is the default plugin extractor
39
+ end
40
+ true
41
+ end
42
+
43
+ def platform
44
+ @data_extraction['platform_family']['platform_family']
45
+ end
46
+
47
+ def data
48
+ @data_extraction
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,71 @@
1
+ require 'cupper/collect'
2
+ require 'cupper/recipe'
3
+ require 'cupper/cookbook_file'
4
+
5
+ module Cupper
6
+ class Cookbook
7
+ # TODO: Read config file to tell the project path and configs
8
+ def initialize(cookbookname='default')
9
+ @cookbook_path = "#{Dir.getwd}/#{cookbookname}"
10
+ @cookbook_files_path = "#{@cookbook_path}/files"
11
+ @cookbook_recipes_path = "#{@cookbook_path}/recipes"
12
+ @recipe_deps = [ # TODO this is hard code to reflect all_recipes. Refactor this later
13
+ "#{cookbookname}::cookbook_file",
14
+ "#{cookbookname}::links",
15
+ "#{cookbookname}::groups",
16
+ "#{cookbookname}::services",
17
+ "#{cookbookname}::users",
18
+ "#{cookbookname}::packages",
19
+ ]
20
+ setup_paths
21
+ end
22
+
23
+ def setup_paths
24
+ Dir.mkdir(@cookbook_path) unless Dir.exists?(@cookbook_path)
25
+ Dir.mkdir(@cookbook_files_path) unless Dir.exists?(@cookbook_files_path)
26
+ Dir.mkdir(@cookbook_recipes_path) unless Dir.exists?(@cookbook_recipes_path)
27
+ end
28
+
29
+ def generate
30
+ collector = Collect.new
31
+ collector.setup
32
+ all_recipes(collector)
33
+ all_cookbook_files(collector)
34
+ end
35
+
36
+ def all_recipes(collector)
37
+ Recipe.new(@cookbook_recipes_path, collector, 'recipe', 'default', @recipe_deps).create
38
+ Recipe.new(@cookbook_recipes_path, collector, '_cookbook_file', 'cookbook_files').create
39
+ Recipe.new(@cookbook_recipes_path, collector, '_links', 'links').create
40
+ Recipe.new(@cookbook_recipes_path, collector, '_groups', 'groups').create
41
+ Recipe.new(@cookbook_recipes_path, collector, '_services', 'services').create
42
+ Recipe.new(@cookbook_recipes_path, collector, '_users', 'users').create
43
+ Recipe.new(@cookbook_recipes_path, collector, '_package', 'packages').create
44
+ end
45
+
46
+ def all_cookbook_files(collector)
47
+ expand_cookbook_files(collector.extract 'files')
48
+ end
49
+
50
+ def text_type?(file)
51
+ file[1]['type'].match('text') or file[1]['type'].match('ASCII')
52
+ end
53
+
54
+ def expand_cookbook_files(files)
55
+ files.each do |attr|
56
+ if text_type?(attr) and !(attr[1]['related'].nil?)
57
+ source = attr[0].split('/').last
58
+ content = attr[1]['content']
59
+ CookbookFile.new(@cookbook_files_path, source, content, 'cookbook_file').create
60
+ end
61
+ # TODO: This is a work around to source list file
62
+ # should be replaced for a better logic
63
+ if text_type?(attr) and attr[0].include? "/etc/apt/sources.list"
64
+ source = attr[0].split('/').last
65
+ content = attr[1]['content']
66
+ CookbookFile.new(@cookbook_files_path, source, content, 'cookbook_file').create
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,10 @@
1
+ module Cupper
2
+ class CookbookFile
3
+ include Entity
4
+ def initialize(dest_path, source, content, erb_file = nil, type = nil)
5
+ @source = source
6
+ @content = content
7
+ super(@source, dest_path, erb_file, type)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module Cupper
2
+ class Cupperfile
3
+
4
+ def initialize(loader, keys)
5
+ @keys = keys
6
+ @loader = loader
7
+ @config, _ = loader.load(keys)
8
+ end
9
+
10
+ protected
11
+
12
+ def find_cupperfile(search_path)
13
+ ["Cupperfile", "cupperfile"].each do |cupperfile|
14
+ current_path = search_path.join(cupperfile)
15
+ return current_path if current_path.file?
16
+ end
17
+
18
+ nil
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ module Cupper
2
+ # Entity represents a Entity
3
+ module Entity
4
+ require 'erb'
5
+
6
+ FILE = 'file'
7
+ DIR = 'dir'
8
+
9
+ # As default the Entity is treated as a file
10
+ def initialize(name, dest_path, erb_file = nil, type = nil, extension = '')
11
+ @name = name
12
+ @dest_path = dest_path
13
+ @erb_file = erb_file
14
+ @type = type.nil? ? FILE : type
15
+ @ext = extension
16
+
17
+ @full_path = "#{@dest_path}/#{@name}#{@ext}"
18
+ end
19
+
20
+ # Create the actual file or dir in the correct place
21
+ def create
22
+ content(@erb_file)
23
+ save
24
+ end
25
+
26
+ # Returns the content of the file
27
+ def content(erb_file)
28
+ return false if self.dir?
29
+ @template = File.read("#{TEMPLATE_PATH}/#{erb_file}.erb")
30
+ end
31
+
32
+ def save
33
+ File.open(@full_path,"a+") { |f| f.write(self.render_template) } if self.file?
34
+ Dir.mkdir(@full_path) if self.dir? && !(self.exist?)
35
+ end
36
+
37
+ def render_template
38
+ ERB.new(@template).result(binding)
39
+ end
40
+
41
+ # Treats entity as a file or as a dir
42
+ def file?
43
+ @type == FILE
44
+ end
45
+ def dir?
46
+ @type == DIR
47
+ end
48
+
49
+ def exist?
50
+ return File.exist?(@full_path) if self.file?
51
+ return Dir.exist?(@full_path) if self.dir?
52
+ end
53
+
54
+ def full_path
55
+ @full_path
56
+ end
57
+ end
58
+
59
+ class Attribute
60
+ attr_reader :attr
61
+ end
62
+
63
+ end