hive-toolbelt 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ce97020a71f474da3ea838dabe9322ebe05c64a
4
- data.tar.gz: cfc75e2f46cc2e51d4227956350fc1e523363c13
3
+ metadata.gz: 3c7c1c2827f31a895cf3c4a926b254c49f52923b
4
+ data.tar.gz: af63873df27ee4aaf8d3ba5675792a5aeecdbe0a
5
5
  SHA512:
6
- metadata.gz: f5ebf9ada6dac3dfee77702c991e16c0fe6776b738c5e2c6273880fc05fb2076f7f3875629a4e674463a3baa1013074b01a70fb37aaf1ab59c9bbfa902b25a3f
7
- data.tar.gz: d83f49af9ea48f2476461454a686f67ed807d7efe64c0161853123a5f047db6faa8072bf3ddc2da5284c48d0f34262d2c23842333d196795172f4743bee98399
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 # (TODO) cleans and creates a .hiveapp bundle from current working directory
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/<my-github-username>/hive-toolbelt/fork )
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
@@ -18,6 +18,8 @@
18
18
  cd ~/Library/Application\ Support/Hive/Applications/
19
19
  ln -s ~/{{project_name}}/ {{app_id}}
20
20
 
21
+ Go to Hive menu "Tools" > "Debugging Tools" > "Rebuild application list".
22
+
21
23
  ## Contributing
22
24
 
23
25
  1. Fork it
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Licensed under the MIT License.
5
5
  *
6
- * v1.0.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
- args['url'] = endpoint.replace(/http[s]?:\/\//gi, "http://www.corsproxy.com/");
119
- $.ajax(args)
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
+
@@ -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
@@ -1,4 +1,5 @@
1
1
  require_relative "toolbelt/version"
2
+ require_relative "toolbelt/package_error"
2
3
  require_relative "toolbelt/cli"
3
4
 
4
5
  module Hive
@@ -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", "scaffolding a Hive app"
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[:repo_url] = ask("Git Repository URL: ")
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
- f.puts(JSON.pretty_generate config.clone.merge(defaults))
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
@@ -0,0 +1,6 @@
1
+ module Hive
2
+ module Toolbelt
3
+ class PackageError < StandardError
4
+ end
5
+ end
6
+ end
@@ -1,5 +1,5 @@
1
1
  module Hive
2
2
  module Toolbelt
3
- VERSION = "0.0.2"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  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
- cli.create_manifest config
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.2
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-01-27 00:00:00.000000000 Z
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