coffer 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ca2c5d3113286b6f76e188960d077dd9728d231
4
+ data.tar.gz: 7fb1cbda0e8b230158d2805a23b6439e3a724e57
5
+ SHA512:
6
+ metadata.gz: 0ec5974676159236f78a7f49ab098feb28efca2c9f10d3664b2572bdbd10a2326b9793b9dae1fb74a63ee6481b1640d69fdfd754710826038a4893e73646df47
7
+ data.tar.gz: df82ed776d4cf9b768fd422e9e73c8847d73de93c2c07a31a2d37fbc3ea95eabc775ebf31f99a6424ca9468befbbfeca27c5d125aa4e4e9ace81e2ba783d52fe
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in coffer.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Spike Grobstein
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,43 @@
1
+ # Coffer
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'coffer'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install coffer
18
+
19
+ ## Requirements
20
+
21
+ On ubuntu:
22
+
23
+ * git
24
+ * build-essential
25
+ * libboost-all-dev
26
+ * libssl-dev
27
+ * libdb++-dev
28
+ * libminiupnpc-dev
29
+ * autoconf
30
+
31
+ Probably ruby 2.x
32
+
33
+ ## Usage
34
+
35
+ TODO: Write usage instructions here
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/Vagrantfile ADDED
@@ -0,0 +1,122 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ VAGRANTFILE_API_VERSION = "2"
6
+
7
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+ # All Vagrant configuration is done here. The most common configuration
9
+ # options are documented and commented below. For a complete reference,
10
+ # please see the online documentation at vagrantup.com.
11
+
12
+ # Every Vagrant virtual environment requires a box to build off of.
13
+ config.vm.box = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-i386-vagrant-disk1.box"
14
+
15
+ # Disable automatic box update checking. If you disable this, then
16
+ # boxes will only be checked for updates when the user runs
17
+ # `vagrant box outdated`. This is not recommended.
18
+ # config.vm.box_check_update = false
19
+
20
+ # Create a forwarded port mapping which allows access to a specific port
21
+ # within the machine from a port on the host machine. In the example below,
22
+ # accessing "localhost:8080" will access port 80 on the guest machine.
23
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
24
+
25
+ # Create a private network, which allows host-only access to the machine
26
+ # using a specific IP.
27
+ # config.vm.network "private_network", ip: "192.168.33.10"
28
+
29
+ # Create a public network, which generally matched to bridged network.
30
+ # Bridged networks make the machine appear as another physical device on
31
+ # your network.
32
+ # config.vm.network "public_network"
33
+
34
+ # If true, then any SSH connections made will enable agent forwarding.
35
+ # Default value: false
36
+ # config.ssh.forward_agent = true
37
+
38
+ # Share an additional folder to the guest VM. The first argument is
39
+ # the path on the host to the actual folder. The second argument is
40
+ # the path on the guest to mount the folder. And the optional third
41
+ # argument is a set of non-required options.
42
+ config.vm.synced_folder ".", "/home/vagrant/coffer"
43
+
44
+ # Provider-specific configuration so you can fine-tune various
45
+ # backing providers for Vagrant. These expose provider-specific options.
46
+ # Example for VirtualBox:
47
+ #
48
+ config.vm.provider "virtualbox" do |vb|
49
+ # Don't boot with headless mode
50
+ # vb.gui = true
51
+
52
+ # Use VBoxManage to customize the VM. For example to change memory:
53
+ vb.customize ["modifyvm", :id, "--memory", "2048"]
54
+ end
55
+ #
56
+ # View the documentation for the provider you're using for more
57
+ # information on available options.
58
+
59
+ # Enable provisioning with CFEngine. CFEngine Community packages are
60
+ # automatically installed. For example, configure the host as a
61
+ # policy server and optionally a policy file to run:
62
+ #
63
+ # config.vm.provision "cfengine" do |cf|
64
+ # cf.am_policy_hub = true
65
+ # # cf.run_file = "motd.cf"
66
+ # end
67
+ #
68
+ # You can also configure and bootstrap a client to an existing
69
+ # policy server:
70
+ #
71
+ # config.vm.provision "cfengine" do |cf|
72
+ # cf.policy_server_address = "10.0.2.15"
73
+ # end
74
+
75
+ # Enable provisioning with Puppet stand alone. Puppet manifests
76
+ # are contained in a directory path relative to this Vagrantfile.
77
+ # You will need to create the manifests directory and a manifest in
78
+ # the file default.pp in the manifests_path directory.
79
+ #
80
+ # config.vm.provision "puppet" do |puppet|
81
+ # puppet.manifests_path = "manifests"
82
+ # puppet.manifest_file = "site.pp"
83
+ # end
84
+
85
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
86
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
87
+ # some recipes and/or roles.
88
+ #
89
+ # config.vm.provision "chef_solo" do |chef|
90
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
91
+ # chef.roles_path = "../my-recipes/roles"
92
+ # chef.data_bags_path = "../my-recipes/data_bags"
93
+ # chef.add_recipe "mysql"
94
+ # chef.add_role "web"
95
+ #
96
+ # # You may also specify custom JSON attributes:
97
+ # chef.json = { mysql_password: "foo" }
98
+ # end
99
+
100
+ # Enable provisioning with chef server, specifying the chef server URL,
101
+ # and the path to the validation key (relative to this Vagrantfile).
102
+ #
103
+ # The Opscode Platform uses HTTPS. Substitute your organization for
104
+ # ORGNAME in the URL and validation key.
105
+ #
106
+ # If you have your own Chef Server, use the appropriate URL, which may be
107
+ # HTTP instead of HTTPS depending on your configuration. Also change the
108
+ # validation key to validation.pem.
109
+ #
110
+ # config.vm.provision "chef_client" do |chef|
111
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
112
+ # chef.validation_key_path = "ORGNAME-validator.pem"
113
+ # end
114
+ #
115
+ # If you're using the Opscode platform, your validator client is
116
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
117
+ #
118
+ # If you have your own Chef Server, the default validation client name is
119
+ # chef-validator, unless you changed the configuration.
120
+ #
121
+ # chef.validation_client_name = "ORGNAME-validator"
122
+ end
data/bin/coffer ADDED
@@ -0,0 +1,6 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'coffer/cli'
4
+
5
+ Coffer::CLI.start(ARGV)
6
+
data/coffer.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'coffer/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "coffer"
8
+ spec.version = Coffer::VERSION
9
+ spec.authors = ["Spike Grobstein"]
10
+ spec.email = ["me@spike.cx"]
11
+ spec.description = %q{Cryptocurrency wallet manager}
12
+ spec.summary = %q{Cryptocurrency wallet manager -- like homebrew, but for your wallets. Linux-only right now.}
13
+ spec.homepage = "https://github.com/spikegrobstein/coffer"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "pry"
24
+
25
+ spec.add_dependency 'activesupport'
26
+ spec.add_dependency 'git'
27
+ spec.add_dependency 'thor'
28
+ end
@@ -0,0 +1,18 @@
1
+ module Coffer
2
+ module Coin
3
+ class Auroracoin < Coffer::Definition
4
+
5
+ git_repo 'https://github.com/baldurodinsson/auroracoin-project.git'
6
+
7
+ home_page 'http://auroracoin.org'
8
+
9
+ symbol :AUR
10
+
11
+ wallet_executable 'auroracoind'
12
+ directory 'auroracoin'
13
+ config_file 'auroracoin.conf'
14
+
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,12 @@
1
+ module Coffer
2
+ module Coin
3
+ class Bottlecaps < Coffer::Definition
4
+ git_repo 'https://github.com/bottlecaps-foundation/bottlecaps.git'
5
+ home_page 'https://cryptocointalk.com/forum/242-bottlecaps-cap/'
6
+ symbol :CAP
7
+ wallet_executable 'bottlecapsd'
8
+ directory 'BottleCaps'
9
+ config_file 'BottleCaps.conf'
10
+ end
11
+ end
12
+ end
data/coins/dogecoin.rb ADDED
@@ -0,0 +1,22 @@
1
+ # May have issues
2
+
3
+ module Coffer
4
+ module Coin
5
+ class Dogecoin < Coffer::Definition
6
+ git_repo 'https://github.com/dogecoin/dogecoin.git'
7
+ home_page 'http://dogecoin.com'
8
+ symbol :DOGE
9
+ wallet_executable 'dogecoind'
10
+ directory 'dogecoin'
11
+ config_file 'dogecoin.conf'
12
+
13
+ build <<-BUILD
14
+ ./autogen.sh
15
+ ./configure --with-incompatible-bdb
16
+ make
17
+ BUILD
18
+
19
+ build_dir '/'
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module Coffer
2
+ module Coin
3
+ class Feathercoin < Coffer::Definition
4
+
5
+ git_repo 'https://github.com/FeatherCoin/Feathercoin.git'
6
+
7
+ home_page 'https://www.feathercoin.com'
8
+
9
+ symbol :FTC
10
+
11
+ wallet_executable 'feathercoind'
12
+
13
+ directory 'feathercoin'
14
+
15
+ config_file 'feathercoin.conf'
16
+
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,18 @@
1
+ module Coffer
2
+ module Coin
3
+ class Fedoracoin < Coffer::Definition
4
+
5
+ home_page 'http://fedoraco.in'
6
+ git_repo 'https://github.com/fedoracoin/fedoracoin.git'
7
+
8
+ symbol :TIPS
9
+
10
+ wallet_executable 'fedoracoind'
11
+ directory 'fedoracoin'
12
+ config_file 'fedoracoin.conf'
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+
data/coins/litecoin.rb ADDED
@@ -0,0 +1,14 @@
1
+ module Coffer
2
+ module Coin
3
+ class Litecoin < Coffer::Definition
4
+ git_branch 'master-0.8'
5
+ git_repo 'https://github.com/litecoin-project/litecoin.git'
6
+ home_page 'https://litecoin.org'
7
+ symbol :LTC
8
+ wallet_executable 'litecoind'
9
+ directory 'litecoin'
10
+ config_file 'litecoin.conf'
11
+ end
12
+ end
13
+ end
14
+
data/coins/megacoin.rb ADDED
@@ -0,0 +1,12 @@
1
+ module Coffer
2
+ module Coin
3
+ class Megacoin < Coffer::Definition
4
+ git_repo 'https://github.com/megacoin/megacoin.git'
5
+ home_page 'http://megacoin.co.nz'
6
+ symbol :MEC
7
+ wallet_executable 'megacoind'
8
+ directory 'Megacoin'
9
+ config_file 'megacoin.conf'
10
+ end
11
+ end
12
+ end
data/coins/mincoin.rb ADDED
@@ -0,0 +1,12 @@
1
+ module Coffer
2
+ module Coin
3
+ class Mincoin < Coffer::Definition
4
+ git_repo 'https://github.com/mincoin/mincoin.git'
5
+ home_page 'https://mincoin.io'
6
+ symbol :MNC
7
+ wallet_executable 'mincoind'
8
+ directory 'Mincoin'
9
+ config_file 'mincoind.conf'
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Coffer
2
+ module Coin
3
+ class Worldcoin < Coffer::Definition
4
+ git_branch 'v0.8.6.2'
5
+ git_repo 'https://github.com/worldcoinproject/worldcoin-v0.8.git'
6
+ home_page 'http://www.worldcoinalliance.net'
7
+ symbol :WDC
8
+ wallet_executable 'worldcoind'
9
+ directory 'Worldcoin'
10
+ config_file 'worldcoin.conf'
11
+ end
12
+ end
13
+ end
data/lib/coffer/cli.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'thor'
2
+ require 'coffer'
3
+ require 'pry'
4
+
5
+ module Coffer
6
+ class CLI < Thor
7
+ desc "list", "List all coins"
8
+ def list
9
+ Coffer::Registry.instance.coins.each do |coin|
10
+ puts "%-20s (%s)" % [ coin.name, coin.symbol ]
11
+ end
12
+ end
13
+
14
+ desc "search", "Search for coins"
15
+ def search
16
+ warn "not implemented"
17
+ end
18
+
19
+ desc "install <coin>", "Install the given coin."
20
+ def install(coin)
21
+ coin = Coffer::Registry.instance.find( coin )
22
+
23
+ if coin.nil?
24
+ warn "Unable to find a coin with a name or symbol of #{ coin }"
25
+ end
26
+
27
+ warn "installing coin: #{ coin.name } (#{coin.symbol})"
28
+
29
+ installer = Coffer::Installer.new(coin)
30
+ if installer.install
31
+ puts "success!"
32
+ else
33
+ puts "Failed to install coin..."
34
+ end
35
+ end
36
+
37
+ desc "start <coin>", "Start the given coin."
38
+ def start(coin)
39
+ coin = Coffer::Registry.instance.find(coin)
40
+
41
+ if coin.nil?
42
+ warn "Unable to find a coin with a name or symbol of #{ coin }"
43
+ end
44
+
45
+ coin.start
46
+ end
47
+
48
+ desc "stop <coin>", "Stop the given coin."
49
+ def stop(coin)
50
+ coin = Coffer::Registry.instance.find(coin)
51
+
52
+ if coin.nil?
53
+ warn "Unable to find a coin with a name or symbol of #{ coin }"
54
+ end
55
+
56
+ coin.stop
57
+ end
58
+
59
+ def self.handle_no_command_error(command, has_namespace=$thor_runner)
60
+ coin = Coffer::Registry.instance.find(command)
61
+
62
+ if coin.nil?
63
+ # warn "Unable to find a coin with a name or symbol of #{ coin }"
64
+ super
65
+ return
66
+ end
67
+
68
+ ARGV.shift
69
+ coin.call_rpc( *ARGV )
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,19 @@
1
+ module Coffer
2
+ class Configuration
3
+
4
+ attr_accessor :fields
5
+
6
+ def initialize
7
+ @fields = []
8
+ end
9
+
10
+ def add( key, value )
11
+ @fields << [ key, value ]
12
+ end
13
+
14
+ def to_config
15
+ @fields.map { |f| f.join('=') }.join("\n")
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,137 @@
1
+ require 'fileutils'
2
+ require 'set'
3
+
4
+ require 'coffer/configuration'
5
+
6
+ module Coffer
7
+ class Definition
8
+
9
+ attr_accessor :config
10
+
11
+ def initialize
12
+ validate!
13
+ end
14
+
15
+ def validate!
16
+ raise "Git repo required!" if @@git_repo.nil?
17
+ raise "wallet_executable required!" if @@wallet_executable.nil?
18
+ raise "directory required!" if @@directory.nil?
19
+ end
20
+
21
+ def requirements
22
+ @@requirements
23
+ end
24
+
25
+ def name
26
+ self.class.name
27
+ end
28
+
29
+ class << self
30
+
31
+ def name
32
+ name = ActiveSupport::Inflector.demodulize(self)
33
+ name = ActiveSupport::Inflector.underscore(name)
34
+ end
35
+
36
+ def config_field( key, value )
37
+ @config_fields ||= []
38
+ @config_fields << [key,value]
39
+ end
40
+
41
+ def executable_path
42
+ "/opt/coffer/bin/#{ wallet_executable }"
43
+ end
44
+
45
+ def installed?
46
+ File.exists? executable_path
47
+ end
48
+
49
+ # TODO: parse output and return
50
+ def call_rpc(*args)
51
+ pid = Process.spawn(
52
+ executable_path, *args
53
+ )
54
+
55
+ Process.wait pid
56
+ end
57
+
58
+ # TODO: figure out if launch was successful
59
+ def start
60
+ pid = Process.spawn(
61
+ executable_path, "-daemon",
62
+ :out => '/dev/null', :err => '/dev/null')
63
+
64
+ # Detach the spawned process
65
+ Process.detach pid
66
+ end
67
+
68
+ def stop
69
+ pid = Process.spawn(
70
+ executable_path, "stop",
71
+ :out => '/dev/null', :err => '/dev/null')
72
+
73
+ # Detach the spawned process
74
+ Process.detach pid
75
+ end
76
+
77
+ def build_config
78
+ return @config if @config
79
+
80
+ @config = Configuration.new
81
+
82
+ @config.add :rpcuser, 'cofferuser'
83
+ @config.add :rpcpassword, 'cofferpass'
84
+ @config.add :server, '1'
85
+ @config.add :rpcallowip, '127.0.0.1'
86
+ @config.add :listen, '1'
87
+ @config.add :port, '4444' #Coffer::Registry.port
88
+
89
+ # now custom fields
90
+ if @config_fields
91
+ fields.each do |f|
92
+ @config.add f[0], f[1]
93
+ end
94
+ end
95
+
96
+ @config
97
+ end
98
+
99
+ def attr_field( name, default=nil )
100
+ @defaults ||= {}
101
+ @defaults[name] = default
102
+
103
+ @attr_fields ||= []
104
+ @attr_fields << name
105
+
106
+ instance_variable_set "@#{name}", default
107
+
108
+ define_singleton_method(name) do |v=nil|
109
+ unless v.nil?
110
+ instance_variable_set "@#{name}", v
111
+ end
112
+
113
+ basecoin = self.ancestors[1]
114
+
115
+ instance_variable_get("@#{name}") || basecoin.instance_variable_get(:'@defaults')[name]
116
+ end
117
+
118
+ define_method(name) do
119
+ self.class.instance_variable_get "@#{name}"
120
+ end
121
+
122
+ end
123
+ end
124
+
125
+ attr_field :git_repo
126
+ attr_field :git_branch, 'master'
127
+ attr_field :wallet_executable
128
+ attr_field :symbol
129
+ attr_field :home_page
130
+ attr_field :directory
131
+ attr_field :config_file
132
+ attr_field :build
133
+ attr_field :build_dir, 'src'
134
+
135
+ end
136
+
137
+ end
@@ -0,0 +1,186 @@
1
+ require 'git'
2
+
3
+ module Coffer
4
+ class Installer
5
+
6
+ CACHE_DIR = '/opt/coffer/cache'
7
+ BIN_DIR = '/opt/coffer/bin'
8
+
9
+ attr_reader :coin
10
+
11
+ def initialize( coin )
12
+ @coin = coin
13
+ end
14
+
15
+ def install
16
+ mkdir CACHE_DIR, 0755
17
+ mkdir BIN_DIR, 0755
18
+
19
+ update_repo
20
+ # preconfigure
21
+
22
+ Dir.chdir( File.join( repo_path, @coin.build_dir) ) do
23
+ mkdir 'obj', 0755
24
+ make
25
+
26
+ check_results
27
+ end
28
+
29
+ copy_built_executable
30
+ create_directories
31
+ create_config
32
+ end
33
+
34
+ # ensure that this git repo is running the latest
35
+ # version and is cloned and all that
36
+ def update_repo
37
+ [ clone, pull ].count { |i| i } > 0
38
+ end
39
+
40
+ # clone a repo to the correct directory
41
+ # if the directory already exists and is a git repo
42
+ # then do nothing.
43
+ def clone
44
+ return false if File.directory?( repo_path )
45
+
46
+ warn "Cloning repo... #{repo_path}"
47
+
48
+ g = Git.clone( coin.git_repo, File.basename(repo_path), :path => File.dirname(repo_path) )
49
+
50
+ g.checkout @coin.git_branch
51
+
52
+ true
53
+ end
54
+
55
+ # pull the latest changes and ensure we have the correct
56
+ # ref checked out.
57
+ def pull
58
+ raise "Not a git repository! (#{ repo_path })" unless File.directory?( repo_path )
59
+
60
+ warn "Updating repo... #{repo_path}"
61
+
62
+ g = Git.open( repo_path, :logger => Logger.new(STDOUT) )
63
+
64
+ # store the current SHA1
65
+ old_sha = g.object('HEAD').sha
66
+
67
+ # ensure the remote is configured as expected
68
+ if g.remote.url != coin.git_repo
69
+ g.remove_remote 'origin'
70
+ g.add_remote 'origin', coin.git_repo, :fetch => true
71
+ end
72
+
73
+ # make sure the tree is clean
74
+ g.reset_hard
75
+ g.clean :force => true, :d => true
76
+
77
+ # fetch data from remote, checkout the right branch and merge into local branch
78
+ g.checkout @coin.git_branch
79
+ g.pull('origin', @coin.git_branch)
80
+
81
+ # check if there are any changes.
82
+ old_sha != g.object('HEAD').sha
83
+ end
84
+
85
+ def copy_built_executable
86
+ FileUtils.cp built_executable_path, installed_executable_path
87
+ end
88
+
89
+ def create_directories
90
+ mkdir wallet_home_directory, 0700
91
+ end
92
+
93
+ def wallet_home_directory
94
+ File.expand_path("~/.#{ @coin.directory }")
95
+ end
96
+
97
+ def create_config
98
+ if File.exists?( config_path )
99
+ puts "Not creating config. (#{ config_path })"
100
+ return
101
+ end
102
+
103
+ File.open( config_path , 'w' ) do |f|
104
+ f.write @coin.build_config.to_config
105
+ end
106
+
107
+ FileUtils.chmod 0600, config_path
108
+ end
109
+
110
+ def config_path
111
+ File.join( wallet_home_directory, @coin.config_file )
112
+ end
113
+
114
+ def start
115
+ `#{ installed_executable_path } -daemon`
116
+ end
117
+
118
+ def check_results
119
+ raise "Build failed. No executable!" unless built_executable_valid?
120
+ end
121
+
122
+ def make
123
+ if @coin.build.nil?
124
+ cmd = "make -f '#{ makefile_name }'"
125
+
126
+ puts `#{cmd}`
127
+
128
+ retval = $?
129
+ if retval != 0
130
+ warn "ERROR from command: (#{ cmd }): #{ retval }"
131
+ end
132
+ else
133
+ @coin.build.split("\n").each do |cmd|
134
+ cmd = cmd.strip
135
+ puts "EXEC> #{ cmd }"
136
+ puts `#{cmd}`
137
+
138
+ retval = $?
139
+ if retval != 0
140
+ warn "ERROR from command (#{cmd}): #{ retval }"
141
+ return false
142
+ end
143
+ end
144
+ end
145
+
146
+ true
147
+ end
148
+
149
+ def makefile_name
150
+ sys = `uname`.chomp.downcase
151
+
152
+ if sys == 'darwin'
153
+ 'makefile.osx'
154
+ elsif sys == 'linux'
155
+ 'makefile.unix'
156
+ end
157
+ end
158
+
159
+ def mkdir( path, mode=0700 )
160
+ begin
161
+ FileUtils.mkdir_p path, :mode => mode
162
+ rescue Errno::EEXIST
163
+ #pass
164
+ end
165
+ end
166
+
167
+ def repo_path
168
+ File.join CACHE_DIR, @coin.name
169
+ end
170
+
171
+ def installed_executable_path
172
+ File.join BIN_DIR, @coin.wallet_executable
173
+ end
174
+
175
+ def built_executable_path
176
+ File.join repo_path, 'src', @coin.wallet_executable
177
+ end
178
+
179
+ def built_executable_valid?
180
+ File.exists?( built_executable_path ) \
181
+ && File.executable?( built_executable_path )
182
+ end
183
+
184
+ end
185
+ end
186
+
@@ -0,0 +1,60 @@
1
+ require 'fileutils'
2
+ require 'active_support' # FIXME: this takes about half a second to load
3
+ require 'singleton'
4
+
5
+ module Coffer
6
+ class Registry
7
+ include Singleton
8
+
9
+ BASE_DIR = '/opt/coffer'
10
+ BIN_DIR = File.join(BASE_DIR, 'bin')
11
+ DATA_FILE = File.join(BASE_DIR, 'coins.dat')
12
+
13
+ attr_reader :coins
14
+
15
+ def initialize
16
+ make_directories
17
+ @coins = []
18
+ load_coins File.join(File.dirname(__FILE__), '../../coins')
19
+ end
20
+
21
+ def make_directories
22
+ FileUtils.mkdir_p BIN_DIR
23
+ end
24
+
25
+ def load_coins(directory)
26
+ Dir["#{ directory }/*.rb"].each do |d|
27
+ require d
28
+
29
+ self.load File.basename(d, '.rb')
30
+ end
31
+ end
32
+
33
+ def self.load(coin)
34
+ instance.load coin
35
+ end
36
+
37
+ def load( coin )
38
+ if coin.is_a?(Symbol) || coin.is_a?(String)
39
+ coin = ActiveSupport::Inflector.camelize( coin, true )
40
+ coin = Coffer::Coin.const_get( coin )
41
+ elsif coin.is_a?(Coffer::Definition)
42
+ # pass
43
+ else
44
+ raise "Wrong type! (#{ coin.class.to_s })"
45
+ end
46
+
47
+ @coins << coin
48
+
49
+ # warn "Loaded coin: #{ coin.inspect } #{ coin.symbol }"
50
+ end
51
+
52
+ def find( coin )
53
+ coin = coin.downcase
54
+ @coins.find do |c|
55
+ c.name.downcase == coin || c.symbol.to_s.downcase == coin
56
+ end
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ module Coffer
2
+ VERSION = "0.0.1"
3
+ end
data/lib/coffer.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "coffer/version"
2
+ require 'coffer/registry'
3
+ require 'coffer/definition'
4
+ require 'coffer/installer'
5
+
6
+ module Coffer
7
+ # Your code goes here...
8
+ end
data/newcoin.sh ADDED
@@ -0,0 +1,28 @@
1
+ #! /bin/bash -
2
+
3
+ echo "Creating new coin..."
4
+
5
+ read -p "Name: " COIN_NAME
6
+ read -p "Git repo: " GIT_REPO
7
+ read -p "Homepage: " HOME_PAGE
8
+ read -p "Symbol: " SYMBOL
9
+ read -p "Wallet executable: " WALLET_EXECUTABLE
10
+ read -p "Directory: " DIRECTORY
11
+ read -p "Config file: " CONFIG_FILE
12
+
13
+ FILENAME=$( echo $COIN_NAME | tr '[:upper:]' '[:lower:]' )
14
+
15
+ cat > coins/${FILENAME}.rb <<EOF
16
+ module Coffer
17
+ module Coin
18
+ class ${COIN_NAME} < Coffer::Definition
19
+ git_repo '${GIT_REPO}'
20
+ home_page '${HOME_PAGE}'
21
+ symbol :${SYMBOL}
22
+ wallet_executable '${WALLET_EXECUTABLE}'
23
+ directory '${COIN_NAME}'
24
+ config_file '${CONFIG_FILE}'
25
+ end
26
+ end
27
+ end
28
+ EOF
data/run_test.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'bundler/setup'
2
+ require 'coffer/registry'
3
+ require 'coffer/installer'
4
+ require 'coffer/definition'
5
+
6
+ require 'pry'
7
+ require 'fileutils'
8
+
9
+ # cleanup
10
+ # FileUtils.rm_rf '/tmp/coffer'
11
+
12
+ Coffer::Registry.instance
13
+
14
+ c = Coffer::Coin::Feathercoin.new
15
+
16
+ installer = Coffer::Installer.new( c )
17
+ installer.install
18
+
19
+ puts "Built: #{ c.executable_path }"
20
+
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: coffer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Spike Grobstein
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: git
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Cryptocurrency wallet manager
98
+ email:
99
+ - me@spike.cx
100
+ executables:
101
+ - coffer
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - .gitignore
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - Vagrantfile
111
+ - bin/coffer
112
+ - coffer.gemspec
113
+ - coins/auroracoin.rb
114
+ - coins/bottlecaps.rb
115
+ - coins/dogecoin.rb
116
+ - coins/feathercoin.rb
117
+ - coins/fedoracoin.rb
118
+ - coins/litecoin.rb
119
+ - coins/megacoin.rb
120
+ - coins/mincoin.rb
121
+ - coins/worldcoin.rb
122
+ - lib/coffer.rb
123
+ - lib/coffer/cli.rb
124
+ - lib/coffer/configuration.rb
125
+ - lib/coffer/definition.rb
126
+ - lib/coffer/installer.rb
127
+ - lib/coffer/registry.rb
128
+ - lib/coffer/version.rb
129
+ - newcoin.sh
130
+ - run_test.rb
131
+ homepage: https://github.com/spikegrobstein/coffer
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.0.14
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Cryptocurrency wallet manager -- like homebrew, but for your wallets. Linux-only
155
+ right now.
156
+ test_files: []