billygoat 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDc0NDZkNDcyZTIyOWE5ZWNlNzExMmQ5NGUxNGJiODM1ZjI3NzEzYw==
5
+ data.tar.gz: !binary |-
6
+ ODE5ZDhjYjM5YTM3NjgwM2UwYWQyZGEzOTYxM2U1NzIyODkyMDI4NA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NzFmN2VmYzMwMDNmNzJlNThiZTY5ZDNhMjZlZTA3YzdhNTI5Yjc5ZmI1Nzll
10
+ NWU1M2JmNTE2NjBiY2U5ZmUwY2E1NjQ3NmQwZmY3MmE5YTIxODM4NTllZWE0
11
+ MTY2NjhlZjJlNWRkZDA2MzY0ZTE2ODBlN2EzZmNjOTZmNmIxZWM=
12
+ data.tar.gz: !binary |-
13
+ ODAxOTZmODcwNTI0YmYwMDMzODIzZDlkZTRkZDAzNzFmMWYwZDMwOWE1MTc3
14
+ YjliZDNhNDVlOWY4MWY5YTY1MzIyOTIxM2FjMmQyNGM4NjkyODhkM2Q1MWE0
15
+ MGVmMWJmMDg4OWViYTVmOTlkMTYxYmNkNmFkZGVkZmRmNWM4OTc=
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Derrick Parkhurst
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,82 @@
1
+ # Billy::Goat
2
+
3
+ Goat do this for me.
4
+
5
+ <a title="By Kuebi = Armin Kübelbeck (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons" href="http://commons.wikimedia.org/wiki/File%3AHausziege_04.jpg"><img width="100%" alt="Hausziege 04" src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Hausziege_04.jpg/512px-Hausziege_04.jpg"/></a>
6
+
7
+
8
+ ## Installation
9
+
10
+ ```
11
+ $ gem install billygoat
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ Getting the goat to do a task
17
+ ```
18
+ > goat [skill] [task]
19
+ ```
20
+
21
+ [A list of all skills and tasks goat already knows](COMMANDS.md)
22
+
23
+
24
+ Getting the goat to do the default task for a given skill
25
+ ```
26
+ > goat [skill]
27
+ ```
28
+
29
+ Asking the goat about the tasks it knows
30
+ ```
31
+ > goat help
32
+ > goat help [skill]
33
+ > goat help [skill] [task]
34
+ ```
35
+
36
+ Teaching the goat new tasks
37
+ ```
38
+ > goat learn file [file name]
39
+ > goat learn directory [file path]
40
+ ```
41
+
42
+ Which services have you authorized your goat to use?
43
+ ```
44
+ > goat show credentials
45
+ ```
46
+
47
+ Give your goat permission to use a service
48
+ ```
49
+ > goat update [service] [key=value] [key=value]
50
+ > goat update github access_token=XXXXXXXX
51
+ > goat update jenkins username=XXXX password=XXXX server_url=XXXX
52
+ ```
53
+
54
+ Goat knows git
55
+ ```
56
+ > goat branches
57
+ > goat git commit [message]
58
+ > goat git checkout (branch)
59
+ > goat git add_tag [name]
60
+ ```
61
+
62
+ Talk like a goat
63
+ ```
64
+ > goat say Naaaaaaa!
65
+ +-----------+
66
+ | Naaaaaaa! |
67
+ +-----------+
68
+ | (_(
69
+ +-- /_/'_____/)
70
+ " | |
71
+ |""""""|
72
+ ```
73
+
74
+ ## License
75
+
76
+ Copyright (c) 2015 Derrick Parkhurst (derrick.parkhurst@gmail.com),
77
+
78
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
79
+
80
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
81
+
82
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+
7
+ task :build_documentation do
8
+ `bundle exec goat document > COMMANDS.md`
9
+ end
data/bin/goat ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'billygoat'
3
+
4
+ goat = Billy::Goat.new
5
+ goat.execute(*ARGV)
@@ -0,0 +1,66 @@
1
+ module Billy
2
+
3
+ class Brain
4
+
5
+ include Disk
6
+ include Config
7
+ include Settings
8
+ include Knowledge
9
+ include Credentials
10
+ include Skills
11
+
12
+ attr_accessor :skill
13
+
14
+ #
15
+ # Short term memory serving as a workspace
16
+ # for executing tasks
17
+ #
18
+ def memory
19
+ return @memory if @memory
20
+ @memory = Memory.new
21
+ @memory.brain = self
22
+ @memory.credentials = credentials
23
+ @memory.skills = skills
24
+ @memory
25
+ end
26
+
27
+ #
28
+ # Clear the workspace for executing tasks
29
+ #
30
+ def forget
31
+ @memory = nil
32
+ end
33
+
34
+ #
35
+ # Recall a skill and place it in memory
36
+ #
37
+ def recall(name)
38
+ self.skill = find_skill(name)
39
+ return unless skill
40
+
41
+ require skill.internal_location if skill.internal_location
42
+ memory.extend(skill.module)
43
+ end
44
+
45
+ #
46
+ # Execute a task in memory
47
+ #
48
+ def execute(*args)
49
+ assert_skill_loaded
50
+
51
+ if args.empty? || !skill.has_a_task?(args.first)
52
+ args.unshift skill.default_task.name
53
+ end
54
+
55
+ memory.send *args
56
+ end
57
+
58
+ private
59
+
60
+ def assert_skill_loaded
61
+ fail "Naaaa! Unknown skill" unless skill
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,35 @@
1
+ module Billy
2
+
3
+ module Config
4
+
5
+ def root
6
+ @root ||= ENV['HOME']
7
+ end
8
+ attr_writer :root
9
+
10
+ def config_dir
11
+ @config_dir ||= ".goat"
12
+ end
13
+ attr_writer :config_dir
14
+
15
+ def config_path
16
+ "#{root}/#{config_dir}"
17
+ end
18
+
19
+ def create_config_path
20
+ create_path(config_path)
21
+ end
22
+
23
+ #
24
+ # Save all in-memory configuration to disk
25
+ #
26
+ def save_configuration
27
+ save_settings
28
+ update_knowledge
29
+ save_knowledge
30
+ save_credentials
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,28 @@
1
+ module Billy
2
+
3
+ module Credentials
4
+
5
+ def credentials_file
6
+ @credentials_file ||= "credentials.yml"
7
+ end
8
+ attr_writer :credentials_file
9
+
10
+ def credentials_path
11
+ "#{config_path}/#{credentials_file}"
12
+ end
13
+
14
+ def credentials
15
+ return @credentials if @credentials
16
+ save_credentials({}) unless File.exists?(credentials_path)
17
+ @credentials = YAML.load_file(credentials_path)
18
+ @credentials.default_proc = ->(h,k) { h[k] = {} }
19
+ end
20
+
21
+ def save_credentials(credentials = @credentials)
22
+ create_config_path
23
+ save_yaml(credentials_path, credentials)
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,16 @@
1
+ module Dependencies
2
+
3
+ def gem_require(name)
4
+
5
+ begin
6
+ require(name)
7
+ rescue LoadError
8
+ puts "#{name} gem not available but is required"
9
+ puts "try: gem install #{name}"
10
+ fail "required gem not available"
11
+ end
12
+
13
+ end
14
+ module_function :gem_require
15
+
16
+ end
@@ -0,0 +1,15 @@
1
+ module Billy
2
+
3
+ module Disk
4
+
5
+ def create_path(path)
6
+ FileUtils.mkdir_p(path)
7
+ end
8
+
9
+ def save_yaml(file_path, object)
10
+ File.open(file_path, 'w') { |file| file.write(object.to_yaml) }
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,133 @@
1
+ module Billy
2
+
3
+ class Documentation
4
+
5
+ #
6
+ # Documentation includes the method definition and any
7
+ # commented lines preceding the method definition
8
+ #
9
+
10
+ attr_accessor :method
11
+ attr_writer :owner
12
+ attr_accessor :mode
13
+
14
+ def initialize(args)
15
+ args.each { |k,v| public_send("#{k}=",v) }
16
+ end
17
+
18
+ def inspect
19
+ return unless file_name && line_number
20
+ case mode
21
+ when :markdown
22
+ build_markdown
23
+ else
24
+ build
25
+ end
26
+ end
27
+
28
+ def inspect_markdown
29
+ return unless file_name && line_number
30
+ build_markdown
31
+ end
32
+
33
+ def file_name
34
+ @file_name ||= self.method.source_location.first
35
+ end
36
+
37
+ def line_number
38
+ @line_number ||= self.method.source_location.last
39
+ end
40
+
41
+ def parameters
42
+ @parameters ||= self.method.parameters
43
+ end
44
+
45
+ def owner
46
+ @owner ||= self.method.owner.name.downcase
47
+ end
48
+
49
+ def name
50
+ @name ||= self.method.name.downcase
51
+ end
52
+
53
+ def required_parameters
54
+ parameters
55
+ .select{ |pair| pair.first == :req }
56
+ .map{ |pair| pair.last}
57
+ end
58
+
59
+ def optional_parameters
60
+ parameters
61
+ .select{ |pair| pair.first == :opt }
62
+ .map{ |pair| pair.last}
63
+ end
64
+
65
+ def variable_parameters
66
+ parameters
67
+ .select{ |pair| pair.first == :rest }
68
+ .map{ |pair| pair.last}
69
+ end
70
+
71
+ def block_parameters
72
+ parameters
73
+ .select{ |pair| pair.first == :block }
74
+ .map{ |pair| pair.last}
75
+ end
76
+
77
+ def source_file
78
+ File.read(file_name)
79
+ end
80
+
81
+ def source
82
+ source_file.split("\n")
83
+ end
84
+
85
+ def range
86
+ head = tail = line_number - 1
87
+ tail.downto(0).each do
88
+ break unless source[head-1].match(/^\s*#/)
89
+ head -= 1
90
+ end
91
+ (head..tail)
92
+ end
93
+
94
+ def unindent
95
+ ->(line) { line.gsub(/^\s*/, '') }
96
+ end
97
+
98
+ def lines
99
+ source[range].map(&unindent)
100
+ end
101
+
102
+ def build
103
+ doc = lines
104
+ doc[-1] = "goat #{owner} #{name} "
105
+ required_parameters.each do |parameter|
106
+ doc[-1] << "[#{parameter}] "
107
+ end
108
+ optional_parameters.each do |parameter|
109
+ doc[-1] << "(#{parameter}) "
110
+ end
111
+ variable_parameters.each do |parameter|
112
+ doc[-1] << "(*#{parameter}) "
113
+ end
114
+ block_parameters.each do |parameter|
115
+ doc[-1] << "{&#{parameter}} "
116
+ end
117
+ doc << "\n"
118
+ doc
119
+ end
120
+
121
+ def build_markdown
122
+ doc = build
123
+ doc.pop
124
+ doc.map! { |line| line.match(/^\s*#/) ? " #{line}" : line }
125
+ doc.unshift "### #{doc.pop}"
126
+ doc << "\n"
127
+ doc.map! { |line| line.gsub(/(\[)/,'\[').gsub(/(\])/,'\]') }
128
+ doc
129
+ end
130
+
131
+ end
132
+
133
+ end
@@ -0,0 +1,17 @@
1
+ module Billy
2
+
3
+ class Goat
4
+
5
+ def brain
6
+ @brain ||= Brain.new
7
+ end
8
+
9
+ def execute(*args)
10
+ args.shift if brain.recall(args.first)
11
+
12
+ brain.execute(*args)
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,73 @@
1
+ module Billy
2
+
3
+ module Knowledge
4
+
5
+ def knowledge_file
6
+ @knowledge_file ||= "knowledge.yml"
7
+ end
8
+ attr_writer :knowledge_file
9
+
10
+ def knowledge_path
11
+ "#{config_path}/#{knowledge_file}"
12
+ end
13
+
14
+ def knowledge
15
+ return @knowledge if @knowledge
16
+ save_knowledge(default_knowledge) unless File.exists?(knowledge_path)
17
+ @knowledge = YAML.load_file(knowledge_path)
18
+ end
19
+
20
+ def update_knowledge
21
+ knowledge[:skills] = skill_set
22
+ .skills
23
+ .reject{ |skill| autoloaded_skills.map{|s| s[:name]}.include? skill.name }
24
+ .uniq{ |skill| skill.name }
25
+ .map(&:to_h)
26
+ end
27
+
28
+ def default_knowledge
29
+ {
30
+ skills: [
31
+ {
32
+ name: 'Learn',
33
+ internal_location: system_skills_path("learn.rb")
34
+ },
35
+ {
36
+ name: 'Show',
37
+ internal_location: system_skills_path("show.rb")
38
+ },
39
+ {
40
+ name: 'Update',
41
+ internal_location: system_skills_path("update.rb")
42
+ },
43
+ {
44
+ name: 'Help',
45
+ internal_location: system_skills_path("help.rb")
46
+ },
47
+ {
48
+ name: 'Git',
49
+ internal_location: system_skills_path("git.rb")
50
+ },
51
+ {
52
+ name: 'Document',
53
+ internal_location: system_skills_path("document.rb")
54
+ }
55
+ ]
56
+ }
57
+ end
58
+
59
+ def validate_knowledge
60
+ return if knowledge &&
61
+ knowledge.is_a?(Hash) &&
62
+ knowledge.include?(:skills)
63
+ fail "Naaa! Broken knowledge file."
64
+ end
65
+
66
+ def save_knowledge(knowledge = @knowledge)
67
+ create_config_path
68
+ save_yaml(knowledge_path, knowledge)
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,18 @@
1
+ class Memory
2
+
3
+ attr_accessor :brain, :skills, :credentials
4
+
5
+ def say(*args)
6
+ words = args.join(" ")
7
+ puts <<-EOS
8
+ +-#{"-"*words.length}-+
9
+ | #{words} |
10
+ +-#{"-"*words.length}-+
11
+ | (_(
12
+ +-- /_/'_____/)
13
+ " | |
14
+ |""""""|
15
+ EOS
16
+ end
17
+
18
+ end
@@ -0,0 +1,36 @@
1
+ module Billy
2
+
3
+ #
4
+ # Storage for all goat specific settings
5
+ #
6
+ module Settings
7
+
8
+ def settings_file
9
+ @settings ||= "settings.yml"
10
+ end
11
+ attr_writer :settings
12
+
13
+ def settings_path
14
+ "#{config_path}/#{settings_file}"
15
+ end
16
+
17
+ def default_settings
18
+ {
19
+ version: VERSION
20
+ }
21
+ end
22
+
23
+ def settings
24
+ return @settings if @settings
25
+ save_settings(default_settings) unless File.exists?(settings_path)
26
+ @settings = YAML.load_file(settings_path)
27
+ end
28
+
29
+ def save_settings(settings = @settings)
30
+ create_config_path
31
+ save_yaml(settings_path, settings)
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,70 @@
1
+ module Billy
2
+
3
+ class Skill
4
+
5
+ ATTRIBUTES = [:name, :internal_location, :external_location]
6
+ attr_accessor *ATTRIBUTES
7
+
8
+ def initialize(config = {})
9
+ config.each { |k,v| public_send("#{k}=",v) }
10
+ end
11
+
12
+ def to_s
13
+ name
14
+ end
15
+
16
+ def to_h
17
+ ATTRIBUTES.each_with_object({}) do |attribute, hash|
18
+ hash[attribute] = public_send(attribute)
19
+ end
20
+ end
21
+
22
+ def module
23
+ module_from_string(name)
24
+ end
25
+
26
+ def tasks
27
+ return @tasks if @tasks
28
+ require internal_location if internal_location
29
+ methods = self.module.instance_methods - Object.new.methods
30
+ @tasks = methods.map { |method| Task.new(name: method, skill: self) }
31
+ end
32
+
33
+ def default_task
34
+ tasks.first
35
+ end
36
+
37
+ def has_a_task?(name)
38
+ !!find_task(name)
39
+ end
40
+
41
+ def find_task(name)
42
+ tasks.detect{ |task| task.name.to_s.downcase == name.to_s.downcase }
43
+ end
44
+
45
+ def documentation?
46
+ !!has_a_task?(:documentation)
47
+ end
48
+
49
+ def documentation(*args)
50
+ execute_task(:documentation, self, *args)
51
+ end
52
+
53
+ def execute_task(name, *args)
54
+ m = Module.new
55
+ require internal_location
56
+ m.extend(self.module)
57
+ m.send(name, *args)
58
+ end
59
+
60
+ private
61
+
62
+ def module_from_string(str)
63
+ str.split('::').inject(Object) do |mod, module_name|
64
+ mod.const_get(module_name)
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,29 @@
1
+ module Billy
2
+
3
+ module Skills
4
+
5
+ def skills_dir
6
+ @skill_dir ||= "skills"
7
+ end
8
+ attr_writer :skill_dir
9
+
10
+ def skills_path
11
+ "#{config_path}/#{skills_dir}/"
12
+ end
13
+
14
+ def system_skills_path(name=nil)
15
+ File.expand_path("../../skills/#{name}", __FILE__)
16
+ end
17
+
18
+ def skills
19
+ validate_knowledge
20
+ knowledge[:skills].map{ |config| Skill.new(config) }
21
+ end
22
+
23
+ def find_skill(name)
24
+ skills.detect{ |skill| skill.name.downcase == name.downcase }
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,34 @@
1
+ module Billy
2
+
3
+ class Task
4
+
5
+ attr_accessor :skill
6
+
7
+ def initialize(config = {})
8
+ config.each { |k,v| public_send("#{k}=",v) }
9
+ end
10
+
11
+ def name
12
+ @name
13
+ end
14
+
15
+ def name=(value)
16
+ @name = value.to_s.downcase
17
+ end
18
+
19
+ def to_s
20
+ name
21
+ end
22
+
23
+ def method
24
+ require skill.internal_location if skill.internal_location
25
+ skill.module.instance_method(name)
26
+ end
27
+
28
+ def source
29
+ self.method.source_location
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,3 @@
1
+ module Billy
2
+ VERSION = "0.0.7"
3
+ end
data/lib/billygoat.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+
4
+ require "billygoat/version"
5
+ require "billygoat/goat"
6
+ require "billygoat/disk"
7
+ require "billygoat/config"
8
+ require "billygoat/settings"
9
+ require "billygoat/credentials"
10
+ require "billygoat/knowledge"
11
+ require "billygoat/skill"
12
+ require "billygoat/skills"
13
+ require "billygoat/memory"
14
+ require "billygoat/task"
15
+ require "billygoat/brain"
16
+ require "billygoat/dependencies"
17
+ require "billygoat/documentation"
@@ -0,0 +1,41 @@
1
+ module Document
2
+
3
+ #
4
+ # Generate markdown documentation
5
+ #
6
+ def markdown(skill = nil, task = nil)
7
+
8
+ skills = skill ? [brain.find_skill(skill)] : brain.skills
9
+ puts "# Default Goat Skills and Tasks"
10
+ skills.each do |skill|
11
+ puts "* [#{skill}](#user-content-skill-#{skill.name.downcase})"
12
+ end
13
+ puts
14
+
15
+ skills.each do |skill|
16
+
17
+ puts "## Skill: #{skill}"
18
+
19
+ if skill.documentation?
20
+ puts skill.documentation(task, :markdown)
21
+ else
22
+ puts documentation(skill, task)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ private
30
+
31
+ def documentation(skill, task=nil)
32
+ tasks = task ? [skill.find_task(task)] : skill.tasks
33
+ tasks.map { |task| task_documentation(skill, task) }
34
+ end
35
+
36
+ def task_documentation(skill, task)
37
+ Billy::Documentation.new(method: task.method, mode: :markdown).inspect
38
+ end
39
+
40
+ end
41
+
data/lib/skills/git.rb ADDED
@@ -0,0 +1,46 @@
1
+ module Git
2
+
3
+ def self.extended(mod)
4
+ Dependencies.gem_require('git')
5
+ require 'logger'
6
+ end
7
+
8
+ #
9
+ # Delegate command
10
+ #
11
+ #
12
+ def delegate(arg)
13
+ case
14
+ when repository.respond_to?(arg)
15
+ puts repository.send(arg)
16
+ when repository.lib.respond_to?(arg)
17
+ puts repository.lib.send(arg)
18
+ end
19
+ end
20
+
21
+ #
22
+ # Documentation
23
+ #
24
+ def documentation(skill, task=nil, mode=nil)
25
+
26
+ base_skill = Billy::Skill.new(name: 'Git::Base')
27
+ lib_skill = Billy::Skill.new(name: 'Git::Lib')
28
+ all_tasks = base_skill.tasks + base_skill.tasks
29
+ tasks = task ? [base_skill.find_task(task) || lib_skill.find_task(task)] : all_tasks
30
+ tasks.map do |task|
31
+ Billy::Documentation.new(
32
+ method: task.method,
33
+ owner: skill.name.downcase,
34
+ mode: mode
35
+ ).inspect
36
+ end
37
+
38
+ end
39
+
40
+ private
41
+
42
+ def repository(path = '../chef')
43
+ Git.open(path, :log => Logger.new(StringIO.new))
44
+ end
45
+
46
+ end
@@ -0,0 +1,40 @@
1
+ module Help
2
+
3
+ #
4
+ # Show all documentation
5
+ # Show the documentation for a skill
6
+ # Show the documentation for a skill and task
7
+ #
8
+ def explain(skill = nil, task = nil)
9
+
10
+ skills = skill ? [brain.find_skill(skill)] : brain.skills
11
+ skills.each do |skill|
12
+
13
+ puts "#"*80
14
+ puts "## Skill: #{skill}"
15
+ puts "##"
16
+ puts
17
+
18
+ if skill.documentation?
19
+ puts skill.documentation(task)
20
+ else
21
+ puts documentation(skill, task)
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
28
+ private
29
+
30
+ def documentation(skill, task=nil)
31
+ tasks = task ? [skill.find_task(task)] : skill.tasks
32
+ tasks.map { |task| task_documentation(skill, task) }
33
+ end
34
+
35
+ def task_documentation(skill, task)
36
+ Billy::Documentation.new(method: task.method).inspect
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,59 @@
1
+ module Learn
2
+
3
+ #
4
+ # Learn a new task described in a local file
5
+ #
6
+ def file(path)
7
+ self.filepath = filepath
8
+ puts "Learning the skill from file #{@filepath}"
9
+
10
+ assert_file_exists
11
+ create_stash
12
+ stash_file
13
+
14
+ slate = Module.new
15
+ slate.module_eval(File.read(internal_location))
16
+ skill_name = slate.constants.first.to_s
17
+ skill = Billy::Skill.new(
18
+ name: skill_name,
19
+ internal_location: internal_location
20
+ )
21
+ brain.skill_set.skills << skill
22
+ brain.update_knowledge
23
+ brain.save_knowledge
24
+ end
25
+
26
+ #
27
+ # Learn a set of new tasks described in a local directory
28
+ #
29
+ def directory(path)
30
+ Dir.glob("#{path}/*.rb").each do |path|
31
+ file(path)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ attr_accessor :filepath
38
+
39
+ def filename
40
+ filepath[/(?<=\/)[^\/]*?$/]
41
+ end
42
+
43
+ def internal_location
44
+ "#{brain.skills_path}#{filename}"
45
+ end
46
+
47
+ def assert_file_exists
48
+ fail "Naaa, cannot find that file" unless File.exist?(filepath)
49
+ end
50
+
51
+ def create_stash
52
+ FileUtils.mkdir_p(brain.skills_path)
53
+ end
54
+
55
+ def stash_file
56
+ FileUtils.cp(filepath, internal_location)
57
+ end
58
+
59
+ end
@@ -0,0 +1,27 @@
1
+ module Show
2
+
3
+ #
4
+ # Show all goat settings
5
+ #
6
+ def settings
7
+ puts brain.settings.to_yaml
8
+ end
9
+
10
+ #
11
+ # Show a given goat setting
12
+ #
13
+ def setting(name)
14
+ puts brain.settings[name.to_sym].to_yaml
15
+ end
16
+
17
+ #
18
+ # Show the credentials for a particular service
19
+ #
20
+ def credentials(service = nil)
21
+ credentials = brain.credentials
22
+ credentials = credentials[service.to_sym] if service
23
+ puts credentials.to_yaml
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,25 @@
1
+ module Update
2
+
3
+ #
4
+ # Update a given goat setting
5
+ #
6
+ def setting(name, value)
7
+ brain.settings[name.to_sym] = value
8
+ brain.save_settings
9
+ puts brain.settings[name.to_sym].to_yaml
10
+ end
11
+
12
+ #
13
+ # Update the credentials for a particular service
14
+ #
15
+ def credentials(service, *args)
16
+ args.each do |pair|
17
+ key, value = pair.split('=')
18
+ brain.credentials[service.to_sym][key.to_sym] = value
19
+ end
20
+ brain.save_credentials
21
+ puts brain.credentials[service.to_sym].to_yaml
22
+ end
23
+
24
+ end
25
+
data/spec/goat_spec.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ module Billy
4
+
5
+ describe Goat do
6
+
7
+ it "has a brain" do
8
+ expect(subject).to respond_to :brain
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'billygoat'
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: billygoat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ platform: ruby
6
+ authors:
7
+ - Derrick Parkhurst
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 3.1.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 3.1.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: git
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ description: Goat do this for me
70
+ email:
71
+ - derrick.parkhurst@gmail.com
72
+ executables:
73
+ - goat
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - LICENSE.txt
78
+ - README.md
79
+ - Rakefile
80
+ - bin/goat
81
+ - lib/billygoat.rb
82
+ - lib/billygoat/brain.rb
83
+ - lib/billygoat/config.rb
84
+ - lib/billygoat/credentials.rb
85
+ - lib/billygoat/dependencies.rb
86
+ - lib/billygoat/disk.rb
87
+ - lib/billygoat/documentation.rb
88
+ - lib/billygoat/goat.rb
89
+ - lib/billygoat/knowledge.rb
90
+ - lib/billygoat/memory.rb
91
+ - lib/billygoat/settings.rb
92
+ - lib/billygoat/skill.rb
93
+ - lib/billygoat/skills.rb
94
+ - lib/billygoat/task.rb
95
+ - lib/billygoat/version.rb
96
+ - lib/skills/document.rb
97
+ - lib/skills/git.rb
98
+ - lib/skills/help.rb
99
+ - lib/skills/learn.rb
100
+ - lib/skills/show.rb
101
+ - lib/skills/update.rb
102
+ - spec/goat_spec.rb
103
+ - spec/spec_helper.rb
104
+ homepage: https://github.com/thirtysixthspan/billygoat
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.4.5
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Goat do this for me
128
+ test_files: []