nutella_framework 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +5 -0
- data/Gemfile +17 -0
- data/LICENSE +20 -0
- data/README.md +11 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/bin/nutella +5 -0
- data/lib/cli/nutella_cli.rb +44 -0
- data/lib/config/config.rb +72 -0
- data/lib/config/project.rb +53 -0
- data/lib/config/runlist.rb +91 -0
- data/lib/core/command.rb +12 -0
- data/lib/core/commands/broker.rb +58 -0
- data/lib/core/commands/checkup.rb +91 -0
- data/lib/core/commands/help.rb +22 -0
- data/lib/core/commands/install.rb +153 -0
- data/lib/core/commands/new.rb +62 -0
- data/lib/core/commands/runs.rb +42 -0
- data/lib/core/commands/start.rb +101 -0
- data/lib/core/commands/stop.rb +62 -0
- data/lib/core/nutella_core.rb +32 -0
- data/lib/core/tmux.rb +33 -0
- data/lib/logging/nutella_logger-remote.rb +31 -0
- data/lib/logging/nutella_logger.rb +42 -0
- data/lib/logging/nutella_logging.rb +35 -0
- data/lib/nutella_framework.rb +17 -0
- data/test/config/test_config.rb +47 -0
- data/test/config/test_project.rb +32 -0
- data/test/config/test_runlist.rb +46 -0
- data/test/helper.rb +36 -0
- data/test/logging/test_logging.rb +16 -0
- data/test/test_nutella_framework.rb +30 -0
- metadata +239 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d3f88ae1dc5c42c292f394ef2a47a646da9b21f7
|
4
|
+
data.tar.gz: 3cd6d1bfa6c0ca8526f49fe1bd9a92484632fa66
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ca6269a2cc2b90c4c0b04a5a3119aa0d2abf4b9f0d1b462c589d0feb469ecb6ffd35cbfae91ed899922c373306818a2aca63636f4e7d562e602078993a015ded
|
7
|
+
data.tar.gz: fedcf4af33fb2298edcdec5e0eed539928eeb772ade17ef7f50b019361b1249b8134ade09e38017ab29b0972a66168aeaf32418678c9b4f1c1b48c387d18be5d
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'ansi', '~> 1.4', '>= 1.4.3'
|
4
|
+
gem 'semantic', '~> 1.3', '>=1.3'
|
5
|
+
gem 'logging', '~> 1.8', '>=1.8.2'
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem 'shoulda', '~> 3', '>= 3'
|
9
|
+
gem 'rdoc', '~> 4.0', '>= 4.0'
|
10
|
+
gem 'bundler', '~> 1.0', '>= 1.0'
|
11
|
+
gem 'jeweler', '~> 2.0.1', '>= 2.0.1'
|
12
|
+
gem 'simplecov', '~> 0', '>= 0'
|
13
|
+
end
|
14
|
+
|
15
|
+
group :test do
|
16
|
+
gem "rake"
|
17
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 by The Board of Trustees of the University of Illinois at Chicago
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
# Nutella [![Build Status](https://travis-ci.org/ltg-uic/nutella_framework.svg?branch=master)](https://travis-ci.org/ltg-uic/nutella_framework) [![Dependency Status](https://gemnasium.com/ltg-uic/nutella_framework.svg)](https://gemnasium.com/ltg-uic/nutella_framework) [![Code Climate](https://codeclimate.com/github/ltg-uic/nutella_framework/badges/gpa.svg)](https://codeclimate.com/github/ltg-uic/nutella_framework)
|
3
|
+
Nutella is a framework to build and run "Internet of Things"-like learning applications. It's still _very_ under development so keep an eye for new version and help fix the bugs you find by sumbmitting issues.
|
4
|
+
|
5
|
+
# Hello world
|
6
|
+
For a complete guide on how to use Nutella, please refer to [this wiki](https://github.com/ltg-uic/nutella/wiki).
|
7
|
+
You can install the most recent version of nutella with `gem install nutella_framework`. If all goes as expected you should be able to type `nutella` in your shell and get a welcome message.
|
8
|
+
|
9
|
+
|
10
|
+
# Building & contributing
|
11
|
+
Clone the repo, and simply type `rake` in the repo. This will run all the tests. If you want to do some fancier tasks simply type `rake -T` for a list of awesomess.
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
17
|
+
gem.name = "nutella_framework"
|
18
|
+
gem.homepage = "https://github.com/ltg-uic/nutella_framework"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{IoT-like learning applications framework}
|
21
|
+
gem.description = %Q{Nutella is a framework to build and run "Internet of Things"-like learning applications}
|
22
|
+
gem.email = "tebemis@gmail.com"
|
23
|
+
gem.authors = ["Alessandro Gnoli"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Code coverage detail"
|
36
|
+
task :simplecov do
|
37
|
+
ENV['COVERAGE'] = "true"
|
38
|
+
Rake::Task['test'].execute
|
39
|
+
end
|
40
|
+
|
41
|
+
task :default => :test
|
42
|
+
|
43
|
+
require 'rdoc/task'
|
44
|
+
Rake::RDocTask.new do |rdoc|
|
45
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "nutella_framework #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/bin/nutella
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Nutella
|
2
|
+
|
3
|
+
class NutellaCLI
|
4
|
+
|
5
|
+
NUTELLA_LOGO = " _ _ _
|
6
|
+
| | | | |
|
7
|
+
_ __ _ _| |_ ___| | | __ _
|
8
|
+
| _ \\| | | | __/ _ \\ | |/ _ |
|
9
|
+
| | | | |_| | || __/ | | (_| |
|
10
|
+
|_| |_|\\__,_|\\__\\___|_|_|\\__,_|
|
11
|
+
"
|
12
|
+
|
13
|
+
# Reads the parameters and executes commands
|
14
|
+
def self.run
|
15
|
+
# Read parameters
|
16
|
+
args = ARGV.dup
|
17
|
+
args.shift
|
18
|
+
# Check that the command is not empty, if so, print the prompt
|
19
|
+
command = ARGV.first
|
20
|
+
if command == nil
|
21
|
+
printPrompt
|
22
|
+
exit 0
|
23
|
+
end
|
24
|
+
# Prepend warning if nutella is not ready
|
25
|
+
if (Nutella.config["ready"].nil? && command!="checkup")
|
26
|
+
console.warn "Looks like this is a fresh installation of nutella. Please run `nutella checkup` to check all dependencies are installed."
|
27
|
+
end
|
28
|
+
Nutella.executeCommand command, args
|
29
|
+
exit 0
|
30
|
+
end
|
31
|
+
|
32
|
+
# Print Nutella logo
|
33
|
+
def self.printPrompt
|
34
|
+
console.info(NUTELLA_LOGO)
|
35
|
+
nutella_version = File.open(NUTELLA_HOME+"VERSION", "rb").read
|
36
|
+
console.info("Welcome to nutella version #{nutella_version}! For a complete lists of available commands type `nutella help`\n")
|
37
|
+
# Append warning if nutella is not ready
|
38
|
+
if (Nutella.config["ready"].nil?)
|
39
|
+
console.warn "Looks like this is a fresh installation of nutella. Please run `nutella checkup` to check all dependencies are installed."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# This handles the configuration files of Nutella
|
2
|
+
# It's basically a hash overload that stores into a file
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Nutella
|
6
|
+
|
7
|
+
class ConfigHash
|
8
|
+
|
9
|
+
def initialize(file)
|
10
|
+
@config_file=file
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def []=(key,val)
|
15
|
+
hash = loadConfig
|
16
|
+
hash[key]=val
|
17
|
+
storeConfig hash
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](key)
|
21
|
+
hash = loadConfig
|
22
|
+
hash[key]
|
23
|
+
end
|
24
|
+
|
25
|
+
def empty?
|
26
|
+
hash = loadConfig
|
27
|
+
hash.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def has_key?(key)
|
31
|
+
hash = loadConfig
|
32
|
+
hash.has_key? key
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
hash = loadConfig
|
37
|
+
hash.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_h
|
41
|
+
hash = loadConfig
|
42
|
+
hash
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def storeConfig(hash)
|
48
|
+
File.open(@config_file, "w+") do |f|
|
49
|
+
f.write(JSON.pretty_generate(hash))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def loadConfig
|
54
|
+
begin
|
55
|
+
return JSON.parse IO.read @config_file
|
56
|
+
rescue
|
57
|
+
# File doesn't exist... do nothing
|
58
|
+
Hash.new
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def removeConfigFile
|
63
|
+
File.delete(@config_file) if File.exist?(@config_file)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def Nutella.config
|
69
|
+
ConfigHash.new(File.dirname(__FILE__)+"/../../config.json")
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# handles current project files
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Nutella
|
7
|
+
|
8
|
+
class Project
|
9
|
+
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
# Check that the current directory is actually a nutella project
|
13
|
+
def exist?
|
14
|
+
@prj_dir = Dir.pwd
|
15
|
+
if File.exist?("#{@prj_dir}/conf/project.json")
|
16
|
+
conf = JSON.parse( IO.read("#{@prj_dir}/conf/project.json") )
|
17
|
+
if conf["nutella_version"].nil?
|
18
|
+
console.warn "The current directory is not a Nutella project"
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
else
|
22
|
+
console.warn "The current directory is not a Nutella project"
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
return true
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the value for an entry in the project configuration file
|
29
|
+
def config
|
30
|
+
@prj_dir = Dir.pwd
|
31
|
+
if File.exist? "#{@prj_dir}/conf/project.json"
|
32
|
+
return ConfigHash.new "#{@prj_dir}/conf/project.json"
|
33
|
+
else
|
34
|
+
console.error "The current directory is not a Nutella project! Impossible to get project configuration file"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns current project directory
|
39
|
+
def dir
|
40
|
+
Dir.pwd
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def Nutella.currentProject
|
47
|
+
Project.instance
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# This handles the list of running instances of Nutella
|
2
|
+
# The list is uniquely maintained inside a file
|
3
|
+
require 'singleton'
|
4
|
+
require 'json'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
module Nutella
|
8
|
+
|
9
|
+
class RunList
|
10
|
+
|
11
|
+
RUN_LIST_FILE=File.dirname(__FILE__)+"/../../runlist.json"
|
12
|
+
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
def add?(runid)
|
16
|
+
begin
|
17
|
+
result = JSON.parse(IO.read(RUN_LIST_FILE)).to_set.add? runid
|
18
|
+
rescue
|
19
|
+
# No file, create one
|
20
|
+
result = [runid].to_set
|
21
|
+
end
|
22
|
+
if result!=nil
|
23
|
+
File.open(RUN_LIST_FILE, "w+") do |f|
|
24
|
+
f.write(JSON.pretty_generate(result.to_a))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete?(runid)
|
31
|
+
begin
|
32
|
+
result = JSON.parse(IO.read(RUN_LIST_FILE)).to_set.delete? runid
|
33
|
+
rescue
|
34
|
+
removeRunListFile
|
35
|
+
result = nil # List is empty, so nil
|
36
|
+
end
|
37
|
+
if result!=nil
|
38
|
+
File.open(RUN_LIST_FILE, "w+") do |f|
|
39
|
+
f.write(JSON.pretty_generate(result.to_a))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def include?(runid)
|
46
|
+
begin
|
47
|
+
return JSON.parse(IO.read(RUN_LIST_FILE)).include? runid
|
48
|
+
rescue
|
49
|
+
false # There is no file so it doens't include runid
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def empty?
|
54
|
+
begin
|
55
|
+
return JSON.parse(IO.read(RUN_LIST_FILE)).empty?
|
56
|
+
rescue
|
57
|
+
true # There is no file so list is empty
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_a(projectName=nil)
|
62
|
+
begin
|
63
|
+
list = JSON.parse(IO.read(RUN_LIST_FILE))
|
64
|
+
# filter by project
|
65
|
+
if projectName == nil
|
66
|
+
return list
|
67
|
+
else
|
68
|
+
return list.select { |run| run.start_with?(projectName) }
|
69
|
+
end
|
70
|
+
rescue
|
71
|
+
Array.new # There is no file or something went wrong
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def removeRunListFile
|
78
|
+
File.delete(RUN_LIST_FILE) if File.exist?(RUN_LIST_FILE)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
def Nutella.runlist
|
85
|
+
RunList.instance
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
|
data/lib/core/command.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'core/command'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
module Nutella
|
5
|
+
class Broker < Command
|
6
|
+
@description = "Displays information about the current broker and allows us to change it"
|
7
|
+
|
8
|
+
def run(args=nil)
|
9
|
+
# If no argument then we jsut display info about the broker
|
10
|
+
if args==nil || args.empty?
|
11
|
+
getBrokerInfo
|
12
|
+
return
|
13
|
+
end
|
14
|
+
# If there are arguments we are doing manipulations
|
15
|
+
case args[0]
|
16
|
+
when "set"
|
17
|
+
changeBroker args[1]
|
18
|
+
# when "start"
|
19
|
+
# startBroker
|
20
|
+
# when "stop"
|
21
|
+
# stopBroker
|
22
|
+
else
|
23
|
+
console.warn "Unknown `nutella broker` option #{args[0]}. Try `nutell broker`, ` nutella broker set <broker> instead"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def getBrokerInfo
|
31
|
+
if Nutella.config["broker"].nil?
|
32
|
+
console.warn "No broker has been specified yet. Please, run `nutella broker set <broker>` to specify a broker."
|
33
|
+
else
|
34
|
+
console.info"Currently using broker: #{Nutella.config["broker"]}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def changeBroker(broker)
|
40
|
+
# Check that there are no runs hinging on this broker
|
41
|
+
if !Nutella.runlist.empty?
|
42
|
+
console.warn "You are currently running some projects on this broker. You can't change the broker while running."
|
43
|
+
return
|
44
|
+
end
|
45
|
+
# Change it
|
46
|
+
begin
|
47
|
+
IPSocket.getaddress(broker)
|
48
|
+
rescue
|
49
|
+
console.warn "Not a valid hostname for a broker"
|
50
|
+
end
|
51
|
+
Nutella.config["broker"] = broker
|
52
|
+
console.success "Now using broker: #{Nutella.config["broker"]}"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|