coffer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []