local_pac 0.1.13 → 0.2.0

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.
Files changed (85) hide show
  1. data/{LICENSE.txt → LICENSE.md} +0 -0
  2. data/README.DEVELOPER.md +7 -0
  3. data/README.md +138 -2
  4. data/Rakefile +16 -8
  5. data/app/controllers/application_controller.rb +5 -3
  6. data/app/controllers/assets_controller.rb +3 -2
  7. data/app/controllers/file_serve_controller.rb +3 -6
  8. data/app/controllers/lookup_controller.rb +9 -9
  9. data/app/locales/en.yml +1 -0
  10. data/app/views/application.haml +1 -1
  11. data/bin/local_pac +49 -64
  12. data/config.ru +24 -7
  13. data/features/initializer.feature +4 -4
  14. data/features/show_status.feature +2 -2
  15. data/files/config.yaml +2 -2
  16. data/files/example-config.erb +10 -12
  17. data/files/git-hook.erb +1 -0
  18. data/lib/local_pac.rb +22 -5
  19. data/lib/local_pac/actions/create_directory.rb +2 -2
  20. data/lib/local_pac/actions/create_file.rb +8 -2
  21. data/lib/local_pac/actions/create_repository.rb +6 -8
  22. data/lib/local_pac/actions/get_system_information.rb +78 -0
  23. data/lib/local_pac/actions/print_newline.rb +19 -0
  24. data/lib/local_pac/actions/print_title.rb +41 -0
  25. data/lib/local_pac/actions/reload_configuration.rb +21 -0
  26. data/lib/local_pac/actions/reload_local_storage.rb +22 -0
  27. data/lib/local_pac/actions/send_signal.rb +32 -0
  28. data/lib/local_pac/actions/show_config.rb +10 -0
  29. data/lib/local_pac/actions/show_process_information.rb +94 -0
  30. data/lib/local_pac/application_status.rb +34 -0
  31. data/lib/local_pac/cli/helper.rb +34 -0
  32. data/lib/local_pac/cli/reload.rb +36 -0
  33. data/lib/local_pac/config.rb +15 -13
  34. data/lib/local_pac/exceptions.rb +6 -0
  35. data/lib/local_pac/file.rb +32 -0
  36. data/lib/local_pac/git.rb +20 -6
  37. data/lib/local_pac/git_repository.rb +40 -28
  38. data/lib/local_pac/git_storage.rb +60 -0
  39. data/lib/local_pac/initializer.rb +8 -5
  40. data/lib/local_pac/local_storage.rb +3 -4
  41. data/lib/local_pac/main.rb +2 -2
  42. data/lib/local_pac/{null_pac_file.rb → null_file.rb} +5 -1
  43. data/lib/local_pac/server.rb +1 -1
  44. data/lib/local_pac/spec_helper_file_server.rb +6 -5
  45. data/lib/local_pac/template_file.rb +1 -1
  46. data/lib/local_pac/template_repository.rb +3 -3
  47. data/lib/local_pac/version.rb +1 -1
  48. data/local_pac.gemspec +13 -9
  49. data/script/console +1 -1
  50. data/share/archlinux/PKGBUILD +4 -1
  51. data/share/archlinux/config.yaml +1 -1
  52. data/spec/actions/create_directory_spec.rb +3 -3
  53. data/spec/actions/create_file_spec.rb +23 -2
  54. data/spec/actions/create_repository_spec.rb +3 -3
  55. data/spec/actions/get_system_information_spec.rb +22 -0
  56. data/spec/actions/print_new_line_spec.rb +36 -0
  57. data/spec/actions/print_title_spec.rb +50 -0
  58. data/spec/actions/reload_configuration_spec.rb +38 -0
  59. data/spec/actions/reload_repository_spec.rb +35 -0
  60. data/spec/actions/send_signal_spec.rb +58 -0
  61. data/spec/actions/show_config_spec.rb +22 -0
  62. data/spec/actions/show_process_information_spec.rb +45 -0
  63. data/spec/application_status_spec.rb +40 -0
  64. data/spec/config_spec.rb +11 -11
  65. data/spec/features/fetch_proxy_pac_spec.rb +11 -10
  66. data/spec/features/lookup_proxy_spec.rb +32 -40
  67. data/spec/file_spec.rb +56 -0
  68. data/spec/git_spec.rb +13 -7
  69. data/spec/git_storage_spec.rb +64 -0
  70. data/spec/initializer_spec.rb +7 -5
  71. data/spec/{null_pac_file_spec.rb → null_file_spec.rb} +6 -6
  72. data/spec/proxy_pac/pac_result_html_stylist_spec.rb +3 -2
  73. data/spec/runner_spec.rb +1 -1
  74. data/spec/spec_helper.rb +2 -2
  75. data/spec/spec_helper_features.rb +2 -2
  76. data/spec/support/config.rb +5 -0
  77. data/spec/support/filesystem.rb +1 -1
  78. data/spec/support/git.rb +23 -2
  79. data/spec/support/helper_features.rb +23 -0
  80. data/spec/template_repository_spec.rb +2 -2
  81. metadata +113 -32
  82. data/lib/local_pac/git_file.rb +0 -18
  83. data/lib/local_pac/pac_file.rb +0 -27
  84. data/spec/git_repository_spec.rb +0 -60
  85. data/spec/pac_file_spec.rb +0 -44
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Actions
4
+ class SendSignal
5
+ private
6
+
7
+ attr_reader :signal, :pid_file, :signalizer
8
+
9
+ public
10
+
11
+ def initialize(signal, pid_file = LocalPac.config.pid_file, signalizer = Process)
12
+ @signal = signal
13
+ @pid_file = pid_file
14
+ @signalizer = signalizer
15
+ end
16
+
17
+ def run
18
+ signalizer.kill signal, pid
19
+ rescue Exceptions::PidFileDoesNotExist
20
+ LocalPac.ui_logger.error "Pid-file \"#{pid_file}\" does not exist. I'm not able to send daemon signal \"#{signal}\"."
21
+ end
22
+
23
+ private
24
+
25
+ def pid
26
+ ::File.read(pid_file).to_i
27
+ rescue Errno::ENOENT => e
28
+ raise Exceptions::PidFileDoesNotExist, e.message
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Actions
4
+ class ShowConfig
5
+ def run
6
+ puts LocalPac.config
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,94 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Actions
4
+ class ShowProcessInformation
5
+
6
+ class IntegerPidInfo
7
+ attr_reader :pid, :error_message
8
+
9
+ def initialize(pid_info)
10
+ @pid = pid_info.to_i
11
+ @error_message = "Process \"#{@pid}\" cannot be found. It is not a running process."
12
+ @error_occured = false
13
+ end
14
+
15
+ def error?
16
+ @error_occured
17
+ end
18
+ end
19
+
20
+ class FilePidInfo
21
+ attr_reader :pid, :error_message
22
+
23
+ def initialize(pid_info)
24
+ @pid = Pathname.new(pid_info).read.to_i
25
+ @error_message = "Process \"#{@pid}\" cannot be found. It is not a running process."
26
+ @error_occured = false
27
+ rescue Errno::ENOENT
28
+ @pid = nil
29
+ @error_message = "Pid-file #{pid_info} cannot be found. Please choose a correct path and try again."
30
+ @error_occured = true
31
+ end
32
+
33
+ def error?
34
+ @error_occured
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :pid_info
41
+
42
+ public
43
+
44
+ def initialize(pid_info)
45
+ if pid_info.kind_of? Integer
46
+ @pid_info = IntegerPidInfo.new(pid_info)
47
+ else
48
+ @pid_info = FilePidInfo.new(pid_info)
49
+ end
50
+ end
51
+
52
+ def run
53
+ if pid_info.error?
54
+ puts pid_info.error_message
55
+ return
56
+ end
57
+
58
+ s = Sys::ProcTable.ps(pid_info.pid)
59
+
60
+ if s.nil?
61
+ puts pid_info.error_message
62
+ return
63
+ end
64
+
65
+ printf( "%#{max_field_length}s | %s\n", 'Information', 'Value')
66
+ printf( "%s + %s\n", '-' * max_field_length, '-' * 40)
67
+ fields.each { |i| printf( "%#{max_field_length}s | %s\n", i, s.public_send(i)) }
68
+ end
69
+
70
+ private
71
+
72
+ def max_field_length
73
+ all = fields + [ 'Information', 'Value' ]
74
+ all.inject(0) { |memo, f| memo = f.size if f.size > memo ; memo}
75
+ end
76
+
77
+ def fields
78
+ %w[
79
+ pid
80
+ name
81
+ exe
82
+ cmdline
83
+ uid
84
+ pgrp
85
+ egid
86
+ gid
87
+ ppid
88
+ root
89
+ environ
90
+ ]
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ class ApplicationStatus
4
+
5
+ private
6
+
7
+ include Pager
8
+
9
+ attr_reader :should_page
10
+
11
+ public
12
+
13
+ def initialize(options = {})
14
+ @should_page = options.fetch(:pager, :true)
15
+ config = options.fetch(:config, LocalPac.config)
16
+
17
+ @actions = []
18
+ @actions << Actions::PrintTitle.new('System Information')
19
+ @actions << Actions::GetSystemInformation.new
20
+ @actions << Actions::PrintNewline.new(2)
21
+ @actions << Actions::PrintTitle.new('Application Configuration')
22
+ @actions << Actions::ShowConfig.new
23
+ @actions << Actions::PrintNewline.new(2)
24
+ @actions << Actions::PrintTitle.new('Process Information')
25
+ @actions << Actions::ShowProcessInformation.new(config.pid_file)
26
+ end
27
+
28
+ def show
29
+ page if should_page
30
+
31
+ @actions.each(&:run)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Cli
4
+ module Helper
5
+ def pid(config = LocalPac.config)
6
+ ::File.read(config.pid_file).chomp
7
+ rescue Errno::ENOENT
8
+ 'Stale PID-file'
9
+ end
10
+
11
+ def set_log_level(requested_level)
12
+ case requested_level.to_s.to_sym
13
+ when :info
14
+ LocalPac.ui_logger.level = ::Logger::INFO
15
+ when :debug
16
+ LocalPac.ui_logger.level = ::Logger::DEBUG
17
+ else
18
+ LocalPac.ui_logger.level = ::Logger::WARN
19
+ end
20
+ end
21
+
22
+ def set_debug(request)
23
+ if request
24
+ LocalPac.ui_logger.info "Activating debug mode."
25
+
26
+ require 'pry'
27
+ require 'debugger'
28
+ end
29
+ rescue LoadError
30
+ LocalPac.ui_logger.error "You tried to enable debug-mode, but either 'pry'- or 'debugger'-gem are not installed. Please fix that before using the debug-switch again."
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Cli
4
+ class Reload < Thor
5
+ no_commands {
6
+ include LocalPac::Cli::Helper
7
+ }
8
+
9
+ desc 'configuration', 'Reload configuration'
10
+ def configuration
11
+ LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
12
+ LocalPac.config.pid_file = options[:pid_file] if options[:pid_file]
13
+ LocalPac.config.lock
14
+
15
+ set_log_level(options[:log_level])
16
+ set_debug(options[:debug])
17
+
18
+ LocalPac.ui_logger.info "Ask web application (PID: #{pid(LocalPac.config)}) to reload configuration"
19
+ Actions::SendSignal.new(LocalPac.config.reload_config_signal).run
20
+ end
21
+
22
+ desc 'local_storage', 'Reload local_storage'
23
+ def local_storage
24
+ LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
25
+ LocalPac.config.pid_file = options[:pid_file] if options[:pid_file]
26
+ LocalPac.config.lock
27
+
28
+ set_log_level(options[:log_level])
29
+ set_debug(options[:debug])
30
+
31
+ LocalPac.ui_logger.info "Ask web application (PID: #{pid(LocalPac.config)}) to reload storage"
32
+ Actions::SendSignal.new(LocalPac.config.reload_storage_signal).run
33
+ end
34
+ end
35
+ end
36
+ end
@@ -32,7 +32,7 @@ module LocalPac
32
32
  yaml = Psych.load_file(file)
33
33
 
34
34
  if yaml.respond_to? :[]
35
- @config = yaml.symbolize_keys.freeze
35
+ @config = yaml.symbolize_keys
36
36
  else
37
37
  @config = {}
38
38
  end
@@ -45,13 +45,15 @@ module LocalPac
45
45
  config.freeze
46
46
  end
47
47
 
48
- option :log_sink, File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'log'))
49
- option :local_storage, File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'data'))
50
- option :executable, File.expand_path(File.expand_path('../../../bin/local_pac', __FILE__))
51
- option :pid_file, File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'run', 'pid'))
52
- option :gem_path, Gem.path.collect {|p| File.expand_path(p) }
53
- option :access_log, File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'log', 'access.log'))
54
- option :sass_cache, File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'cache', 'sass'))
48
+ option :local_storage, ::File.expand_path(::File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'data', 'storage.git'))
49
+ option :executable, ::File.expand_path(::File.expand_path('../../../bin/local_pac', __FILE__))
50
+ option :pid_file, ::File.expand_path(::File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'run', 'pid'))
51
+ option :gem_path, Gem.path.collect {|p|::File.expand_path(p) }
52
+ option :access_log, ::File.expand_path(::File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'log', 'access.log'))
53
+ option :sass_cache, ::File.expand_path(::File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'cache'))
54
+ option :config_file, ::File.expand_path(::File.join(ENV['HOME'], '.config', 'local_pac', 'config.yaml'))
55
+ option :reload_config_signal, :USR1
56
+ option :reload_storage_signal, :USR2
55
57
 
56
58
  def to_s
57
59
  result = []
@@ -67,17 +69,17 @@ module LocalPac
67
69
 
68
70
  def allowed_config_file_paths
69
71
  [
70
- File.expand_path(File.join(ENV['HOME'], '.config', 'local_pac', 'config.yaml')),
71
- File.expand_path(File.join(ENV['HOME'], '.local_pac', 'config.yaml')),
72
- File.expand_path(File.join('/etc', 'local_pac', 'config.yaml')),
73
- File.expand_path('../../../files/config.yaml', __FILE__),
72
+ ::File.expand_path(::File.join(ENV['HOME'], '.config', 'local_pac', 'config.yaml')),
73
+ ::File.expand_path(::File.join(ENV['HOME'], '.local_pac', 'config.yaml')),
74
+ ::File.expand_path(::File.join('/etc', 'local_pac', 'config.yaml')),
75
+ ::File.expand_path('../../../files/config.yaml', __FILE__),
74
76
  ]
75
77
  end
76
78
 
77
79
  private
78
80
 
79
81
  def available_config_file
80
- allowed_config_file_paths.find { |f| File.exists? f }
82
+ allowed_config_file_paths.find { |f| ::File.exists? f }
81
83
  end
82
84
  end
83
85
  end
@@ -20,5 +20,11 @@ module LocalPac
20
20
 
21
21
  # raised if request is invalid
22
22
  class GivenUrlInvalid < Exception; end
23
+
24
+ # raised if pid file does not exist
25
+ class PidFileDoesNotExist < Exception; end
26
+
27
+ # raised if repository does not exist
28
+ class RepositoryDoesNotExist < Exception; end
23
29
  end
24
30
  end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ class File
4
+ private
5
+
6
+ attr_reader :extension
7
+
8
+ public
9
+
10
+ attr_accessor :compressed_content
11
+ attr_reader :path, :name, :content
12
+
13
+ def initialize(path, content = '')
14
+ @path = path
15
+ @extension = ::File.extname(path)
16
+ @name = path.sub(/\..*$/, '').camelize.downcase.to_sym
17
+ @content = content
18
+ end
19
+
20
+ def nil?
21
+ false
22
+ end
23
+
24
+ def extension?(ext)
25
+ extension == ext
26
+ end
27
+
28
+ def prepare(handler)
29
+ handler.prepare(self)
30
+ end
31
+ end
32
+ end
@@ -2,29 +2,43 @@ module LocalPac
2
2
  class Git
3
3
  def self.ls_files(filter = nil)
4
4
  cmd = ['git ls-files']
5
- cmd << " #{filter}" if filter
5
+ cmd << filter if filter
6
6
 
7
7
  runner = Runner.new(cmd.join(" "))
8
8
  runner.result
9
9
  end
10
10
 
11
- def self.ls_tree(git_dir = nil)
11
+ def self.config(option, value, git_dir, is_global = true)
12
12
  cmd = ['git']
13
13
  cmd << "--git-dir #{git_dir}" if git_dir
14
- cmd << 'ls-tree -r HEAD'
14
+ cmd << 'config'
15
+ cmd << option
16
+ cmd << "\"#{value}\""
17
+ cmd << "--global" if is_global
15
18
 
16
19
  runner = Runner.new(cmd.join(" "))
17
20
  runner.result
18
21
  end
19
22
 
20
- def self.init(path, is_bare = false)
21
- cmd = ["git init #{File.expand_path(path)}"]
22
- cmd << "--bare" if is_bare
23
+
24
+ def self.ls_tree(git_dir = nil, filter = nil)
25
+ cmd = ['git']
26
+ cmd << "--git-dir #{git_dir}" if git_dir
27
+ cmd << 'ls-tree -r HEAD'
28
+ cmd << filter if filter
23
29
 
24
30
  runner = Runner.new(cmd.join(" "))
25
31
  runner.result
26
32
  end
27
33
 
34
+ def self.init(path, is_bare = false)
35
+ if is_bare
36
+ Rugged::Repository.init_at(path, :bare)
37
+ else
38
+ Rugged::Repository.init_at(path)
39
+ end
40
+ end
41
+
28
42
  def self.add(object)
29
43
  runner = Runner.new("git add #{object}")
30
44
  runner.result
@@ -1,50 +1,62 @@
1
1
  # encoding: utf-8
2
2
  module LocalPac
3
-
4
3
  class GitRepository
5
4
  private
6
5
 
7
- attr_reader :storage_path, :data
6
+ attr_reader :repository, :root_commit
8
7
 
9
8
  public
10
9
 
11
- def initialize(storage_path, compressor_engine = JavaScriptCompressor, file_creator = PacFile)
12
- @storage_path = File.expand_path(storage_path)
13
- javascript_compressor = compressor_engine.new
10
+ attr_reader :storage_path
14
11
 
15
- create unless ::File.exists? @storage_path
12
+ def initialize(storage_path)
13
+ @storage_path = ::File.expand_path(storage_path)
14
+ @repository = Rugged::Repository.new(storage_path)
15
+ rescue Rugged::RepositoryError
16
+ raise Exceptions::RepositoryDoesNotExist, "Sorry, but #{storage_path} is not a git repository."
17
+ end
16
18
 
17
- mutex = Mutex.new
18
- mutex.synchronize do
19
- @data = pac_files.reduce({}) do |memo, git_file|
20
- pac_file = file_creator.new(git_file)
21
- javascript_compressor.prepare(pac_file)
22
- memo[pac_file.name.to_sym] = pac_file
19
+ def self.create(storage_path)
20
+ storage_path = ::File.expand_path(storage_path)
21
+ Rugged::Repository.init_at(storage_path, :bare)
23
22
 
24
- memo
25
- end
26
- end
23
+ new(storage_path)
27
24
  end
28
25
 
29
- def [](name)
30
- data[name]
31
- end
26
+ def add_content(path, content = '', mode = 0100644, commit_info = default_commit_info)
27
+ oid = repository.write(content, :blob)
28
+ index = Rugged::Index.new
29
+ index.add(:path => path, :oid => oid, :mode => mode)
32
30
 
33
- private
31
+ unless repository.empty?
32
+ root_commit = @repository.lookup(@repository.head.target)
33
+
34
+ root_commit.tree.walk_blobs(:postorder) do |r, e|
35
+ e.merge!( { path: "#{r}#{e[:name]}" } )
36
+ e.delete(:name)
34
37
 
35
- def create
36
- Git.init(storage_path)
38
+ index.add(e)
39
+ end
40
+ end
41
+
42
+ options = {}
43
+ options[:tree] = index.write_tree(repository)
44
+ options[:parents] = repository.empty? ? [] : [ repository.head.target ].compact
45
+ options[:update_ref] = 'HEAD'
46
+ options.merge! commit_info
47
+
48
+ Rugged::Commit.create(repository, options)
37
49
  end
38
50
 
39
- def pac_files
40
- LocalPac.ui_logger.debug "I'm using the following storage path: \"#{storage_path}\"."
51
+ private
41
52
 
42
- files = Git.ls_tree(storage_path).collect do |l|
43
- GitFile.new(l, storage_path)
44
- end
53
+ def default_commit_info
54
+ options = {}
55
+ options[:author] = { :email => 'local_pac@local_pac', :name => 'Local Pac', :time => Time.now }
56
+ options[:committer] = { :email => 'local_pac@local_pac', :name => 'Local Pac', :time => Time.now }
57
+ options[:message] = 'Commit made by local pac itself'
45
58
 
46
- LocalPac.ui_logger.debug "Found the following files: \"#{files.join(", ")}\"."
47
- files
59
+ options
48
60
  end
49
61
  end
50
62
  end