local_pac 0.0.7 → 0.1.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 (54) hide show
  1. data/Gemfile +2 -0
  2. data/bin/local_pac +47 -2
  3. data/features/initializer.feature +23 -0
  4. data/features/show_config.feature +22 -0
  5. data/features/support/env.rb +1 -1
  6. data/files/config.yaml +6 -0
  7. data/files/git-hook.erb +24 -0
  8. data/lib/local_pac/actions/create_directory.rb +33 -0
  9. data/lib/local_pac/actions/create_file.rb +48 -0
  10. data/lib/local_pac/actions/create_repository.rb +38 -0
  11. data/lib/local_pac/config.rb +64 -0
  12. data/lib/local_pac/data.rb +23 -0
  13. data/lib/local_pac/erb_generator.rb +34 -0
  14. data/lib/local_pac/exceptions.rb +9 -0
  15. data/lib/local_pac/file_server.rb +10 -3
  16. data/lib/local_pac/fileable.rb +12 -0
  17. data/lib/local_pac/git.rb +63 -0
  18. data/lib/local_pac/git_file.rb +18 -0
  19. data/lib/local_pac/git_repository.rb +52 -0
  20. data/lib/local_pac/initializer.rb +28 -0
  21. data/lib/local_pac/local_storage.rb +21 -0
  22. data/lib/local_pac/logger.rb +0 -5
  23. data/lib/local_pac/main.rb +24 -0
  24. data/lib/local_pac/pac_file.rb +5 -5
  25. data/lib/local_pac/runner.rb +29 -0
  26. data/lib/local_pac/spec_helper_file_server.rb +41 -0
  27. data/lib/local_pac/template_file.rb +19 -0
  28. data/lib/local_pac/template_repository.rb +22 -0
  29. data/lib/local_pac/ui_logger.rb +12 -0
  30. data/lib/local_pac/version.rb +1 -1
  31. data/lib/local_pac.rb +30 -4
  32. data/local_pac.gemspec +1 -0
  33. data/share/examples/config.yaml +5 -0
  34. data/spec/actions/create_directory_spec.rb +47 -0
  35. data/spec/actions/create_file_spec.rb +95 -0
  36. data/spec/actions/create_repository_spec.rb +47 -0
  37. data/spec/config_spec.rb +113 -0
  38. data/spec/data_spec.rb +34 -0
  39. data/spec/erb_generator_spec.rb +31 -0
  40. data/spec/features/fetch_proxy_pac_spec.rb +30 -12
  41. data/spec/git_repository_spec.rb +60 -0
  42. data/spec/git_spec.rb +100 -0
  43. data/spec/initializer_spec.rb +29 -0
  44. data/spec/local_storage_spec.rb +59 -0
  45. data/spec/pac_file_spec.rb +14 -14
  46. data/spec/runner_spec.rb +42 -0
  47. data/spec/support/git.rb +52 -0
  48. data/spec/support/reporting.rb +1 -0
  49. data/spec/support/rspec.rb +3 -0
  50. data/spec/template_file_spec.rb +25 -0
  51. data/spec/template_repository_spec.rb +44 -0
  52. metadata +74 -5
  53. data/lib/local_pac/pac_manager.rb +0 -55
  54. data/spec/pac_manager_spec.rb +0 -52
data/Gemfile CHANGED
@@ -10,6 +10,8 @@ group :test do
10
10
  gem 'simplecov', require: false
11
11
  gem 'rubocop', require: false
12
12
  gem 'coveralls', require: false
13
+ gem 'cucumber', require: false
14
+ gem 'aruba', require: false
13
15
  end
14
16
 
15
17
  group :development do
data/bin/local_pac CHANGED
@@ -1,19 +1,64 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
3
  require 'thor'
4
+ require 'fileutils'
4
5
 
5
6
  $LOAD_PATH << File.expand_path('../../lib', __FILE__)
6
7
  require 'local_pac'
7
8
 
8
9
  class Default < Thor
10
+ class_option :config_file, type: :string, desc: 'Config file'
11
+ class_option :log_level, type: :string, desc: 'Log level for ui logging'
12
+
9
13
  desc 'serve', 'Serve pacfiles'
10
- option :logfile, type: :string, default: File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'access.log')), desc: 'File to write access log to'
14
+ option :access_log, type: :string, desc: 'File to write access log to'
11
15
  option :port, type: :numeric, default: 8000, desc: 'The port the server listens on'
12
16
  def serve
13
- LocalPac::FileServer.use Rack::CommonLogger, LocalPac::Logger.new(options[:logfile])
17
+ LocalPac.config(LocalPac::Config.new(options[:config_file])) if options[:config_file]
18
+ access_log = options[:access_log] || ::File.join(LocalPac.config.log_sink, 'access.log')
19
+
20
+ case options[:log_level]
21
+ when 'info'
22
+ LocalPac.ui_logger.level = Logger::INFO
23
+ when 'debug'
24
+ LocalPac.ui_logger.level = Logger::DEBUG
25
+ else
26
+ LocalPac.ui_logger.level = Logger::WARN
27
+ end
28
+
29
+ LocalPac.ui_logger.debug('Options: ' + options.to_s)
30
+ LocalPac.ui_logger.debug("Config:\n" + LocalPac.config.to_s)
31
+
32
+ LocalPac::FileServer.use Rack::CommonLogger, LocalPac::Logger.new(access_log)
14
33
  LocalPac::FileServer.set :port, options[:port]
15
34
  LocalPac::FileServer.run!
16
35
  end
36
+
37
+ desc 'init', 'Create files/directories to use local_pac in dir or $PWD'
38
+ option :force, type: :boolean, default: false, desc: 'Overwrite existing files?'
39
+ def init
40
+ LocalPac.config(LocalPac::Config.new(options[:config_file])) if options[:config_file]
41
+
42
+ case options[:log_level]
43
+ when 'info'
44
+ LocalPac.ui_logger.level = Logger::INFO
45
+ when 'debug'
46
+ LocalPac.ui_logger.level = Logger::DEBUG
47
+ else
48
+ LocalPac.ui_logger.level = Logger::WARN
49
+ end
50
+
51
+ LocalPac.ui_logger.debug('Options: ' + options.to_s)
52
+ LocalPac.ui_logger.debug("Config:\n" + LocalPac.config.to_s)
53
+
54
+ LocalPac::Initializer.new(force: options[:force]).run
55
+ end
56
+
57
+ desc 'config', 'Show configuration'
58
+ def config
59
+ LocalPac.config(LocalPac::Config.new(options[:config_file])) if options[:config_file]
60
+ puts LocalPac.config
61
+ end
17
62
  end
18
63
 
19
64
  Default.start
@@ -0,0 +1,23 @@
1
+ Feature: Initialize environment
2
+ As a administrator
3
+ I want to have utility to init environment for local_pac
4
+ In order to make less mistakes
5
+
6
+ @wip
7
+ Scenario: Not initialized
8
+ Given a file named "config.yaml" with:
9
+ """
10
+ pid_file: 'run/pid'
11
+ local_storage: 'storage'
12
+ log_sink: 'log'
13
+ executable: 'bin/local_pac'
14
+ """
15
+ When I successfully run `local_pac init --config-file config.yaml`
16
+ Then the following directories should exist:
17
+ | directory |
18
+ | 'run' |
19
+ | 'storage/cache.git' |
20
+ | 'log' |
21
+ And the following files should exist:
22
+ | file |
23
+ | 'storage/cache.git/hooks/pre-receive' |
@@ -0,0 +1,22 @@
1
+ Feature: Show config
2
+ As a administrator
3
+ I want to have utility to show config of local pac
4
+ In order to make less mistakes
5
+
6
+ @wip
7
+ Scenario: Default
8
+ Given a file named "config.yaml" with:
9
+ """
10
+ pid_file: 'run/pid'
11
+ local_storage: 'storage'
12
+ log_sink: 'log'
13
+ executable: 'bin/local_pac'
14
+ """
15
+ When I successfully run `local_pac config`
16
+ Then the stdout should contain:
17
+ """
18
+ pid_file: 'run/pid'
19
+ local_storage: 'storage'
20
+ log_sink: 'log'
21
+ executable: 'bin/local_pac'
22
+ """
@@ -1 +1 @@
1
- require 'local_pac'
1
+ require 'aruba/cucumber'
data/files/config.yaml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ :storage_path: ~/.local/share/pacfiles/cache/cache.pstore
3
+ :import_paths:
4
+ - ~/.local/share/pacfiles/new
5
+ - ~/.pacfiles/new
6
+ - /var/pacfiles/new
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ <% Array(lookup('gem_path')).each do |p| -%>
4
+ $LOAD_PATH.unshift '<%= p %>'
5
+ <% end -%>
6
+
7
+ require 'git_hook-pre_receive'
8
+ require 'pac'
9
+
10
+ class PacFileSyntaxChecker
11
+ def check(files)
12
+ files.each do |f|
13
+ begin
14
+ PAC.load f.content
15
+ rescue
16
+ $stderr.puts "Syntax error found in #{f.name}. Please check files locally again, fix the error and send update via git."
17
+ exit 1
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ parser = Git::PreReceiveHookParser.new($stdin.read)
24
+ PacFileSyntaxChecker.new.check(parser.files)
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Actions
4
+ class CreateDirectory
5
+ private
6
+
7
+ attr_reader :fs_engine, :path, :options
8
+
9
+ public
10
+
11
+ def initialize(path, options = {}, fs_engine = FileUtils)
12
+ @path = path
13
+ @options = options
14
+ @fs_engine = fs_engine
15
+ end
16
+
17
+ def run
18
+ if need_to_run? || options[:force] == true
19
+ LocalPac.ui_logger.warn "Creating repository \"#{path}\"."
20
+ fs_engine.mkdir_p(path)
21
+ else
22
+ LocalPac.ui_logger.warn "Repository \"#{path}\" already exists. Do not create it again!."
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def need_to_run?
29
+ !File.exists?(path)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Actions
4
+ class CreateFile
5
+ private
6
+
7
+ attr_reader :name, :destination, :data, :options, :engine, :repository
8
+
9
+ public
10
+
11
+ def initialize(name, destination, data, options = {}, engine = ErbGenerator, repository = TemplateRepository.new)
12
+ @name = name
13
+ @destination = destination
14
+ @data = data
15
+ @options = options
16
+ @engine = engine
17
+ @repository = repository
18
+ end
19
+
20
+ def run
21
+ if need_to_run? || options[:force] == true
22
+ LocalPac.ui_logger.warn "Creating file \"#{destination}\"."
23
+
24
+ FileUtils.chmod('+x', template(name, destination, data)) if options[:executable] == true
25
+ else
26
+ LocalPac.ui_logger.warn "File \"#{destination}\" already exists. Do not create it again!."
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def template(local_name, local_destination, local_data)
33
+ template = repository.find(local_name)
34
+
35
+ generator = engine.new(local_data)
36
+ generator.compile(template, ::File.new(local_destination, 'w'))
37
+
38
+ local_destination
39
+ rescue Errno::ENOENT
40
+ fail Exceptions::ErbTemplateIsUnknown, "Unknown erb template \"#{template_path}\"."
41
+ end
42
+
43
+ def need_to_run?
44
+ !File.exists?(destination)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Actions
4
+ class CreateRepository
5
+ private
6
+
7
+ attr_reader :vcs_engine, :path, :options
8
+
9
+ public
10
+
11
+ def initialize(path, options = {}, vcs_engine = LocalPac::Git)
12
+ @path = path
13
+ @options = options
14
+ @vcs_engine = vcs_engine
15
+ end
16
+
17
+ def run
18
+ if need_to_run? || options[:force] == true
19
+ LocalPac.ui_logger.warn "Creating repository \"#{path}\"."
20
+
21
+ if options[:bare] == true
22
+ vcs_engine.init(path, true)
23
+ else
24
+ vcs_engine.init(path)
25
+ end
26
+ else
27
+ LocalPac.ui_logger.warn "Repository \"#{path}\" already exists. Do not create it again!."
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def need_to_run?
34
+ !File.exists?(path)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ class Config
4
+ private
5
+
6
+ attr_reader :config
7
+
8
+ @options = []
9
+ class << self
10
+
11
+ attr_reader :options
12
+
13
+ def option(option, default_value)
14
+ define_method option.to_sym do
15
+ config.transaction do
16
+ config.fetch(option.to_sym, default_value)
17
+ end
18
+ end
19
+
20
+ @options << option
21
+ end
22
+ end
23
+
24
+ public
25
+
26
+ def initialize(file = available_config_file, config_engine = YAML::Store)
27
+ @config = config_engine.new(file)
28
+ end
29
+
30
+ option :log_sink, File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'log')
31
+ option :local_storage, File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'data')
32
+ option :executable, File.expand_path('../../../bin/local_pac', __FILE__)
33
+ option :pid_file, File.join(ENV['HOME'], '.local', 'share', 'local_pac', 'run', 'pid')
34
+ option :gem_path, Gem.path
35
+
36
+ def to_s
37
+ result = []
38
+ result << sprintf("%20s | %s", 'option', 'value')
39
+ result << sprintf("%s + %s", '-' * 20, '-' * 80)
40
+
41
+ Config.options.each do |o|
42
+ result << sprintf("%20s | %s", o, Array(public_send(o)).join(', '))
43
+ end
44
+
45
+ result.join("\n")
46
+ end
47
+
48
+ private
49
+
50
+ def candiate_files
51
+ [
52
+ File.expand_path(File.join(Dir.getwd, 'config.yaml')),
53
+ File.expand_path(File.join(ENV['HOME'], '.config', 'local_pac', 'config.yaml')),
54
+ File.expand_path(File.join(ENV['HOME'], '.local_pac', 'config.yaml')),
55
+ File.expand_path(File.join('/etc', 'local_pac', 'config.yaml')),
56
+ File.expand_path('../../../files/config.yaml', __FILE__),
57
+ ]
58
+ end
59
+
60
+ def available_config_file
61
+ candiate_files.find { |f| File.exists? f }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,23 @@
1
+ module LocalPac
2
+ class Data
3
+ private
4
+
5
+ attr_reader :config
6
+
7
+ public
8
+
9
+ def initialize(config = LocalPac.config)
10
+ @config = config
11
+ end
12
+
13
+ def instance_binding
14
+ binding
15
+ end
16
+
17
+ def lookup(variable)
18
+ config.public_send variable.to_sym
19
+ rescue NoMethodError
20
+ fail "Variable \"#{variable}\" not found."
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ # Used to generate the template
4
+ class ErbGenerator
5
+ private
6
+
7
+ attr_reader :data
8
+
9
+ public
10
+
11
+ # Create erb generator
12
+ #
13
+ # @param [Data] data
14
+ # The data class to be used within the template
15
+ def initialize(data)
16
+ @data = data
17
+ end
18
+
19
+ # Compile the template
20
+ #
21
+ # @param [IO] source
22
+ # The source template to be used
23
+ # @param [IO] destination
24
+ # The output io handle
25
+ def compile(source, destination)
26
+ erb = ERB.new(source.read, nil, '-')
27
+ begin
28
+ destination.puts erb.result(data.instance_binding)
29
+ rescue SyntaxError => e
30
+ raise Exceptions::ErbTemplateHasSyntaxErrors, e.message
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,9 @@
1
+ module LocalPac
2
+ module Exceptions
3
+ # raise if there are template syntax errrors
4
+ class ErbTemplateHasSyntaxErrors < Exception; end
5
+
6
+ # raised if Template does not exist
7
+ class ErbTemplateIsUnknown < Exception; end
8
+ end
9
+ end
@@ -2,6 +2,15 @@ module LocalPac
2
2
  class FileServer < Sinatra::Base
3
3
  use Rack::Deflater
4
4
 
5
+ configure do
6
+ if settings.environment == :test
7
+ require_relative 'spec_helper_file_server'
8
+ SpecHelperFileServer.new
9
+ end
10
+
11
+ set :local_storage, LocalPac::LocalStorage.new
12
+ end
13
+
5
14
  configure do
6
15
  mime_type :proxy_pac_file, 'application/x-ns-proxy-autoconfig'
7
16
  end
@@ -16,9 +25,7 @@ module LocalPac
16
25
 
17
26
  get '/v1/pac/:name' do
18
27
  content_type :proxy_pac_file
19
-
20
- manager = PacManager.new
21
- file = manager.find(params[:name])
28
+ file = settings.local_storage.find(params[:name])
22
29
 
23
30
  if file.nil?
24
31
  fail Sinatra::NotFound, params[:name]
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ module Fileable
4
+ def mkdir_p(*args)
5
+ FileUtils.mkdir_p(*args)
6
+ end
7
+
8
+ def exist?(*args)
9
+ File.exist?(*args)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,63 @@
1
+ module LocalPac
2
+ class Git
3
+ def self.ls_files(filter = nil)
4
+ cmd = ['git ls-files']
5
+ cmd << " #{filter}" if filter
6
+
7
+ runner = Runner.new(cmd.join(" "))
8
+ runner.result
9
+ end
10
+
11
+ def self.ls_tree(git_dir = nil)
12
+ cmd = ['git']
13
+ cmd << "--git-dir #{git_dir}" if git_dir
14
+ cmd << 'ls-tree -r HEAD'
15
+
16
+ runner = Runner.new(cmd.join(" "))
17
+ runner.result
18
+ end
19
+
20
+ def self.init(path, is_bare = false)
21
+ cmd = ["git init #{path}"]
22
+ cmd << "--bare" if is_bare
23
+
24
+ runner = Runner.new(cmd.join(" "))
25
+ runner.result
26
+ end
27
+
28
+ def self.add(object)
29
+ runner = Runner.new("git add #{object}")
30
+ runner.result
31
+ end
32
+
33
+ def self.commit(message)
34
+ runner = Runner.new("git commit -m \"#{message}\"")
35
+ runner.result
36
+ end
37
+
38
+ def self.status
39
+ runner = Runner.new('git status')
40
+ runner.result
41
+ end
42
+
43
+ def self.show(sha = nil, git_dir = nil)
44
+ cmd = ['git']
45
+ cmd << "--git-dir #{git_dir}" if git_dir
46
+ cmd << 'show'
47
+ cmd << " #{sha}" if sha
48
+
49
+ runner = Runner.new(cmd.join(" "))
50
+ runner.result
51
+ end
52
+
53
+ def self.cat_file(sha, git_dir = nil)
54
+ cmd = ['git']
55
+ cmd << "--git-dir #{git_dir}" if git_dir
56
+ cmd << 'cat-file -p'
57
+ cmd << sha
58
+
59
+ runner = Runner.new(cmd.join(" "))
60
+ runner.result
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ class GitFile
4
+ attr_reader :path, :name, :content, :sha
5
+
6
+ def initialize(data, git_dir = nil)
7
+ data = data.split(" ")
8
+ @path = data.last
9
+ @sha = data[2]
10
+ @name = path.sub(/.pac$/, '').camelize.downcase.to_sym
11
+ @content = Git.cat_file(@sha, git_dir).join("\n")
12
+ end
13
+
14
+ def to_s
15
+ "#{name}: #{path} (#{content})"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,52 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+
4
+ class GitRepository
5
+ private
6
+
7
+ attr_reader :storage_path, :data
8
+
9
+ public
10
+
11
+ def initialize(storage_path, compressor_engine = JavaScriptCompressor, file_creator = PacFile)
12
+ @storage_path = storage_path
13
+ javascript_compressor = compressor_engine.new
14
+
15
+ create unless ::File.exists? storage_path
16
+
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
23
+
24
+ memo
25
+ end
26
+ end
27
+ end
28
+
29
+ def [](name)
30
+ data[name]
31
+ end
32
+
33
+ private
34
+
35
+ def create
36
+ Git.init(storage_path)
37
+ end
38
+
39
+ def pac_files
40
+ Dir.chdir(storage_path) do
41
+ LocalPac.ui_logger.debug "I'm using the following storage path: \"#{storage_path}\"."
42
+
43
+ files = Git.ls_tree(storage_path).collect do |l|
44
+ GitFile.new(l)
45
+ end
46
+
47
+ LocalPac.ui_logger.debug "Found the following files: \"#{files.join(", ")}\"."
48
+ files
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,28 @@
1
+ module LocalPac
2
+ class Initializer
3
+
4
+ private
5
+
6
+ attr_reader :config, :vcs, :options
7
+
8
+ include Fileable
9
+
10
+ public
11
+
12
+ def initialize(options = {}, config = LocalPac.config)
13
+ @config = config
14
+ @options = options
15
+ end
16
+
17
+ def run
18
+ LocalPac.ui_logger.info "Creating pid directory: #{::File.dirname(config.pid_file)}"
19
+ Actions::CreateDirectory.new(::File.dirname(config.pid_file), force: options[:force]).run
20
+ LocalPac.ui_logger.info "Creating log sink: #{config.log_sink}"
21
+ Actions::CreateDirectory.new(config.log_sink, force: options[:force]).run
22
+ LocalPac.ui_logger.info "Creating local storage: #{config.local_storage}"
23
+ Actions::CreateRepository.new(config.local_storage, bare: true, force: options[:force]).run
24
+ LocalPac.ui_logger.info "Creating pre-receive hook in local storage \"#{config.local_storage}\"."
25
+ Actions::CreateFile.new(:'git-hook', File.join(config.local_storage, 'hooks', 'pre-receive'), Data.new(config), force: options[:force]).run
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+ class LocalStorage
4
+ private
5
+
6
+ attr_reader :storage, :null_file
7
+
8
+ public
9
+
10
+ def initialize(storage = GitRepository.new(LocalPac.config.local_storage), null_file = NullPacFile.new )
11
+ @storage = storage
12
+ @null_file = null_file
13
+ end
14
+
15
+ def find(name)
16
+ name = name.sub(/.pac$/, '').camelize.downcase.to_sym
17
+ LocalPac.ui_logger.debug "Using the following name to find pac file: \":#{name}\"."
18
+ storage[name] || null_file
19
+ end
20
+ end
21
+ end
@@ -8,10 +8,5 @@ module LocalPac
8
8
  def write(*args, &block)
9
9
  @logger.<<(*args, &block)
10
10
  end
11
-
12
- private
13
-
14
- def default_path
15
- end
16
11
  end
17
12
  end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module LocalPac
3
+
4
+ @config_semaphore = Mutex.new
5
+ @logger_semaphore = Mutex.new
6
+
7
+ class << self
8
+ attr_reader :config_semaphore
9
+ attr_reader :logger_semaphore
10
+ attr_accessor :debug_mode
11
+
12
+ def config(local_config = LocalPac::Config.new)
13
+ config_semaphore.synchronize do
14
+ @config ||= local_config
15
+ end
16
+ end
17
+
18
+ def ui_logger(local_logger = LocalPac::UiLogger.new)
19
+ logger_semaphore.synchronize do
20
+ @ui_logger ||= local_logger
21
+ end
22
+ end
23
+ end
24
+ end