hive-toolbelt 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/assets/README.md +2 -0
- data/assets/javascripts/hiveapp-api-mock.js +48 -3
- data/hive-toolbelt.gemspec +1 -0
- data/lib/hive/toolbelt.rb +1 -0
- data/lib/hive/toolbelt/cli.rb +61 -3
- data/lib/hive/toolbelt/package_error.rb +6 -0
- data/lib/hive/toolbelt/version.rb +1 -1
- data/spec/lib/hive/toolbelt_spec.rb +79 -13
- data/spec/spec_helper.rb +4 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c7c1c2827f31a895cf3c4a926b254c49f52923b
|
4
|
+
data.tar.gz: af63873df27ee4aaf8d3ba5675792a5aeecdbe0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f149d1426c56a68ad33b3e837f61c55dd8fc4c1415e5874e64a13c4dcef96ac7ea23eee01938644f01b24cb1432aa5b5a5d51dcc135bebab4e99365c7e95701
|
7
|
+
data.tar.gz: 6f49a4f13d008eef4cb57f2827a8e9e44c38b2d307fed2c06068d0a1c95277689017a5966df8aeb4eaf393acf2b034d44fdf90ccaca85bc429d9bf1a90f4124e
|
data/README.md
CHANGED
@@ -9,12 +9,12 @@ Command Line Interface for the Hive wallet
|
|
9
9
|
## Usage
|
10
10
|
|
11
11
|
$ hive init # walk you through scaffolding a Hive app
|
12
|
-
$ hive package #
|
12
|
+
$ hive package # creates a .hiveapp bundle from specified or current working directory (.hidden files ignored)
|
13
13
|
$ hive release # (TODO) bumps version, tags and pushes
|
14
14
|
|
15
15
|
## Contributing
|
16
16
|
|
17
|
-
1. Fork it ( http://github.com
|
17
|
+
1. Fork it ( http://github.com/hivewallet/hive-toolbelt/fork )
|
18
18
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
19
19
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
20
20
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/assets/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
*
|
4
4
|
* Licensed under the MIT License.
|
5
5
|
*
|
6
|
-
* v1.0.
|
6
|
+
* v1.0.1
|
7
7
|
*/
|
8
8
|
|
9
9
|
var bitcoin = bitcoin || mockBitcoin()
|
@@ -25,6 +25,50 @@ function mockBitcoin() {
|
|
25
25
|
var locale = navigator.language;
|
26
26
|
|
27
27
|
function async(fn) { setTimeout(fn, 0) }
|
28
|
+
function createCORSRequest(method, url) {
|
29
|
+
var xhr = new XMLHttpRequest();
|
30
|
+
if ("withCredentials" in xhr) {
|
31
|
+
xhr.open(method, url, true);
|
32
|
+
} else if (typeof XDomainRequest != "undefined") {
|
33
|
+
xhr = new XDomainRequest();
|
34
|
+
xhr.open(method, url);
|
35
|
+
} else {
|
36
|
+
throw new Error('CORS not supported');
|
37
|
+
}
|
38
|
+
return xhr;
|
39
|
+
}
|
40
|
+
|
41
|
+
function ajax(url, options) {
|
42
|
+
options = options || {}
|
43
|
+
options.type = options.type || "GET"
|
44
|
+
options.dataType = options.dataType || "json"
|
45
|
+
options.success = options.success || function(){}
|
46
|
+
options.failure = options.failure || function(){}
|
47
|
+
options.complete = options.complete || function(){}
|
48
|
+
|
49
|
+
var xhr = createCORSRequest(options.type, url)
|
50
|
+
xhr.responseType = options.dataType
|
51
|
+
|
52
|
+
xhr.onload = function(event) {
|
53
|
+
options.success(xhr.response, xhr.status)
|
54
|
+
};
|
55
|
+
|
56
|
+
xhr.onerror = function(event) {
|
57
|
+
options.error(xhr.response, xhr.status, xhr.statusText)
|
58
|
+
};
|
59
|
+
|
60
|
+
xhr.onloadend = function(event) {
|
61
|
+
options.complete(xhr.response, xhr.status, xhr.statusText)
|
62
|
+
};
|
63
|
+
|
64
|
+
var data = new FormData();
|
65
|
+
if(options.data) {
|
66
|
+
for(var key in options.data) {
|
67
|
+
data.append(key, options.data[key])
|
68
|
+
}
|
69
|
+
}
|
70
|
+
xhr.send(data);
|
71
|
+
}
|
28
72
|
|
29
73
|
return {
|
30
74
|
BTC_IN_SATOSHI: _BTC_IN_SATOSHI,
|
@@ -115,8 +159,8 @@ function mockBitcoin() {
|
|
115
159
|
},
|
116
160
|
|
117
161
|
makeRequest: function(endpoint, args){
|
118
|
-
|
119
|
-
|
162
|
+
var url = endpoint.replace(/http[s]?:\/\//gi, "http://www.corsproxy.com/");
|
163
|
+
ajax(url, args)
|
120
164
|
},
|
121
165
|
|
122
166
|
userStringForSatoshi: function(satoshiAmount) {
|
@@ -142,3 +186,4 @@ function mockBitcoin() {
|
|
142
186
|
};
|
143
187
|
}
|
144
188
|
|
189
|
+
|
data/hive-toolbelt.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "thor"
|
22
22
|
spec.add_dependency "active_support"
|
23
|
+
spec.add_dependency "rubyzip"
|
23
24
|
spec.add_development_dependency "bundler", "~> 1.5"
|
24
25
|
spec.add_development_dependency "rake"
|
25
26
|
spec.add_development_dependency "rspec"
|
data/lib/hive/toolbelt.rb
CHANGED
data/lib/hive/toolbelt/cli.rb
CHANGED
@@ -2,20 +2,23 @@ require "thor"
|
|
2
2
|
require "json"
|
3
3
|
require "active_support"
|
4
4
|
require "active_support/core_ext/string"
|
5
|
+
require "active_support/core_ext/hash"
|
6
|
+
require "zip"
|
5
7
|
|
6
8
|
I18n.enforce_available_locales = false
|
7
9
|
|
8
10
|
module Hive
|
9
11
|
module Toolbelt
|
10
12
|
class CLI < Thor
|
11
|
-
desc "init", "
|
13
|
+
desc "init", "scaffold a Hive app"
|
12
14
|
def init
|
13
15
|
config = {}
|
14
16
|
config[:name] = ask("App Name: ")
|
15
17
|
config[:description] = ask("Description: ")
|
16
18
|
config[:author] = ask("Author Name: ")
|
17
19
|
config[:contact] = ask("Author Contact: ")
|
18
|
-
config[:
|
20
|
+
config[:repoURL] = ask("Git Repository URL: ")
|
21
|
+
config[:accessedHosts] = ask("API hosts the app needs to talk to (separated by comma. e.g. api.github.com, www.bitstamp.net): ")
|
19
22
|
|
20
23
|
create_manifest(config)
|
21
24
|
copy_default_icon
|
@@ -23,6 +26,21 @@ module Hive
|
|
23
26
|
create_index_html config[:name]
|
24
27
|
create_readme config
|
25
28
|
create_license config[:author]
|
29
|
+
create_empty_folders
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "package [DIR_NAME]", "package a directory into a .hiveapp bundle. DIR_NAME defaults to current working directory if not specified."
|
33
|
+
def package dir_name='.'
|
34
|
+
directory = sanitize_dir_name dir_name
|
35
|
+
check_for_required_files directory
|
36
|
+
|
37
|
+
bundle_name = bundle_name_from_manifest(File.join directory, 'manifest.json')
|
38
|
+
FileUtils.rm(bundle_name) if File.exists? bundle_name
|
39
|
+
bundle_files bundle_name, directory
|
40
|
+
|
41
|
+
say "#{bundle_name} packaged successfully", :green
|
42
|
+
rescue PackageError => e
|
43
|
+
say e.message, :red
|
26
44
|
end
|
27
45
|
|
28
46
|
no_commands do
|
@@ -37,7 +55,8 @@ module Hive
|
|
37
55
|
}
|
38
56
|
|
39
57
|
File.open('manifest.json', 'w') do |f|
|
40
|
-
|
58
|
+
config[:accessedHosts] = config[:accessedHosts].split(',').map(&:strip)
|
59
|
+
f.puts(JSON.pretty_generate config.merge(defaults))
|
41
60
|
end
|
42
61
|
end
|
43
62
|
|
@@ -89,6 +108,45 @@ module Hive
|
|
89
108
|
safe_gsub_file license_filename, /{{year}}/, Time.now.year.to_s
|
90
109
|
safe_gsub_file license_filename, /{{author}}/, author
|
91
110
|
end
|
111
|
+
|
112
|
+
def create_empty_folders
|
113
|
+
%w(stylesheets images fonts).each do |dirname|
|
114
|
+
create_file File.join(dirname, '.gitignore')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def sanitize_dir_name dir_name
|
119
|
+
directory = File.expand_path dir_name
|
120
|
+
directory << File::SEPARATOR unless directory.ends_with?(File::SEPARATOR)
|
121
|
+
directory
|
122
|
+
end
|
123
|
+
|
124
|
+
def check_for_required_files sanitized_dir_name
|
125
|
+
%w(index.html manifest.json).each do |filename|
|
126
|
+
if Dir.glob(File.join sanitized_dir_name, filename).empty?
|
127
|
+
raise PackageError.new("#{filename} is required. But it's not found under #{sanitized_dir_name}")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def bundle_files bundle_name, directory
|
133
|
+
Zip::File.open(bundle_name, Zip::File::CREATE) do |zipfile|
|
134
|
+
Dir[File.join(directory, '**', '**')].each do |file|
|
135
|
+
zipfile.add(file.sub(directory, ''), file)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def bundle_name_from_manifest manifest
|
141
|
+
config = JSON.parse(File.read manifest).with_indifferent_access
|
142
|
+
required = config.slice :author, :name, :version
|
143
|
+
|
144
|
+
required.each do |k, v|
|
145
|
+
raise PackageError.new("Please provide a value for `#{k}` field in manifest.json") if v.blank?
|
146
|
+
end
|
147
|
+
|
148
|
+
required.values.join(' ').parameterize << '.hiveapp'
|
149
|
+
end
|
92
150
|
end
|
93
151
|
end
|
94
152
|
end
|
@@ -4,17 +4,21 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
module Hive::Toolbelt
|
6
6
|
describe CLI do
|
7
|
+
let(:cli) { described_class.new }
|
8
|
+
|
7
9
|
describe '#create_manifest' do
|
8
|
-
let(:cli) { described_class.new }
|
9
10
|
let(:filename) { 'manifest.json' }
|
10
11
|
|
11
|
-
it 'creates a manifest file' do
|
12
|
-
cli.create_manifest
|
13
|
-
expect(File.exists?(filename)).to be_true
|
14
|
-
end
|
15
|
-
|
16
12
|
def create_manifest_json config
|
17
|
-
|
13
|
+
default = {
|
14
|
+
name: "",
|
15
|
+
description: "",
|
16
|
+
author: "",
|
17
|
+
contact: "",
|
18
|
+
repoURL: "",
|
19
|
+
accessedHosts: ""
|
20
|
+
}
|
21
|
+
cli.create_manifest default.merge(config)
|
18
22
|
JSON.parse File.read(filename)
|
19
23
|
end
|
20
24
|
|
@@ -34,10 +38,27 @@ module Hive::Toolbelt
|
|
34
38
|
expect(manifest["icon"]).to eq("icon.png")
|
35
39
|
expect(manifest["id"]).to eq("wei_lu.foo_app")
|
36
40
|
end
|
41
|
+
|
42
|
+
describe 'accessedHosts' do
|
43
|
+
context 'when not specified' do
|
44
|
+
it 'has `[]` as value for accessedHosts' do
|
45
|
+
manifest = create_manifest_json({ accessedHosts: '' })
|
46
|
+
|
47
|
+
expect(manifest["accessedHosts"]).to eq([])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when specified' do
|
52
|
+
it 'populates accessedHosts with an array' do
|
53
|
+
manifest = create_manifest_json({ accessedHosts: 'api.github.com, www.bitstamp.net' })
|
54
|
+
|
55
|
+
expect(manifest["accessedHosts"]).to eq(['api.github.com', 'www.bitstamp.net'])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
37
59
|
end
|
38
60
|
|
39
61
|
describe '#copy_default_icon' do
|
40
|
-
let(:cli) { described_class.new }
|
41
62
|
let(:filename) { 'icon.png' }
|
42
63
|
|
43
64
|
it 'provides a default icon file' do
|
@@ -47,8 +68,6 @@ module Hive::Toolbelt
|
|
47
68
|
end
|
48
69
|
|
49
70
|
describe '#copy_api_mock' do
|
50
|
-
let(:cli) { described_class.new }
|
51
|
-
|
52
71
|
it 'provides a mock api for in-browser development' do
|
53
72
|
cli.copy_api_mock
|
54
73
|
expect(File.exists?(File.join('javascripts', 'hiveapp-api-mock.js'))).to be_true
|
@@ -56,7 +75,6 @@ module Hive::Toolbelt
|
|
56
75
|
end
|
57
76
|
|
58
77
|
describe '#create_index_html' do
|
59
|
-
let(:cli) { described_class.new }
|
60
78
|
let(:filename) { 'index.html' }
|
61
79
|
let(:index) do
|
62
80
|
cli.create_index_html 'Foo App'
|
@@ -78,7 +96,6 @@ module Hive::Toolbelt
|
|
78
96
|
end
|
79
97
|
|
80
98
|
describe '#create_readme' do
|
81
|
-
let(:cli) { described_class.new }
|
82
99
|
let(:filename) { 'README.md' }
|
83
100
|
let(:project_name) { 'toolbelt' }
|
84
101
|
let(:config) do
|
@@ -107,7 +124,6 @@ module Hive::Toolbelt
|
|
107
124
|
end
|
108
125
|
|
109
126
|
describe '#create_license' do
|
110
|
-
let(:cli) { described_class.new }
|
111
127
|
let(:filename) { 'LICENSE.txt' }
|
112
128
|
let(:author) { 'Wei Lu' }
|
113
129
|
let(:license) do
|
@@ -123,5 +139,55 @@ module Hive::Toolbelt
|
|
123
139
|
it { expect(license).to include(author) }
|
124
140
|
it { expect(license).to include(Time.now.year.to_s) }
|
125
141
|
end
|
142
|
+
|
143
|
+
describe '#create_empty_folders' do
|
144
|
+
%w(stylesheets images fonts).each do |dirname|
|
145
|
+
it "creates #{dirname} folder" do
|
146
|
+
cli.create_empty_folders
|
147
|
+
expect(File.exists?(File.join(dirname, '.gitignore'))).to be_true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '#pacakge' do
|
153
|
+
let(:filename) { 'wei-lu-my-app-1-0-1.hiveapp' }
|
154
|
+
|
155
|
+
context 'when any of the required files is missing' do
|
156
|
+
%w(index.html manifest.json).each do |filename|
|
157
|
+
it "prints error when #{filename} is not found" do
|
158
|
+
expect(cli).to receive(:say).with(anything, :red)
|
159
|
+
cli.package
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'when required files are found' do
|
165
|
+
before do
|
166
|
+
FileUtils.touch 'index.html'
|
167
|
+
File.open('manifest.json', 'w') do |f|
|
168
|
+
f.puts(JSON.pretty_generate name: 'My App', author: 'Wei Lu', version: '1.0.1')
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
it "produces the bundled file" do
|
173
|
+
cli.package
|
174
|
+
expect(File.exists?(filename)).to be_true
|
175
|
+
end
|
176
|
+
|
177
|
+
it "exclude the .git directory (and all hidden files)" do
|
178
|
+
cli.package
|
179
|
+
expect(Zip::File.new(filename).find_entry '.git/').to be_nil
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'when there already exists a packaged file' do
|
183
|
+
it "overwrites it without raising error" do
|
184
|
+
cli.package
|
185
|
+
expect {
|
186
|
+
cli.package
|
187
|
+
}.to_not raise_error
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
126
192
|
end
|
127
193
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,8 +8,11 @@ RSpec.configure do |config|
|
|
8
8
|
config.order = 'random'
|
9
9
|
|
10
10
|
# clean up generated files
|
11
|
-
generated_files = %w(manifest.json icon.png index.html README.md LICENSE.txt)
|
11
|
+
generated_files = %w(manifest.json icon.png index.html README.md LICENSE.txt wei-lu-my-app-1-0-1.hiveapp)
|
12
12
|
generated_files << File.join('javascripts', 'hiveapp-api-mock.js')
|
13
|
+
%w(stylesheets images fonts).each do |dirname|
|
14
|
+
generated_files << File.join(dirname, '.gitignore')
|
15
|
+
end
|
13
16
|
config.before do
|
14
17
|
generated_files.each do |filename|
|
15
18
|
FileUtils.mv(filename, "#{filename}.tmp") if File.exists?(filename)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hive-toolbelt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wei Lu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubyzip
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,6 +131,7 @@ files:
|
|
117
131
|
- hive-toolbelt.gemspec
|
118
132
|
- lib/hive/toolbelt.rb
|
119
133
|
- lib/hive/toolbelt/cli.rb
|
134
|
+
- lib/hive/toolbelt/package_error.rb
|
120
135
|
- lib/hive/toolbelt/version.rb
|
121
136
|
- spec/lib/hive/toolbelt_spec.rb
|
122
137
|
- spec/spec_helper.rb
|