anvil-core 0.0.1.alpha.1

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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +30 -0
  7. data/Rakefile +6 -0
  8. data/anvil-core.gemspec +35 -0
  9. data/bin/anvil +8 -0
  10. data/lib/anvil.rb +13 -0
  11. data/lib/anvil/assure.rb +9 -0
  12. data/lib/anvil/assures/directory_assure.rb +11 -0
  13. data/lib/anvil/assures/file_assure.rb +11 -0
  14. data/lib/anvil/cli.rb +59 -0
  15. data/lib/anvil/config.rb +15 -0
  16. data/lib/anvil/config/class_methods.rb +41 -0
  17. data/lib/anvil/parser.rb +34 -0
  18. data/lib/anvil/rubygems.rb +19 -0
  19. data/lib/anvil/task.rb +47 -0
  20. data/lib/anvil/task/class_methods.rb +39 -0
  21. data/lib/anvil/task/naming.rb +28 -0
  22. data/lib/anvil/task/options.rb +41 -0
  23. data/lib/anvil/task/repositories.rb +13 -0
  24. data/lib/anvil/task_manager.rb +47 -0
  25. data/lib/anvil/version.rb +3 -0
  26. data/lib/gem_ext/mixlib.rb +22 -0
  27. data/lib/tasks/gem_build_task.rb +51 -0
  28. data/lib/tasks/help_task.rb +20 -0
  29. data/lib/tasks/projects/add_task.rb +31 -0
  30. data/lib/tasks/projects/list_task.rb +21 -0
  31. data/spec/lib/assure_spec.rb +15 -0
  32. data/spec/lib/assures/directory_assure_spec.rb +19 -0
  33. data/spec/lib/assures/file_assure_spec.rb +13 -0
  34. data/spec/lib/cli_spec.rb +54 -0
  35. data/spec/lib/config_spec.rb +24 -0
  36. data/spec/lib/task/naming_spec.rb +26 -0
  37. data/spec/lib/task/options_spec.rb +33 -0
  38. data/spec/lib/task_manager_spec.rb +45 -0
  39. data/spec/lib/task_spec.rb +74 -0
  40. data/spec/lib/tasks/gem_build_task_spec.rb +89 -0
  41. data/spec/lib/tasks/projects/add_task_spec.rb +26 -0
  42. data/spec/lib/tasks/projects/list_task_spec.rb +20 -0
  43. data/spec/spec_helper.rb +26 -0
  44. data/spec/support/dot_anvil/config.rb +2 -0
  45. data/spec/support/fixtures/dummy_after_task.rb +3 -0
  46. data/spec/support/fixtures/dummy_assure.rb +5 -0
  47. data/spec/support/fixtures/dummy_before_task.rb +3 -0
  48. data/spec/support/fixtures/dummy_failed_assure.rb +5 -0
  49. data/spec/support/fixtures/dummy_task.rb +15 -0
  50. data/spec/support/fixtures/foo/dummy_task.rb +5 -0
  51. data/spec/support/shared/config_context.rb +10 -0
  52. metadata +245 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c082eabf101a620961dc1325d55a7235e427ba62
4
+ data.tar.gz: 4b78960acabfbe004739467088eb9ed28cdc1ba1
5
+ SHA512:
6
+ metadata.gz: a60cd3ccd83e0caa7cf709e2cb22888aeebd47d5082c97da61e1ea37f87a1d20a0c3cf1028aea0055c34ad1fa32aa3d08945832e19be9d5e1359a8d7b749fb47
7
+ data.tar.gz: 9d0d04affd45adc653858b94dbbfec6dbbe348c602a2532ef3902188f7fe2a702508bf32fe25d3829defe7d8fb1a6ae6583f78007f6332bcf1d1b0434f25d9a9
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor
19
+ .rspec
20
+ .ruby-version
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in anvil-core.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rake'
8
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Francisco J.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Anvil
2
+
3
+ Anvil is a tool for the real craftsmen to build its own tools.
4
+
5
+ - [![Build Status](https://travis-ci.org/anvil-src/anvil-core.png?branch=master)](https://travis-ci.org/anvil-src/anvil-core)
6
+
7
+
8
+ Anvil tries to be a framework for building command line applications to
9
+ automate tedious tasks like apps or gems releasing process. Pull request
10
+ updating, etc.
11
+
12
+ ## Installation
13
+
14
+ To install it:
15
+
16
+ gem install anvil
17
+
18
+ ## Usage
19
+
20
+ To see all the options execute:
21
+
22
+ $ anvil
23
+
24
+ ## Contributing
25
+
26
+ 1. Fork it
27
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
28
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
29
+ 4. Push to the branch (`git push origin my-new-feature`)
30
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -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
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'anvil/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'anvil-core'
8
+ spec.version = Anvil::VERSION
9
+ spec.authors = ['Fran Casas', 'Jon de Andres']
10
+ spec.email = %w(nflamel@otrobloggeek.com jondeandres@gmail.com)
11
+ spec.description = 'Anvil is a tool for building tools.'
12
+ spec.summary = <<SUMMARY
13
+ Anvil is a tool for building tools. A tool that a real craftsmen uses to build its tools.
14
+ SUMMARY
15
+ spec.homepage = 'http://github.com/anvil-src/anvil-core'
16
+ spec.license = 'MIT'
17
+
18
+ spec.files = `git ls-files -z`.split("\x0")
19
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
21
+ spec.require_paths = %w(lib)
22
+
23
+ # Runtime dependencies
24
+ spec.add_runtime_dependency 'git', '~> 1.2'
25
+ spec.add_runtime_dependency 'activesupport', '~> 4.0'
26
+ spec.add_runtime_dependency 'mixlib-config', '~> 2.1'
27
+ spec.add_runtime_dependency 'cocaine', '~> 0.5'
28
+
29
+ # Development dependencies
30
+ spec.add_development_dependency 'bundler', '~> 1.5'
31
+ spec.add_development_dependency 'rspec', '~> 2.14'
32
+ spec.add_development_dependency 'byebug', '~> 2.6'
33
+ spec.add_development_dependency 'fakefs', '~> 0.5'
34
+ spec.add_development_dependency 'rubocop', '~> 0.18'
35
+ end
data/bin/anvil ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'anvil'
6
+
7
+ Anvil::Config.init
8
+ Anvil::Cli.new.run ARGV
data/lib/anvil.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'anvil/version'
2
+ require 'active_support/core_ext'
3
+
4
+ module Anvil
5
+ # Your code goes here...
6
+ end
7
+
8
+ require 'anvil/config'
9
+ require 'anvil/cli'
10
+ require 'anvil/task'
11
+ require 'anvil/assure'
12
+ require 'anvil/assures/file_assure'
13
+ require 'anvil/assures/directory_assure'
@@ -0,0 +1,9 @@
1
+ module Anvil
2
+ class Assure
3
+ class << self
4
+ def from_name(assure_name)
5
+ "#{assure_name}_assure".camelize.constantize
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Anvil
2
+ class DirectoryAssure < Anvil::FileAssure
3
+ def assured?(dir)
4
+ super && assure_dir?(dir)
5
+ end
6
+
7
+ def assure_dir?(dirname)
8
+ File.directory? dirname
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Anvil
2
+ class FileAssure < Anvil::Assure
3
+ def assured?(file)
4
+ assure_exists? file
5
+ end
6
+
7
+ def assure_exists?(file)
8
+ File.exists? file
9
+ end
10
+ end
11
+ end
data/lib/anvil/cli.rb ADDED
@@ -0,0 +1,59 @@
1
+ require 'anvil/task_manager'
2
+ require 'tasks/help_task'
3
+
4
+ module Anvil
5
+ class Cli
6
+ HELP = <<-HELP
7
+ Anvil is a tool for making your life easier.
8
+
9
+ Available tasks:
10
+ HELP
11
+
12
+ def run(argv)
13
+ load_tasks
14
+
15
+ if argv.empty?
16
+ print_help
17
+ else
18
+ build_task(argv).run
19
+ end
20
+ end
21
+
22
+ def load_tasks
23
+ Anvil::TaskManager.load_tasks
24
+ end
25
+
26
+ def build_task(argv)
27
+ arguments = argv.dup
28
+ task_name = arguments.shift
29
+ klazz = Task.from_name(task_name)
30
+ klazz.new(*klazz.parse_options!(arguments))
31
+ rescue NameError
32
+ task_not_found(task_name)
33
+ exit(FALSE)
34
+ rescue ArgumentError
35
+ help(task_name)
36
+ exit(FALSE)
37
+ end
38
+
39
+ def task_not_found(task_name)
40
+ printf("Task '#{task_name}' not found\n\n")
41
+ print_help
42
+ end
43
+
44
+ def help(task_name)
45
+ printf("Wrong number of arguments.\n\n")
46
+ HelpTask.run(task_name)
47
+ end
48
+
49
+ def print_help
50
+ printf('%s', HELP)
51
+ tasks = Anvil::TaskManager.tasks_by_name
52
+ tasks.each { |task| print_task_line(task) }
53
+ end
54
+
55
+ def print_task_line(task)
56
+ printf("%-20s %s\n", task.task_name, task.description)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ require 'mixlib/config'
2
+ require 'anvil/config/class_methods'
3
+ require 'gem_ext/mixlib'
4
+
5
+ module Anvil
6
+ module Config
7
+ extend Mixlib::Config
8
+ extend Anvil::Config::ClassMethods
9
+
10
+ config_context :github do
11
+ configurable :user
12
+ configurable :token
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ require 'fileutils'
2
+
3
+ module Anvil
4
+ module Config
5
+ module ClassMethods
6
+ def base_path
7
+ File.expand_path('~/.anvil')
8
+ end
9
+
10
+ def base_tasks_path
11
+ "#{base_path}/tasks"
12
+ end
13
+
14
+ def base_config_path
15
+ "#{base_path}/config.rb"
16
+ end
17
+
18
+ def base_projects_path
19
+ "#{base_path}/projects"
20
+ end
21
+
22
+ def init
23
+ init_base_path
24
+ init_config
25
+ end
26
+
27
+ protected
28
+
29
+ def init_base_path
30
+ FileUtils.mkdir_p(base_path)
31
+ FileUtils.mkdir_p(base_tasks_path)
32
+ FileUtils.mkdir_p(base_projects_path)
33
+ FileUtils.touch(base_config_path) unless File.exists?(base_config_path)
34
+ end
35
+
36
+ def init_config
37
+ from_file base_config_path
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ module Anvil
2
+ class Parser < OptionParser
3
+ attr_accessor :options
4
+ attr_accessor :task
5
+
6
+ def options
7
+ @options ||= {}
8
+ end
9
+
10
+ def arguments(args = [])
11
+ @arguments ||= []
12
+ @arguments += args if args.any?
13
+ @arguments.compact
14
+ end
15
+
16
+ def banner
17
+ unless @banner
18
+ @banner = banner_string
19
+ visit(:add_banner, @banner)
20
+ end
21
+
22
+ @banner
23
+ end
24
+
25
+ def banner_string
26
+ args = arguments.map(&:upcase).join(' ')
27
+ message = "Usage: anvil #{task.task_name}"
28
+ message += " #{args}" unless args.empty?
29
+ message += ' [options]'
30
+
31
+ message
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ require 'cocaine'
2
+
3
+ module Anvil
4
+ class Rubygems
5
+ class << self
6
+ def build(gemspec)
7
+ line = Cocaine::CommandLine.new 'gem', 'build :gemspec'
8
+
9
+ line.run gemspec: gemspec
10
+ end
11
+
12
+ def install(gem_file)
13
+ line = Cocaine::CommandLine.new 'gem', 'install :gem_file'
14
+
15
+ line.run gem_file: gem_file
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/anvil/task.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'anvil/task/class_methods'
2
+ require 'anvil/task/naming'
3
+ require 'anvil/task/options'
4
+
5
+ module Anvil
6
+ class Task
7
+ extend ClassMethods
8
+ extend Naming
9
+ extend Options
10
+
11
+ attr_reader :options
12
+
13
+ def initialize(options = {})
14
+ @options = options
15
+ end
16
+
17
+ def run
18
+ if run_assures
19
+ run_before_callbacks
20
+ run_task
21
+ run_after_callbacks
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def run_after_callbacks
28
+ self.class.afters.each do |after|
29
+ after[0].new(after[1]).run
30
+ end
31
+ end
32
+
33
+ def run_assures
34
+ self.class.assures.map { |a| a.new.assured? }.all?
35
+ end
36
+
37
+ def run_before_callbacks
38
+ self.class.befores.each do |before|
39
+ before[0].new(before[1]).run
40
+ end
41
+ end
42
+
43
+ def run_task
44
+ task
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ require 'optparse'
2
+
3
+ module Anvil
4
+ class Task
5
+ module ClassMethods
6
+ def afters
7
+ @afters ||= []
8
+ end
9
+
10
+ def befores
11
+ @befores ||= []
12
+ end
13
+
14
+ def assures
15
+ @assures ||= []
16
+ end
17
+
18
+ def after(task_name, options = {})
19
+ afters << [from_name(task_name), options]
20
+ end
21
+
22
+ def assure(assure_name)
23
+ assures << Assure.from_name(assure_name)
24
+ end
25
+
26
+ def before(task_name, options = {})
27
+ befores << [from_name(task_name), options]
28
+ end
29
+
30
+ def run(*args)
31
+ new(*args).run
32
+ end
33
+
34
+ def descendants
35
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
36
+ end
37
+ end
38
+ end
39
+ end