cached 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ coverage
2
+ doc/rdoc
3
+ log
4
+ pkg
5
+ .gemspec
@@ -0,0 +1,15 @@
1
+ load "#{File.dirname __FILE__}/vex/gem.rake"
2
+
3
+ task :default => :test
4
+
5
+ task :test do
6
+ sh "ruby test/test.rb"
7
+ end
8
+
9
+ task :rcov do
10
+ sh "cd test; rcov -o ../coverage -x ruby/.*/gems -x ^test.rb test.rb"
11
+ end
12
+
13
+ task :rdoc do
14
+ sh "rdoc -o doc/rdoc"
15
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV == %w(--install)
4
+ require "fileutils"
5
+
6
+ FileUtils.rm($0)
7
+ FileUtils.symlink(__FILE__, $0)
8
+ exit
9
+ elsif defined?(Gem)
10
+ STDERR.puts "Note: please run improved installation via\n\n\tsudo #{$0} --install"
11
+ end
12
+
13
+ begin
14
+ path = File.readlink(__FILE__)
15
+ rescue Errno::EINVAL
16
+ path = __FILE__
17
+ end
18
+
19
+ $: << File.expand_path(File.dirname(path) + "/../lib")
20
+
21
+ require "cached"
22
+
23
+ load "db.rb"
24
+
25
+ Db.database ||= "#{ENV["HOME"]}/.cached.sql"
26
+
27
+ puts Cached.exec *ARGV
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV == %w(--install)
4
+ require "fileutils"
5
+
6
+ FileUtils.rm($0)
7
+ FileUtils.symlink(__FILE__, $0)
8
+ exit
9
+ elsif defined?(Gem)
10
+ STDERR.puts "Note: please run improved installation via\n\n\tsudo #{$0} --install"
11
+ end
12
+
13
+ begin
14
+ path = File.readlink(__FILE__)
15
+ rescue Errno::EINVAL
16
+ path = __FILE__
17
+ end
18
+
19
+ $: << File.expand_path(File.dirname(path) + "/../lib")
20
+
21
+ require "db"
22
+
23
+ Db.database = "#{ENV["HOME"]}/.kvstore.sql"
24
+
25
+ class App
26
+ include Db
27
+
28
+ def initialize
29
+ unless ask "SELECT name FROM sqlite_master WHERE type='table' AND name='kvstore'"
30
+ ask "CREATE TABLE kvstore(key, value)"
31
+ ask "CREATE UNIQUE INDEX IF NOT EXISTS kvstore_key ON kvstore(key)"
32
+ end
33
+ end
34
+
35
+ def set(key, value)
36
+ ask("INSERT OR REPLACE INTO kvstore VALUES(?, ?)", key, value)
37
+ end
38
+
39
+ def get(key)
40
+ puts ask("SELECT value FROM kvstore WHERE key=?", key)
41
+ end
42
+
43
+ def delete(key)
44
+ ask("DELETE FROM kvstore WHERE key=?", key)
45
+ end
46
+
47
+ def list
48
+ sql("SELECT key, value FROM kvstore") do |row|
49
+ puts row.first
50
+ end
51
+ end
52
+
53
+ def help(*args)
54
+ STDERR.puts <<-MSG
55
+
56
+ Usage:
57
+
58
+ #{$0} set key value
59
+ #{$0} get key
60
+ #{$0} delete key
61
+ #{$0} list
62
+ MSG
63
+ end
64
+ end
65
+
66
+ app = App.new
67
+
68
+ cmd = ARGV.shift || "help"
69
+ begin
70
+ app.send cmd, *ARGV
71
+ rescue NoMethodError, ArgumentError
72
+ puts $!
73
+ app.help
74
+ end
data/gem.yml ADDED
@@ -0,0 +1,11 @@
1
+ #
2
+ # A vex/gem config file.
3
+ version: 0.2
4
+ authors: ["radiospiel"]
5
+ email: eno@open-lab.org
6
+ homepage: http://radiospiel.org
7
+ summary: cached command line tool
8
+ description: |
9
+ The 'cached' command line tool provides an easy to use *nix caching tool.
10
+
11
+ dependencies: sqlite3
@@ -0,0 +1 @@
1
+ STDERR.puts "*** THIS IS THE POST INSTALL SCRIPT"
@@ -0,0 +1 @@
1
+ STDERR.puts "*** THIS IS THE PRE UNINSTALL SCRIPT"
@@ -0,0 +1,84 @@
1
+ load "db.rb"
2
+ Db.database ||= "#{ENV["HOME"]}/.cached.sql"
3
+
4
+ require 'digest/sha1'
5
+
6
+ class Entry
7
+ extend Db
8
+
9
+ def self.init
10
+ unless ask "SELECT name FROM sqlite_master WHERE type='table' AND name='cached'"
11
+ ask "CREATE TABLE cached(key, value, valid_until)"
12
+ end
13
+
14
+ ask "CREATE UNIQUE INDEX IF NOT EXISTS cached_key ON cached(key)"
15
+ ask "CREATE INDEX IF NOT EXISTS cached_valid_until ON cached(valid_until)"
16
+ end
17
+
18
+ init
19
+
20
+ def self.cleanup
21
+ ask "DELETE FROM cached WHERE valid_until < ?", now
22
+ end
23
+
24
+ def self.now
25
+ Time.now.to_i
26
+ end
27
+
28
+ def self.get(key)
29
+ value, valid_until = *row("SELECT value, valid_until FROM cached WHERE key=?", key)
30
+ return value if value && valid_until.to_i >= now
31
+ end
32
+
33
+ def self.set(key, value, options)
34
+ ask "INSERT OR REPLACE INTO cached (key, value, valid_until) VALUES(?, ?, ?)", key, value, now + options[:ttl]
35
+ end
36
+ end
37
+
38
+ module Cached
39
+ def self.exec(*args)
40
+ ttl = 3600
41
+
42
+ case args.first
43
+ when /^--ttl=([0-9]+)$/
44
+ args.shift
45
+ ttl = $1.to_i
46
+ end
47
+
48
+ key = Digest::SHA1.hexdigest(Dir.getwd + ":" + args.inspect)
49
+ Entry.get(key) || begin
50
+ value = run(*args)
51
+ Entry.set(key, value, :ttl => ttl)
52
+ value
53
+ end
54
+ end
55
+
56
+ def self.shell_escape(*args)
57
+ args.map do |str|
58
+ if str.empty?
59
+ "''"
60
+ elsif %r{\A[0-9A-Za-z+,./:=@_-]+\z} =~ str
61
+ str
62
+ else
63
+ result = ''
64
+ str.scan(/('+)|[^']+/) {
65
+ if $1
66
+ result << %q{\'} * $1.length
67
+ else
68
+ result << "'#{$&}'"
69
+ end
70
+ }
71
+ result
72
+ end
73
+ end.join(" ")
74
+ end
75
+
76
+ def self.run(*args)
77
+ command = args.join(" ")
78
+ # command = shell_escape args
79
+ `#{command}`
80
+ end
81
+ end
82
+
83
+ #
84
+ # TODO: start cleanup in background... Entry.cleanup
@@ -0,0 +1,40 @@
1
+ load "fast_gem.rb"
2
+
3
+ FastGem.load "sqlite3"
4
+
5
+ module Db
6
+ def self.database=(database)
7
+ @database = database
8
+ end
9
+
10
+ def self.database
11
+ @database
12
+ end
13
+
14
+ def db
15
+ @db ||= SQLite3::Database.new(Db.database)
16
+ end
17
+
18
+ def log(query, *args)
19
+ # STDERR.puts "[sqlite] #{query}"
20
+ end
21
+
22
+ def sql(query, *args, &block)
23
+ log query, *args
24
+ r = db.execute query, *args, &block
25
+ return r if r
26
+ return [ db.changes ] if query =~ /^\s*(DELETE|INSERT)\b/i
27
+ end
28
+
29
+ def ask(query, *args)
30
+ log query, *args
31
+ r = db.get_first_value(query, *args)
32
+ return r if r
33
+ return db.changes if query =~ /^\s*(DELETE|INSERT)\b/i
34
+ end
35
+
36
+ def row(query, *args)
37
+ log query, *args
38
+ db.get_first_row(query, *args)
39
+ end
40
+ end
@@ -0,0 +1,56 @@
1
+ module Gem
2
+ require 'rbconfig'
3
+
4
+ if !defined?(ConfigMap)
5
+
6
+ ConfigMap = {
7
+ :EXEEXT => RbConfig::CONFIG["EXEEXT"],
8
+ :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
9
+ :arch => RbConfig::CONFIG["arch"],
10
+ :bindir => RbConfig::CONFIG["bindir"],
11
+ :datadir => RbConfig::CONFIG["datadir"],
12
+ :libdir => RbConfig::CONFIG["libdir"],
13
+ :ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
14
+ :ruby_version => RbConfig::CONFIG["ruby_version"],
15
+ :rubylibprefix => RbConfig::CONFIG["rubylibprefix"],
16
+ :sitedir => RbConfig::CONFIG["sitedir"],
17
+ :sitelibdir => RbConfig::CONFIG["sitelibdir"],
18
+ :vendordir => RbConfig::CONFIG["vendordir"] ,
19
+ :vendorlibdir => RbConfig::CONFIG["vendorlibdir"]
20
+ }
21
+
22
+ end
23
+
24
+ def self.user_home
25
+ ENV["HOME"]
26
+ end
27
+ end
28
+
29
+ require 'rubygems/defaults'
30
+
31
+ module FastGem
32
+ extend self
33
+
34
+ def gem_paths
35
+ [ Gem.default_dir, Gem.user_dir ]
36
+ end
37
+
38
+ #
39
+ # Try ro find the file "name" in any of the available paths, and return the path
40
+ def find(name)
41
+ # look into each gempath for a matching file, sort by version (roughly),
42
+ # and return the last hit
43
+ gem_paths.
44
+ map { |gem_path| Dir.glob("#{gem_path}/gems/#{name}-[0-9]*") }.
45
+ flatten.
46
+ sort_by { |gem_path| gem_path.gsub(/.*\/gems\/[^-]+-/, "") }.
47
+ last
48
+ end
49
+
50
+ def load(name)
51
+ path = find(name)
52
+ # STDERR.puts "Load #{name} from #{path}"
53
+ $: << "#{path}/lib"
54
+ require name
55
+ end
56
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Start a console that initializes the gem
4
+ #
5
+ require "irb"
6
+ require "rubygems"
7
+
8
+ begin
9
+ require 'wirble'
10
+ Wirble.init
11
+ Wirble.colorize
12
+ rescue LoadError
13
+ STDERR.puts "To enable colorized and tab completed run 'gem install wirble'"
14
+ end
15
+
16
+ $: << "#{File.dirname(__FILE__)}/../lib"
17
+ $: << "#{File.dirname(__FILE__)}/../init.rb"
18
+
19
+ IRB.start
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ DIRNAME = File.expand_path File.dirname(__FILE__)
3
+ Dir.chdir(DIRNAME)
4
+
5
+ STDERR.puts "Skipping tests"
@@ -0,0 +1,36 @@
1
+ def sys(*args)
2
+ STDERR.puts "#{args.join(" ")}"
3
+ system *args
4
+ end
5
+
6
+ namespace :gem do
7
+ task :build => :spec do
8
+ options = []
9
+ sys "gem build .gemspec #{options.join(" ")} && mkdir -p pkg && mv *.gem pkg"
10
+ end
11
+
12
+ task :spec do
13
+ File.open ".gemspec", "w" do |file|
14
+ file.write <<-TXT
15
+ require "vex/gem"
16
+ Gem.spec File.dirname(__FILE__)
17
+ TXT
18
+ end
19
+ end
20
+
21
+ task :install => :build do
22
+ file = Dir.glob("pkg/*.gem").sort.last
23
+ sys "gem install #{file}"
24
+ end
25
+
26
+ task :push => :build do
27
+ file = Dir.glob("pkg/*.gem").sort.last
28
+ puts "To push the gem to gemcutter please run"
29
+ puts
30
+ puts "\tgem push #{file}"
31
+ end
32
+ end
33
+
34
+ desc "Build gem"
35
+ # task :gem => %w(test gem:install)
36
+ task :gem => %w(gem:install gem:push)
@@ -0,0 +1,95 @@
1
+ module Gem
2
+ (class << self; self; end).class_eval do
3
+ def default_attributes
4
+ %w(name version date files executables)
5
+ end
6
+
7
+ def set_root(root)
8
+ @root = File.expand_path(root)
9
+ @name = File.basename(@root)
10
+ @conf ||= YAML.load File.read("#{@root}/gem.yml")
11
+ @attributes ||= (default_attributes + @conf.keys.map(&:to_s)).uniq
12
+ end
13
+
14
+ # attr_reader :root, :conf, :attributes,
15
+ attr_reader :name
16
+
17
+ def attribute(name)
18
+ if @conf.key?(name) && !%w(dependencies).include?(name)
19
+ @conf[name]
20
+ else
21
+ self.send(name)
22
+ end
23
+ end
24
+
25
+ #
26
+ # create a new Gem::Specification object for this gem.
27
+ def spec(root)
28
+ self.set_root root
29
+
30
+ Gem::Specification.new do |s|
31
+ @attributes.each do |attr|
32
+ v = attribute(attr)
33
+ next if v.nil?
34
+
35
+ log attr, v
36
+
37
+ s.send attr + "=", v
38
+ end
39
+
40
+ %w(pre_uninstall post_install).each do |hook|
41
+ next unless File.exists?("#{root}/hooks/#{hook}.rb")
42
+ log hook, "yes"
43
+ Gem.send(hook) {
44
+ load "hooks/#{hook}.rb"
45
+ }
46
+ end
47
+ end
48
+ end
49
+
50
+ def log(attr, v)
51
+ v = case attr
52
+ when "files" then "#{v.length} files"
53
+ else v.inspect
54
+ end
55
+
56
+ STDERR.puts "#{"%20s" % attr}:\t#{v}"
57
+ end
58
+
59
+ def dependencies
60
+ return nil unless @conf["dependencies"]
61
+
62
+ @conf["dependencies"].map do |d|
63
+ Gem::Dependency.new d, ">= 0"
64
+ end
65
+ end
66
+
67
+ def head(file)
68
+ File.open(file) do |f|
69
+ f.readline
70
+ end
71
+ end
72
+
73
+ def executables
74
+ r = Dir.glob("#{@root}/bin/**/*").map do |file|
75
+ next unless head(file) =~ /^#!/
76
+ file[@root.length + 5 .. -1]
77
+ end.compact
78
+
79
+ return nil if r.empty?
80
+ r
81
+ end
82
+
83
+ #
84
+ # get files from git
85
+ def files
86
+ r = `git ls-files`.split("\n")
87
+ end
88
+
89
+ #
90
+ # return the date
91
+ def date
92
+ Date.today.to_s
93
+ end
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cached
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ version: "0.2"
10
+ platform: ruby
11
+ authors:
12
+ - radiospiel
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-06-16 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sqlite3
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ description: |
35
+ The 'cached' command line tool provides an easy to use *nix caching tool.
36
+
37
+ email: eno@open-lab.org
38
+ executables:
39
+ - cached
40
+ - kvstore
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - .gitignore
47
+ - Rakefile
48
+ - bin/cached
49
+ - bin/kvstore
50
+ - gem.yml
51
+ - hooks/post_install.rb
52
+ - hooks/pre_uninstall.rb
53
+ - lib/cached.rb
54
+ - lib/db.rb
55
+ - lib/fast_gem.rb
56
+ - script/console
57
+ - test/test.rb
58
+ - vex/gem.rake
59
+ - vex/gem.rb
60
+ has_rdoc: true
61
+ homepage: http://radiospiel.org
62
+ licenses: []
63
+
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: 3
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.7
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: cached command line tool
94
+ test_files: []
95
+