local_pac 0.1.13 → 0.2.0

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