golden 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/exe/golden +76 -0
  3. data/lib/crucible.rb +133 -0
  4. data/lib/golden.rb +31 -0
  5. metadata +118 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cb7d6213bb1ec1308135221959c65ebe9e60d3451867ad900b7b59772ce30108
4
+ data.tar.gz: 826478ec45eff91699476be02d45b1319683c227faa60aa39c8a0ca68ecfc1f2
5
+ SHA512:
6
+ metadata.gz: b158e3292725f4bd05f8e55691aebff8110966e4b7806954d012caeae8a0366fd5a12c2ea8b9faefbf892c1047e59d5195bee7f41dc244606743976074157153
7
+ data.tar.gz: 5568c2e5e7c084e2e996bf3a2c70780fff6e4cd72278174dd5106217f89631f98db185d5a7d55fdf64d50583a444a2b6af32bc3bcf2aa5b540c2312c60fcb0c7
data/exe/golden ADDED
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env ruby
2
+ require "thor"
3
+ require 'open3'
4
+ require 'json'
5
+ require_relative("../lib/crucible.rb")
6
+ module Golden
7
+ class Cli < Thor
8
+ desc "build [fileName]", "build library named [fileName]"
9
+ method_option :verbose, :aliases => "-v", :desc => "Build with verbose logging"
10
+ def build(fileName)
11
+ self.load(options)
12
+ @crucible.build(fileName,Dir.pwd)
13
+ self.save
14
+ end
15
+
16
+ desc "clear ", "forget all known libraries"
17
+ method_option :force, :aliases => "-f", :desc => "Clear without confirmation."
18
+ def clear
19
+ self.load(options)
20
+ if(!options[:force])
21
+ puts "Golden will forget all known libraries (#{@crucible.packages.keys.length}). Do you want to proceed? (Yes/No)"
22
+ response = STDIN.gets.chomp
23
+ if(response == "Yes")
24
+ @crucible.clear
25
+ puts "Golden library cache cleared."
26
+ else
27
+ puts "clear cancelled. To clear Golden libraries, run 'golden clear' again and respond with 'Yes' (case sensitive)."
28
+ end
29
+ else
30
+ @crucible.clear
31
+ puts "Golden library cache cleared."
32
+ end
33
+ self.save
34
+ end
35
+
36
+ desc "list ", "list all libraries built with golden"
37
+ method_option :verbose, :aliases => "-v", :desc => "List with package detail"
38
+ def list
39
+ self.load(options)
40
+ if(!@crucible.packages || @crucible.packages.keys.length == 0)
41
+ puts "No libraries have yet been built. Navigate to a go project and build one using 'golden build (LibraryName).'"
42
+ else
43
+ puts "Golden has access to the following libraries:"
44
+ if(@crucible.verbose?)
45
+ @crucible.packages.each do |name, location|
46
+ puts "#{name}\t#{location}"
47
+ end
48
+ else
49
+ puts @crucible.packages.keys
50
+ end
51
+ end
52
+ end
53
+
54
+ desc "install [fileName]", "install a library built with golden to the current ruby project"
55
+ method_option :verbose, :aliases => "-v", :desc => "Install with verbose logging"
56
+ def install(packageName)
57
+ self.load(options)
58
+ if(!!@crucible.packages[packageName])
59
+ puts "installing #{packageName}."
60
+ @crucible.install(packageName)
61
+ else
62
+ puts "No libraries named #{packageName} are yet known to golden. You can list all known libraries with 'golden list'"
63
+ end
64
+ end
65
+
66
+ protected
67
+ def load(options=nil)
68
+ @crucible = Golden::Crucible.new(options)
69
+ end
70
+ def save
71
+ @crucible.save
72
+ end
73
+ end
74
+ end
75
+
76
+ Golden::Cli.start(ARGV)
data/lib/crucible.rb ADDED
@@ -0,0 +1,133 @@
1
+
2
+ module Golden
3
+ class Crucible
4
+ attr_accessor :packages, :pkgLogFile
5
+ def initialize(options=nil)
6
+ @pkgLogFile = File.expand_path("~")+"/.golden_packages.json" # Persistent package log
7
+ # @pkgLogFile = File.expand_path(File.dirname(__FILE__)+"/../packages.json") # Gemset specific package log
8
+ # puts "opened package list at #{@pkgLogFile}"
9
+ @options = options
10
+ if(!File.exist?(@pkgLogFile))
11
+ @packages = {}
12
+ self.save()
13
+ else
14
+ @packages = JSON.parse(File.open(@pkgLogFile).read)
15
+ end
16
+ end
17
+
18
+ def build(fileName,dir)
19
+ libName,extension = fileName.split('.')
20
+ if(!extension)
21
+ fileName = "#{libName}.go"
22
+ end
23
+ golden_json = "#{dir}/golden.json"
24
+ if(File.exist?(golden_json))
25
+ golden_data = JSON.parse(File.open(golden_json).read)
26
+ else
27
+ golden_data = {}
28
+ end
29
+ path = dir+"/"+fileName
30
+ outfile = "#{libName}.so"
31
+ outpath = dir+"/"+libName
32
+ goVersion = `go version`
33
+ if(!!goVersion)
34
+ if(verbose?)
35
+ puts "detected #{goVersion}"
36
+ end
37
+ # if(File.exist?("#{path}/go.mod")) # Module build procedure
38
+ # puts "building module at #{path}"
39
+ # puts "building standard lib"
40
+ # system("go install -buildmode=shared -linkshared std")
41
+ # puts "installing dependencies"
42
+ # deps = system("go mod vendor")
43
+ # if(!!deps)
44
+ # puts "linking shared lib for module"
45
+ # lnk = `go install -buildmode=shared -linkshared #{infile}`
46
+ # puts lnk
47
+ # puts "building shared lib for module"
48
+ # bld = `go build -linkshared -o #{outfile}`
49
+ # puts bld
50
+ # system("go build -buildmode=c-shared -o #{outfile} #{fileName}")
51
+ # end
52
+ # else
53
+ puts "building #{fileName} to shared library #{outfile}"
54
+ system("go build -buildmode=c-shared -o #{outfile} #{fileName}")
55
+ # end
56
+ else
57
+ puts "go not found."
58
+ end
59
+ file = File.open(path)
60
+ source_code = file.read
61
+ exports = source_code.scan(/\/\/\s?export(?<function>.+)/).flatten
62
+ if(verbose?)
63
+ puts "#{fileName} exports the following methods:"
64
+ puts exports
65
+ end
66
+
67
+ golden_data[libName] = {}
68
+ exports.each do |e|
69
+ function_name = e.chomp.lstrip
70
+ declaration_regex = Regexp.new("func #{function_name}\s?\((?<args>.*)\) (?<returns>.*) {")
71
+ export_data = {}
72
+ export_data[:args] = {}
73
+ args = source_code.scan(declaration_regex).flatten[0]
74
+ args = args[1,args.length-2]
75
+ args = args.split(',')
76
+ args.each do |arg|
77
+ name, type = arg.split(" ")
78
+ export_data[:args][name] = type
79
+ end
80
+ export_data[:returns] = source_code.scan(declaration_regex).flatten[1]
81
+ # require "pry"
82
+ # binding.pry
83
+ golden_data[libName][function_name] = export_data
84
+ end
85
+ # require "pry"
86
+ # binding.pry
87
+ if(verbose?)
88
+ puts "writing library export info to #{golden_json}"
89
+ end
90
+ File.open(golden_json,"w") do |f|
91
+ f.write(JSON.pretty_generate(golden_data))
92
+ end
93
+ @packages[libName] = dir
94
+ end
95
+
96
+ def install(packageName)
97
+ cwd = Dir.pwd
98
+ extDestination = File.expand_path(cwd+"/bin")
99
+ if(!!@packages[packageName])
100
+ if(!File.exist? extDestination)
101
+ Dir.mkdir extDestination
102
+ end
103
+
104
+ if(File.exist?(cwd+"/golden.json"))
105
+ golden_json = JSON.parse(File.open(cwd+"/golden.json").read)
106
+ new_package = JSON.parse(File.open(@packages[packageName]+"/golden.json").read)
107
+ golden_json = golden_json.merge(new_package)
108
+ File.open(cwd+"/golden.json","w") do |f|
109
+ f.write(JSON.pretty_generate(golden_json))
110
+ end
111
+ else
112
+ FileUtils.cp(@packages[packageName]+"/golden.json", cwd+"/golden.json")
113
+ end
114
+ FileUtils.cp(@packages[packageName]+"/#{packageName}.so", extDestination+"/#{packageName}.so")
115
+ else
116
+ throw "No such package (#{packageName})."
117
+ end
118
+ end
119
+ def clear
120
+ @packages = {}
121
+ save
122
+ end
123
+ def verbose?
124
+ return (!!@options && !!@options[:verbose])
125
+ end
126
+ def save
127
+ # @pkgLogFile = File.expand_path(File.dirname(__FILE__)+"/../packages.json") # Installation specific package log
128
+ File.open(@pkgLogFile,"w") do |f|
129
+ f.write(JSON.pretty_generate(@packages))
130
+ end
131
+ end
132
+ end
133
+ end
data/lib/golden.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'ffi'
2
+ require 'json'
3
+ require "crucible"
4
+ module Golden
5
+ def self.require(library)
6
+ golden_data = self.load
7
+ return self::Library.new(File.expand_path("./bin/#{library}.so"),golden_data[library])
8
+ end
9
+ def self.load
10
+ golden_json = File.expand_path(Dir.pwd()+"/golden.json")
11
+ if(!!File.exist?(golden_json))
12
+ golden_data = JSON.parse(File.open(golden_json).read)
13
+ else
14
+ throw "golden.json not found."
15
+ end
16
+ return golden_data
17
+ end
18
+ module Library
19
+ extend FFI::Library
20
+ def self.new(library_file, exports)
21
+ @exports = exports
22
+ @library_file = library_file
23
+ ffi_lib @library_file
24
+ @exports.each do |func, data|
25
+ # puts "attach_function #{func}, #{data["args"]}, #{data["returns"]}"
26
+ attach_function func, data["args"].values.map(&:to_sym), data["returns"].to_sym
27
+ end
28
+ return self
29
+ end
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: golden
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1
5
+ platform: ruby
6
+ authors:
7
+ - Greg Mikeska
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-02-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.14.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.14.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.13'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 12.3.3
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 12.3.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: Golden is a development tool that makes it easier to wrap Go libraries
84
+ for use in Ruby.
85
+ email:
86
+ - gmikeska07@gmail.com
87
+ executables:
88
+ - golden
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - exe/golden
93
+ - lib/crucible.rb
94
+ - lib/golden.rb
95
+ homepage: https://github.com/gmikeska/golden
96
+ licenses: []
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubygems_version: 3.0.3
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Golden is a development tool that makes it easier to wrap Go libraries for
117
+ use in Ruby.
118
+ test_files: []