hal9000 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +1 -0
- data/bin/hal +6 -0
- data/hal9000.gemspec +30 -0
- data/lib/hal9000.rb +16 -0
- data/lib/hal9000/action.rb +24 -0
- data/lib/hal9000/actionstore.rb +35 -0
- data/lib/hal9000/command.rb +94 -0
- data/lib/hal9000/manager.rb +58 -0
- data/lib/hal9000/version.rb +3 -0
- metadata +117 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 David Rodrigues
|
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,70 @@
|
|
1
|
+
# hal9000
|
2
|
+
|
3
|
+
hal maps your commands to an human readable form, you just need to think what you want to do and hal will do it for you with pleasure! It's like a domain for a not-easy-to-remember ip but for your commands.
|
4
|
+
|
5
|
+
## Motivation
|
6
|
+
|
7
|
+
Aliases are extremely helpful and simple but they are not always self descriptive and easy to remember. Hal is an helper for this, it helps manage your aliases, create, delete, keep them on a single location. Finally it maps your actions into your thoughts. Thoughts? What?
|
8
|
+
|
9
|
+
I give you an example. I'm currently using a remote server and the access is made directly by the ip address. I found that very boring and hard to remember.
|
10
|
+
|
11
|
+
Well, this was before hal. Now i can simply do:
|
12
|
+
|
13
|
+
hal connect to my remote server
|
14
|
+
|
15
|
+
Hal will recognize this and will map to my `ssh user@x.x.x.x` command. I found it helpful.
|
16
|
+
|
17
|
+
### Inspiration
|
18
|
+
|
19
|
+
I developed hal with some inspiring references in mind.
|
20
|
+
|
21
|
+
1. [HUBOT](http://hubot.github.com/) from Github.
|
22
|
+
2. [boom](http://zachholman.com/boom) from Zach Holman.
|
23
|
+
3. [HAL 9000](http://en.wikipedia.org/wiki/HAL_9000), the super computer from the `2001: A Space Odyssey` movie.
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
Install it via RubyGems:
|
28
|
+
|
29
|
+
$ gem install hal9000
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
example usage:
|
34
|
+
hal --list lists all actions
|
35
|
+
hal --create <thought> <action> create a new action
|
36
|
+
hal --delete <thought> delete an action
|
37
|
+
|
38
|
+
hal <thought> execute an action
|
39
|
+
|
40
|
+
hal --version show hal version
|
41
|
+
hal --help show this shiny help
|
42
|
+
|
43
|
+
## Examples
|
44
|
+
|
45
|
+
$ hal --create "say hello" "echo 'Hello'"
|
46
|
+
$ hal say hello
|
47
|
+
you - say hello
|
48
|
+
hal - right way sir! running: 'echo 'Hello''
|
49
|
+
Hello
|
50
|
+
|
51
|
+
$ hal --create "start jenkins" "java -jar /usr/local/opt/jenkins/libexec/jenkins.war"
|
52
|
+
$ hal start jenkins
|
53
|
+
(jenkins starts)
|
54
|
+
...
|
55
|
+
|
56
|
+
$ hal --create "copy my ssh key" "pbcopy < ~/.ssh/id_rsa.pub"
|
57
|
+
$ hal copy my ssh key
|
58
|
+
(key copied to clipboard)
|
59
|
+
|
60
|
+
## Portability
|
61
|
+
|
62
|
+
Hal uses a single JSON file to store all your thoughts and actions. This file is a pure JSON file and is available on your `$HOME` directory with the name `.hal`. Alternatively, it's possible to configure the location of this file using an enviroment variable with the name `HAL_FILE`.
|
63
|
+
|
64
|
+
## Contributing
|
65
|
+
|
66
|
+
Hal is currently in a very alpha version so any help is very welcome. Just fork it! :)
|
67
|
+
|
68
|
+
## Licence
|
69
|
+
|
70
|
+
[MIT License](http://en.wikipedia.org/wiki/MIT_License) (c) [David Rodrigues](mailto:david.ndh@gmail.com)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/hal
ADDED
data/hal9000.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hal9000/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hal9000"
|
8
|
+
spec.version = HAL9000::VERSION
|
9
|
+
|
10
|
+
spec.authors = ["David Rodrigues"]
|
11
|
+
spec.email = ["david.ndh@gmail.com"]
|
12
|
+
spec.homepage = "https://github.com/dmcrodrigues/hal9000"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.description = "hal uses your thoughts as an alias to your commands.
|
16
|
+
think of what you want to do and hal will run it for you."
|
17
|
+
spec.summary = "hal maps your commands to an human readable form, you
|
18
|
+
just need to think what you want to do and hal will do it for you with pleasure!
|
19
|
+
It's like a domain for a not-easy-to-remember ip but for your commands."
|
20
|
+
|
21
|
+
spec.files = `git ls-files`.split($/)
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_dependency "oj", "~> 2.0"
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
end
|
data/lib/hal9000.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module HAL9000
|
4
|
+
class Action
|
5
|
+
|
6
|
+
attr_accessor :thought
|
7
|
+
|
8
|
+
attr_accessor :action
|
9
|
+
|
10
|
+
def initialize(thought, action)
|
11
|
+
@thought = thought
|
12
|
+
@action = action
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(other)
|
16
|
+
@thought <=> other.thought
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"#{thought} => #{action}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end # class Action
|
24
|
+
end # module HAL9000
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module HAL9000
|
4
|
+
class ActionStore
|
5
|
+
|
6
|
+
attr_accessor :actions
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@actions = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_action(action)
|
13
|
+
unless find_action(action.thought)
|
14
|
+
actions << action
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_action(thought)
|
19
|
+
actions.find do |action|
|
20
|
+
action.thought.casecmp(thought) == 0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_action(thought)
|
25
|
+
actions.reject! { |action| action.thought == thought }
|
26
|
+
end
|
27
|
+
|
28
|
+
def list
|
29
|
+
actions.sort.each do |action|
|
30
|
+
puts action
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end # class ActionStore
|
35
|
+
end # module HAL9000
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module HAL9000
|
4
|
+
class Command
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def manager
|
8
|
+
HAL9000.manager
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute(args)
|
12
|
+
case args.first when '--help', 'help', '-h', '--usage', nil
|
13
|
+
help
|
14
|
+
when '--version'
|
15
|
+
version
|
16
|
+
when '--list'
|
17
|
+
list
|
18
|
+
when '--create'
|
19
|
+
thought, action = args[1], args[2]
|
20
|
+
return help unless thought && action
|
21
|
+
create(thought, action)
|
22
|
+
when '--delete'
|
23
|
+
thought = args[1]
|
24
|
+
return help unless thought
|
25
|
+
delete(thought)
|
26
|
+
else
|
27
|
+
thought = args.join(' ')
|
28
|
+
return help unless thought
|
29
|
+
execute_action(thought)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def list
|
34
|
+
puts "hal - here are the thoughts that we've shared."
|
35
|
+
puts "----------------------------------------------"
|
36
|
+
manager.list_actions
|
37
|
+
end
|
38
|
+
|
39
|
+
def create(thought, action)
|
40
|
+
if manager.create_action(thought, action)
|
41
|
+
puts "hal - done! i will keep this in mind for you."
|
42
|
+
else
|
43
|
+
puts "hal - clash of thoughts! you already have this thought."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def delete(thought)
|
48
|
+
if manager.delete_action(thought)
|
49
|
+
puts "hal - gone! keep me posted if you think on this again."
|
50
|
+
else
|
51
|
+
puts "hal - maybe you are confused, i don't have this thought."
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def execute_action(thought)
|
56
|
+
action_item = manager.find_action(thought)
|
57
|
+
unless action_item
|
58
|
+
puts "you - #{thought}"
|
59
|
+
puts "hal - i don't know what you mean. maybe this will help."
|
60
|
+
help
|
61
|
+
else
|
62
|
+
begin
|
63
|
+
puts "you - #{thought}"
|
64
|
+
puts "hal - right way sir! running: '#{action_item.action}'"
|
65
|
+
system(action_item.action)
|
66
|
+
rescue Exception => e
|
67
|
+
puts "hal - oops! i can't perform this action. here, maybe this will help."
|
68
|
+
puts e
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def help
|
74
|
+
help_text = <<-EOS
|
75
|
+
example usage:
|
76
|
+
hal --list lists all actions
|
77
|
+
hal --create <thought> <action> create a new action
|
78
|
+
hal --delete <thought> delete an action
|
79
|
+
|
80
|
+
hal <thought> execute an action
|
81
|
+
|
82
|
+
hal --version show hal version
|
83
|
+
hal --help show this shiny help
|
84
|
+
EOS
|
85
|
+
puts help_text.gsub(/^ {10}/, '')
|
86
|
+
end
|
87
|
+
|
88
|
+
def version
|
89
|
+
puts "hal - i'm currently running the version #{HAL9000::VERSION}"
|
90
|
+
end
|
91
|
+
|
92
|
+
end # class << self
|
93
|
+
end # class Command
|
94
|
+
end # module HAL9000
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module HAL9000
|
4
|
+
class Manager
|
5
|
+
|
6
|
+
HAL_FILE = "#{ENV['HOME']}/.hal"
|
7
|
+
|
8
|
+
attr_accessor :actionstore
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@actionstore = ActionStore.new
|
12
|
+
populate
|
13
|
+
end
|
14
|
+
|
15
|
+
def list_actions
|
16
|
+
actionstore.list
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_action(thought, action)
|
20
|
+
action = Action.new(thought, action)
|
21
|
+
return unless actionstore.add_action(action)
|
22
|
+
persist
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete_action(thought)
|
26
|
+
return unless actionstore.delete_action(thought)
|
27
|
+
persist
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_action(thought)
|
31
|
+
actionstore.find_action(thought)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Persistence ==============================================================
|
35
|
+
|
36
|
+
def hal_file
|
37
|
+
ENV['HAL_FILE'] || HAL_FILE
|
38
|
+
end
|
39
|
+
|
40
|
+
def populate
|
41
|
+
unless !File.exist?(hal_file)
|
42
|
+
storage = Oj.load(IO.read(hal_file), { :mode => :compat, :indent => 2 })
|
43
|
+
storage['actions'].each do |action|
|
44
|
+
actionstore.add_action(Action.new(action['thought'], action['action']))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def persist
|
50
|
+
File.open(hal_file, 'w') { |f| f.write(to_json) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_json
|
54
|
+
Oj.dump(actionstore, { :mode => :compat, :indent => 2 })
|
55
|
+
end
|
56
|
+
|
57
|
+
end # class Manager
|
58
|
+
end # module HAL9000
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hal9000
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Rodrigues
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: oj
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: ! "hal uses your thoughts as an alias to your commands. \n think of
|
63
|
+
what you want to do and hal will run it for you."
|
64
|
+
email:
|
65
|
+
- david.ndh@gmail.com
|
66
|
+
executables:
|
67
|
+
- hal
|
68
|
+
extensions: []
|
69
|
+
extra_rdoc_files: []
|
70
|
+
files:
|
71
|
+
- .gitignore
|
72
|
+
- Gemfile
|
73
|
+
- LICENSE.txt
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- bin/hal
|
77
|
+
- hal9000.gemspec
|
78
|
+
- lib/hal9000.rb
|
79
|
+
- lib/hal9000/action.rb
|
80
|
+
- lib/hal9000/actionstore.rb
|
81
|
+
- lib/hal9000/command.rb
|
82
|
+
- lib/hal9000/manager.rb
|
83
|
+
- lib/hal9000/version.rb
|
84
|
+
homepage: https://github.com/dmcrodrigues/hal9000
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
hash: 1227463475522443602
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
hash: 1227463475522443602
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 1.8.25
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: hal maps your commands to an human readable form, you just need to think
|
115
|
+
what you want to do and hal will do it for you with pleasure! It's like a domain
|
116
|
+
for a not-easy-to-remember ip but for your commands.
|
117
|
+
test_files: []
|