owlet 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/README.md +17 -0
- data/Rakefile +9 -0
- data/bin/owlet +6 -0
- data/lib/owlet/cli.rb +38 -0
- data/lib/owlet/package.rb +35 -0
- data/lib/owlet/signer.rb +104 -0
- data/lib/owlet/version.rb +3 -0
- data/lib/owlet.rb +6 -0
- data/owlet.gemspec +28 -0
- data/spec/fixtures/first.p12 +0 -0
- data/spec/fixtures/fixture.alulaextension/init.rb +25 -0
- data/spec/fixtures/fixture.alulatheme/init.rb +8 -0
- data/spec/fixtures/fixture.alulatheme/javascripts/application.js.coffeescript +1 -0
- data/spec/fixtures/fixture.alulatheme/stylesheets/application.css.scss +5 -0
- data/spec/fixtures/pleco.p12 +0 -0
- data/spec/owlet/cli_spec.rb +0 -0
- data/spec/owlet/package_spec.rb +25 -0
- data/spec/owlet/signer_spec.rb +91 -0
- data/spec/spec_helper.rb +12 -0
- metadata +145 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
guard 'rspec', :version => 2, :cli => "--color --format documentation" do
|
2
|
+
watch(%r{^spec/.+_spec\.rb$})
|
3
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
4
|
+
watch(%r{^lib/(.+)/(.+)\.rb$}) { |m| "spec/#{m[1]}/#{m[2]}_spec.rb" }
|
5
|
+
watch('spec/spec_helper.rb') { "spec" }
|
6
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Owlet
|
2
|
+
|
3
|
+
Owlet is a package system for Alula extensions and themes. Using custom packages for extensions
|
4
|
+
gives benefits of easier distribution, downloading and management. Using single file packages
|
5
|
+
it is easy to upload required extensions and themes directly to the server from your computer.
|
6
|
+
|
7
|
+
In addition, all Owlets are digitally signed to make sure that package is not altered in any ways.
|
8
|
+
|
9
|
+
## Technical
|
10
|
+
|
11
|
+
Basically Owlets are simple ZIP files which as `_Signature` file as addition.
|
12
|
+
Signature file is simple YAML file, which contains signatures in base64 encoded
|
13
|
+
for all files that are in package, as well public certificate that was used
|
14
|
+
in signing process.
|
15
|
+
|
16
|
+
Owlets can be signed more than once, every additional signing round adds more signatures and
|
17
|
+
public key. While verifying packages, all signatures must match to public keys.
|
data/Rakefile
ADDED
data/bin/owlet
ADDED
data/lib/owlet/cli.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'owlet'
|
3
|
+
|
4
|
+
module Owlet
|
5
|
+
class CLI < Thor
|
6
|
+
# Signing operations
|
7
|
+
desc "sign PACKAGE", "Signs Owlet package with supplied key."
|
8
|
+
method_option :key, :required => true, :description => "Private and public key to be used for signing. Must be in PKCS12 format."
|
9
|
+
def sign(package)
|
10
|
+
Owlet::Signer.sign_package(package, options[:key])
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "verify PACKAGE", "Verifies Alula extension or theme"
|
14
|
+
def verify(package)
|
15
|
+
begin
|
16
|
+
Owlet::Signer.verify_package(package)
|
17
|
+
puts "Verify OK."
|
18
|
+
rescue
|
19
|
+
puts "Verify FAILED."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Packaking operations
|
24
|
+
desc "package DIRECTORY", "Create owlet package from given directory."
|
25
|
+
method_option :key
|
26
|
+
def package(dir)
|
27
|
+
pkg = Owlet::Package.create_from_dir(dir)
|
28
|
+
if (options[:key] and pkg)
|
29
|
+
Owlet::Signer.sign_package(pkg, options[:key])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "extract PACKAGE [DIR]", "Extracts contents of given package, optionally to given directory"
|
34
|
+
def extract(package, dir = ".")
|
35
|
+
Owlet::Package.extract(package, dir)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'zip/zip'
|
2
|
+
|
3
|
+
module Owlet
|
4
|
+
class Package
|
5
|
+
|
6
|
+
def self.create(args = {})
|
7
|
+
source = args[:source]
|
8
|
+
|
9
|
+
# Validate source
|
10
|
+
unless File.directory?(source)
|
11
|
+
raise "Invalid source directory."
|
12
|
+
end
|
13
|
+
|
14
|
+
ext = File.extname(source)
|
15
|
+
dest_ext = case ext[1..-1]
|
16
|
+
when "alulaextension"
|
17
|
+
"alulaextz"
|
18
|
+
when "alulatheme"
|
19
|
+
"alulathmz"
|
20
|
+
else
|
21
|
+
raise "Unknown owlet type."
|
22
|
+
end
|
23
|
+
destination = args[:destination] || File.join(File.dirname(source), "#{File.basename(source, ext)}.#{dest_ext}")
|
24
|
+
|
25
|
+
Zip::ZipFile.open(destination, Zip::ZipFile::CREATE) do |zip|
|
26
|
+
Dir.glob("#{source}/**/*").each do |entry|
|
27
|
+
zip.add(entry.gsub("#{source}/", ''), entry)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# All done
|
32
|
+
return destination
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/owlet/signer.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Owlet
|
5
|
+
class Signer
|
6
|
+
# Sign arbitary data using private_key
|
7
|
+
# Return Base 64 (RFC 4648) encoded signature
|
8
|
+
def self.sign(data, private_key)
|
9
|
+
Base64.encode64(private_key.sign(OpenSSL::Digest::SHA256.new, data)).gsub(/\n/, '')
|
10
|
+
end
|
11
|
+
|
12
|
+
# Verify arbitary data against given signature and public key.
|
13
|
+
# Signature must be Base64 encoded, RFC 4648 compliat.
|
14
|
+
def self.verify(data, signature, public_key)
|
15
|
+
public_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature).gsub(/\n/, ''), data)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.list_certificates(package)
|
19
|
+
# Check that package exists.
|
20
|
+
raise "Cannot file package #{package}" unless File.exists?(package)
|
21
|
+
|
22
|
+
sig_data = Zip::ZipFile.open(package) do |zip|
|
23
|
+
entry = zip.find_entry("_Signature")
|
24
|
+
unless entry.nil?
|
25
|
+
YAML.load(entry.get_input_stream.read)
|
26
|
+
else
|
27
|
+
{:certificates => []}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
sig_data[:certificates]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Signs given package with PKCS12 file
|
35
|
+
# p12 is either OpenSSL::PKCS!@ or file
|
36
|
+
def self.sign_package(package, p12)
|
37
|
+
# Get private key
|
38
|
+
unless p12.kind_of? OpenSSL::PKCS12
|
39
|
+
p12 = OpenSSL::PKCS12.new(File.read(p12))
|
40
|
+
end
|
41
|
+
|
42
|
+
raise "Cannot find package #{package}" unless File.exists?(package)
|
43
|
+
|
44
|
+
# Initialize signature data
|
45
|
+
sig_data = { :signatures => {}, :certificates => []}
|
46
|
+
|
47
|
+
# Open and sign files
|
48
|
+
Zip::ZipFile.open(package) do |zip|
|
49
|
+
sig_meta = zip.find_entry("_Signature")
|
50
|
+
unless sig_meta.nil?
|
51
|
+
sig_data = YAML.load(sig_meta.get_input_stream.read)
|
52
|
+
end
|
53
|
+
|
54
|
+
zip.each do |entry|
|
55
|
+
data = entry.get_input_stream.read
|
56
|
+
next if data.nil?
|
57
|
+
|
58
|
+
sig_data[:signatures][entry.name] ||= []
|
59
|
+
sig_data[:signatures][entry.name].push sign(data, p12.key)
|
60
|
+
end
|
61
|
+
|
62
|
+
sig_data[:certificates].push p12.certificate.to_pem
|
63
|
+
|
64
|
+
zip.get_output_stream("_Signature") do |io|
|
65
|
+
io.puts sig_data.to_yaml
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
true
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.verify_package(package)
|
73
|
+
raise "Cannot find package #{package}" unless File.exists?(package)
|
74
|
+
|
75
|
+
Zip::ZipFile.open(package) do |zip|
|
76
|
+
entry = zip.find_entry("_Signature")
|
77
|
+
raise "Package not signed." if entry.nil?
|
78
|
+
|
79
|
+
sig_data = YAML.load(entry.get_input_stream.read)
|
80
|
+
sig_data[:certificates].map! { |c| OpenSSL::X509::Certificate.new(c) }
|
81
|
+
|
82
|
+
zip.each do |entry|
|
83
|
+
next if entry.name == "_Signature"
|
84
|
+
|
85
|
+
# Check for all certificates
|
86
|
+
sig_data[:certificates].each_index do |i|
|
87
|
+
data = entry.get_input_stream.read
|
88
|
+
next if data.nil?
|
89
|
+
|
90
|
+
if sig_data[:signatures][entry.name].nil? or sig_data[:signatures][entry.name][i].nil?
|
91
|
+
raise "Cannot find signature for #{entry.name}"
|
92
|
+
end
|
93
|
+
|
94
|
+
unless verify(data, sig_data[:signatures][entry.name][i], sig_data[:certificates][i].public_key)
|
95
|
+
raise "Signature for #{entry.name} for certicate #{sig_data[:certificates][i].subject} failed."
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
return true
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/owlet.rb
ADDED
data/owlet.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "owlet/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "owlet"
|
7
|
+
s.version = Owlet::VERSION
|
8
|
+
s.authors = ["Mikko Kokkonen"]
|
9
|
+
s.email = ["mikko@mikian.com"]
|
10
|
+
s.homepage = "http://alula.in/owlet"
|
11
|
+
s.summary = %q{Owlet is a packaging system for distributing extensions and themes for Alula Engine}
|
12
|
+
s.description = %q{Use Owlet library to create and alter and gather information about owlets.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "owlet"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'thor'
|
22
|
+
s.add_dependency 'rubyzip'
|
23
|
+
|
24
|
+
s.add_development_dependency 'rake'
|
25
|
+
s.add_development_dependency 'rspec'
|
26
|
+
s.add_development_dependency 'guard-rspec'
|
27
|
+
s.add_development_dependency 'ci_reporter'
|
28
|
+
end
|
Binary file
|
@@ -0,0 +1,25 @@
|
|
1
|
+
extension "GoSquared"
|
2
|
+
|
3
|
+
description "GoSquared - real-time web analytics"
|
4
|
+
|
5
|
+
configuration do
|
6
|
+
desc "Site Token for your site"
|
7
|
+
option :token, :type => String
|
8
|
+
end
|
9
|
+
|
10
|
+
analytics :position => :body_bottom, do |c|
|
11
|
+
<<<-EOD
|
12
|
+
<script type="text/javascript">
|
13
|
+
var GoSquared={};
|
14
|
+
GoSquared.acct = "#{c.token}";
|
15
|
+
(function(w){
|
16
|
+
function gs(){
|
17
|
+
w._gstc_lt=+(new Date); var d=document;
|
18
|
+
var g = d.createElement("script"); g.type = "text/javascript"; g.async = true; g.src = "//d1l6p2sc9645hc.cloudfront.net/tracker.js";
|
19
|
+
var s = d.getElementsByTagName("script")[0]; s.parentNode.insertBefore(g, s);
|
20
|
+
}
|
21
|
+
w.addEventListener?w.addEventListener("load",gs,false):w.attachEvent("onload",gs);
|
22
|
+
})(window);
|
23
|
+
</script>
|
24
|
+
EOD
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
alert("Hello World!")
|
Binary file
|
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Owlet::Package do
|
4
|
+
let(:fixture_path) { fixture_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "fixtures")) }
|
5
|
+
|
6
|
+
before(:all) do
|
7
|
+
%w{fixture.alulaextz fixture.alulathmz}.each do |fixture|
|
8
|
+
File.unlink(File.join(fixture_path, fixture)) if File.exists?(File.join(fixture_path, fixture))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should raise error for invalid source path" do
|
13
|
+
lambda { Owlet::Package.create(:source => File.join(fixture_path, "missing_path")) }.should raise_error("Invalid source directory.")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should create a package from extension" do
|
17
|
+
pkg = Owlet::Package.create(:source => File.join(fixture_path, "fixture.alulaextension"))
|
18
|
+
pkg.should eq(File.join(fixture_path, "fixture.alulaextz"))
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should create package from theme" do
|
22
|
+
pkg = Owlet::Package.create(:source => File.join(fixture_path, "fixture.alulatheme"))
|
23
|
+
pkg.should eq(File.join(fixture_path, "fixture.alulathmz"))
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Owlet::Signer do
|
4
|
+
let(:fixture_path) { fixture_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "fixtures")) }
|
5
|
+
|
6
|
+
context "Helper Methods" do
|
7
|
+
let(:first_p12) { OpenSSL::PKCS12.new(File.read(File.join(fixture_path, "first.p12"))) }
|
8
|
+
let(:pleco_p12) { OpenSSL::PKCS12.new(File.read(File.join(fixture_path, "pleco.p12"))) }
|
9
|
+
let(:first_signature) { "lu2zFctrv7ssmcudjTVNoj9xS47GpMsYBxF8tQVhXnpOBXIM/7TuY+ZpHkxUqzgWssJdrUqLpC6t9OoUyLbUOU2HI4aNdmwOHv3XmpuIazmELEz/aCbwuCnwIAw6YtQiF14GQhUqR2A/6LE9ZB3+bKBDuxSMRY9WbRHELjoeXyg=" }
|
10
|
+
|
11
|
+
it "should sign data" do
|
12
|
+
# Load private key
|
13
|
+
data = "aaaa/bbbb/cccc"
|
14
|
+
signature = Owlet::Signer.sign(data, first_p12.key)
|
15
|
+
|
16
|
+
signature.should == first_signature
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should verify data" do
|
20
|
+
data = "aaaa/bbbb/cccc"
|
21
|
+
|
22
|
+
Owlet::Signer.verify(data, first_signature, first_p12.certificate.public_key).should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not verify invalid data" do
|
26
|
+
data = "aaaa/bbbb/cccc/dddd"
|
27
|
+
|
28
|
+
Owlet::Signer.verify(data, first_signature, first_p12.certificate.public_key).should be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not verify with wrong public key" do
|
32
|
+
data = "aaaa/bbbb/cccc"
|
33
|
+
|
34
|
+
Owlet::Signer.verify(data, first_signature, pleco_p12.certificate.public_key).should be_false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "Package" do
|
39
|
+
let(:first_p12) { OpenSSL::PKCS12.new(File.read(File.join(fixture_path, "first.p12"))) }
|
40
|
+
let(:pleco_p12) { OpenSSL::PKCS12.new(File.read(File.join(fixture_path, "pleco.p12"))) }
|
41
|
+
|
42
|
+
before(:each) do
|
43
|
+
# Create package
|
44
|
+
File.unlink(File.join(fixture_path, "fixture.alulaextz")) if File.exists?(File.join(fixture_path, "fixture.alulaextz"))
|
45
|
+
@pkg = Owlet::Package.create(:source => File.join(fixture_path, "fixture.alulaextension"))
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should have no certificates" do
|
49
|
+
signatures = Owlet::Signer.list_certificates(@pkg)
|
50
|
+
signatures.should be_empty
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be signed succesfully" do
|
54
|
+
Owlet::Signer.sign_package(@pkg, first_p12).should be_true
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have one certificate" do
|
58
|
+
Owlet::Signer.sign_package(@pkg, first_p12).should be_true
|
59
|
+
signatures = Owlet::Signer.list_certificates(@pkg)
|
60
|
+
signatures[0].should_not be_nil
|
61
|
+
cert = OpenSSL::X509::Certificate.new(signatures[0])
|
62
|
+
cert.subject.to_s.should == "/O=Owl Forestry/CN=Alula Extension"
|
63
|
+
signatures[1].should be_nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should verify signed package" do
|
67
|
+
Owlet::Signer.sign_package(@pkg, first_p12).should be_true
|
68
|
+
Owlet::Signer.verify_package(@pkg).should be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should signed twice" do
|
72
|
+
Owlet::Signer.sign_package(@pkg, first_p12).should be_true
|
73
|
+
Owlet::Signer.sign_package(@pkg, pleco_p12).should be_true
|
74
|
+
signatures = Owlet::Signer.list_certificates(@pkg)
|
75
|
+
signatures[1].should_not be_nil
|
76
|
+
cert = OpenSSL::X509::Certificate.new(signatures[1])
|
77
|
+
cert.subject.to_s.should == "/O=Owl Forestry/CN=Alula Pleco - Extension"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should fail with modified package" do
|
81
|
+
Owlet::Signer.sign_package(@pkg, first_p12).should be_true
|
82
|
+
Zip::ZipFile.open(@pkg) do |zip|
|
83
|
+
zip.get_output_stream("init.rb") do |io|
|
84
|
+
io.puts "# Fail this thanks."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
lambda { Owlet::Signer.verify_package(@pkg)}.should raise_error "Signature for init.rb for certicate /O=Owl Forestry/CN=Alula Extension failed."
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'owlet'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: owlet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mikko Kokkonen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: &70162863022180 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70162863022180
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rubyzip
|
27
|
+
requirement: &70162863021740 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70162863021740
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70162863021240 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70162863021240
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70162863020600 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70162863020600
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: guard-rspec
|
60
|
+
requirement: &70162863019940 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70162863019940
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: ci_reporter
|
71
|
+
requirement: &70162863019520 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70162863019520
|
80
|
+
description: Use Owlet library to create and alter and gather information about owlets.
|
81
|
+
email:
|
82
|
+
- mikko@mikian.com
|
83
|
+
executables:
|
84
|
+
- owlet
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files: []
|
87
|
+
files:
|
88
|
+
- .gitignore
|
89
|
+
- Gemfile
|
90
|
+
- Guardfile
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- bin/owlet
|
94
|
+
- lib/owlet.rb
|
95
|
+
- lib/owlet/cli.rb
|
96
|
+
- lib/owlet/package.rb
|
97
|
+
- lib/owlet/signer.rb
|
98
|
+
- lib/owlet/version.rb
|
99
|
+
- owlet.gemspec
|
100
|
+
- spec/fixtures/first.p12
|
101
|
+
- spec/fixtures/fixture.alulaextension/init.rb
|
102
|
+
- spec/fixtures/fixture.alulatheme/init.rb
|
103
|
+
- spec/fixtures/fixture.alulatheme/javascripts/application.js.coffeescript
|
104
|
+
- spec/fixtures/fixture.alulatheme/stylesheets/application.css.scss
|
105
|
+
- spec/fixtures/pleco.p12
|
106
|
+
- spec/owlet/cli_spec.rb
|
107
|
+
- spec/owlet/package_spec.rb
|
108
|
+
- spec/owlet/signer_spec.rb
|
109
|
+
- spec/spec_helper.rb
|
110
|
+
homepage: http://alula.in/owlet
|
111
|
+
licenses: []
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options: []
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project: owlet
|
130
|
+
rubygems_version: 1.8.6
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: Owlet is a packaging system for distributing extensions and themes for Alula
|
134
|
+
Engine
|
135
|
+
test_files:
|
136
|
+
- spec/fixtures/first.p12
|
137
|
+
- spec/fixtures/fixture.alulaextension/init.rb
|
138
|
+
- spec/fixtures/fixture.alulatheme/init.rb
|
139
|
+
- spec/fixtures/fixture.alulatheme/javascripts/application.js.coffeescript
|
140
|
+
- spec/fixtures/fixture.alulatheme/stylesheets/application.css.scss
|
141
|
+
- spec/fixtures/pleco.p12
|
142
|
+
- spec/owlet/cli_spec.rb
|
143
|
+
- spec/owlet/package_spec.rb
|
144
|
+
- spec/owlet/signer_spec.rb
|
145
|
+
- spec/spec_helper.rb
|