anvil-core 0.0.1.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +30 -0
- data/Rakefile +6 -0
- data/anvil-core.gemspec +35 -0
- data/bin/anvil +8 -0
- data/lib/anvil.rb +13 -0
- data/lib/anvil/assure.rb +9 -0
- data/lib/anvil/assures/directory_assure.rb +11 -0
- data/lib/anvil/assures/file_assure.rb +11 -0
- data/lib/anvil/cli.rb +59 -0
- data/lib/anvil/config.rb +15 -0
- data/lib/anvil/config/class_methods.rb +41 -0
- data/lib/anvil/parser.rb +34 -0
- data/lib/anvil/rubygems.rb +19 -0
- data/lib/anvil/task.rb +47 -0
- data/lib/anvil/task/class_methods.rb +39 -0
- data/lib/anvil/task/naming.rb +28 -0
- data/lib/anvil/task/options.rb +41 -0
- data/lib/anvil/task/repositories.rb +13 -0
- data/lib/anvil/task_manager.rb +47 -0
- data/lib/anvil/version.rb +3 -0
- data/lib/gem_ext/mixlib.rb +22 -0
- data/lib/tasks/gem_build_task.rb +51 -0
- data/lib/tasks/help_task.rb +20 -0
- data/lib/tasks/projects/add_task.rb +31 -0
- data/lib/tasks/projects/list_task.rb +21 -0
- data/spec/lib/assure_spec.rb +15 -0
- data/spec/lib/assures/directory_assure_spec.rb +19 -0
- data/spec/lib/assures/file_assure_spec.rb +13 -0
- data/spec/lib/cli_spec.rb +54 -0
- data/spec/lib/config_spec.rb +24 -0
- data/spec/lib/task/naming_spec.rb +26 -0
- data/spec/lib/task/options_spec.rb +33 -0
- data/spec/lib/task_manager_spec.rb +45 -0
- data/spec/lib/task_spec.rb +74 -0
- data/spec/lib/tasks/gem_build_task_spec.rb +89 -0
- data/spec/lib/tasks/projects/add_task_spec.rb +26 -0
- data/spec/lib/tasks/projects/list_task_spec.rb +20 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/dot_anvil/config.rb +2 -0
- data/spec/support/fixtures/dummy_after_task.rb +3 -0
- data/spec/support/fixtures/dummy_assure.rb +5 -0
- data/spec/support/fixtures/dummy_before_task.rb +3 -0
- data/spec/support/fixtures/dummy_failed_assure.rb +5 -0
- data/spec/support/fixtures/dummy_task.rb +15 -0
- data/spec/support/fixtures/foo/dummy_task.rb +5 -0
- data/spec/support/shared/config_context.rb +10 -0
- 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
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
data/anvil-core.gemspec
ADDED
@@ -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
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'
|
data/lib/anvil/assure.rb
ADDED
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
|
data/lib/anvil/config.rb
ADDED
@@ -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
|
data/lib/anvil/parser.rb
ADDED
@@ -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
|