Skip to content

Commit

Permalink
Extract Share and Initializer from Configuration
Browse files Browse the repository at this point in the history
The original motivation for this refactoring is to reduce the number of
objects which are getting passed around making the Celluloid conversion
easier. ActiveRecord objects (e.g., Share and Config) will be used from
their class methods, more like Rails does. This will eliminate some
object passing as well as deprecating some delegate code in the
Configuration and Manager classes.

This results in 3 classes instead of 1 and I hope will make each one
easier to understand, and test.

I have kept Configuration::Config to avoid changing the table names.
This could be simplified in the future.
  • Loading branch information
acant committed Jul 7, 2015
1 parent 568d02b commit fcacb46
Show file tree
Hide file tree
Showing 17 changed files with 248 additions and 218 deletions.
1 change: 1 addition & 0 deletions bin/gitdocs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

require 'gitdocs'

Gitdocs::Initializer.initialize_all
Gitdocs::Cli.start(ARGV)
8 changes: 4 additions & 4 deletions config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ use Rack::Static,
root: './lib/gitdocs/public'
use Rack::MethodOverride

config_root = './tmp/web'
FileUtils.mkdir_p(config_root)
Gitdocs::SettingsApp.set :manager, Gitdocs::Manager.new(config_root, true)
Gitdocs::Initializer.root_dirname = './tmp/web'
Gitdocs::Initializer.initialize_database

Gitdocs::SettingsApp.set :logging, true
map('/settings') { run Gitdocs::SettingsApp }

Gitdocs::BrowserApp.set :repositories, Gitdocs::Configuration.new(config_root).shares.map { |x| Gitdocs::Repository.new(x) }
Gitdocs::BrowserApp.set :repositories, Gitdocs::Share.all.map { |x| Gitdocs::Repository.new(x) }
Gitdocs::BrowserApp.set :logging, true
map('/') { run Gitdocs::BrowserApp }
2 changes: 2 additions & 0 deletions lib/gitdocs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
require 'table_print'

require 'gitdocs/version'
require 'gitdocs/initializer'
require 'gitdocs/share'
require 'gitdocs/configuration'
require 'gitdocs/runner'
require 'gitdocs/server'
Expand Down
20 changes: 11 additions & 9 deletions lib/gitdocs/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,22 @@ def restart
method_option :pid, type: :string, aliases: '-P'
desc 'add PATH', 'Adds a path to gitdocs'
def add(path)
config.add_path(path)
Share.create_by_path!(normalize_path(path))
say "Added path #{path} to doc list"
restart if running?
end

method_option :pid, type: :string, aliases: '-P'
desc 'rm PATH', 'Removes a path from gitdocs'
def rm(path)
config.remove_path(path)
Share.remove_by_path(path)
say "Removed path #{path} from doc list"
restart if running?
end

desc 'clear', 'Clears all paths from gitdocs'
def clear
config.clear
Share.destroy_all
say 'Cleared paths from gitdocs'
end

Expand Down Expand Up @@ -103,7 +103,7 @@ def status
status
end
tp(
config.shares,
Share.all,
{ sync: { display_method: :sync_type } },
{ s: status_display },
:path
Expand All @@ -120,7 +120,7 @@ def open
end

web_port = options[:port]
web_port ||= config.web_frontend_port
web_port ||= Configuration.web_frontend_port
Launchy.open("http://localhost:#{web_port}/")
end

Expand All @@ -146,10 +146,6 @@ def runner
)
end

def config
@config ||= Configuration.new
end

def running?
runner.daemon_running?
end
Expand All @@ -162,6 +158,12 @@ def pid_path
options[:pid] || '/tmp/gitdocs.pid'
end

# @param [String] path
# @return [String]
def normalize_path(path)
File.expand_path(path, Dir.pwd)
end

# @return [Symbol] to indicate how the file system is being watched
def file_system_watch_method # rubocop:disable CyclomaticComplexity
if Guard::Listener.mac? && Guard::Darwin.usable?
Expand Down
114 changes: 19 additions & 95 deletions lib/gitdocs/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,112 +1,36 @@
# -*- encoding : utf-8 -*-

require 'active_record'
require 'grit'

class Gitdocs::Configuration
attr_reader :config_root

def initialize(config_root = nil)
@config_root = config_root || File.expand_path('.gitdocs', ENV['HOME'])
FileUtils.mkdir_p(@config_root)
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: ENV['TEST'] ? ':memory:' : File.join(@config_root, 'config.db')
)
ActiveRecord::Migrator.migrate(File.expand_path('../migration', __FILE__))
import_old_shares unless ENV['TEST']
end

class Share < ActiveRecord::Base
#attr_accessible :polling_interval, :path, :notification, :branch_name, :remote_name, :sync_type
end

class Config < ActiveRecord::Base
#attr_accessible :start_web_frontend, :web_frontend_port
end

# return [Boolean]
def start_web_frontend
global.start_web_frontend
# @return [Boolean]
def self.start_web_frontend
Config.global.start_web_frontend
end

# @return [Integer]
def web_frontend_port
global.web_frontend_port
end

# @param [String] path
# @param [Hash] opts
def add_path(path, opts = nil)
path = normalize_path(path)
path_opts = { path: path }
path_opts.merge!(opts) if opts
Share.new(path_opts).save!
def self.web_frontend_port
Config.global.web_frontend_port
end

# @param [Hash] new_config
# @option new_config [Hash] 'config'
# @option new_config [Array<Hash>] 'share'
def update_all(new_config)
global.update_attributes(new_config['config'])
new_config['share'].each do |index, share_config|
# Skip the share update if there is no path specified.
next unless share_config['path'] && !share_config['path'].empty?

# Split the remote_branch into remote and branch
remote_branch = share_config.delete('remote_branch')
if remote_branch
share_config['remote_name'], share_config['branch_name'] = remote_branch.split('/', 2)
end
shares[index.to_i].update_attributes(share_config)
end
def self.update(new_config)
Config.global.update_attributes(new_config)
end

# @param [String] path of the share to remove
def remove_path(path)
path = normalize_path(path)
Share.where(path: path).destroy_all
end

# @param [Integer] id of the share to remove
#
# @return [true] share was deleted
# @return [false] share does not exist
def remove_by_id(id)
Share.find(id).destroy
true
rescue ActiveRecord::RecordNotFound
false
end

def clear
Share.destroy_all
end

def shares
Share.all
end

##############################################################################

private

def global
fail if Config.all.size > 1
Config.create! if Config.all.empty?
Config.all.first
end

def normalize_path(path)
File.expand_path(path, Dir.pwd)
end

def import_old_shares
full_path = File.expand_path('paths', config_root)
return unless File.exist?(full_path)
# NOTE: This record has been kept as a subclass to avoid changing the
# database table. There are other ways to achieve this, but this seemed most
# clear for now. [2015-06-26 -- acant]
class Config < ActiveRecord::Base
# attr_accessible :start_web_frontend, :web_frontend_port

File.read(full_path).split("\n").each do |path|
Share.find_or_create_by_path(path)
# @return [Gitdocs::Configuration::Config]
def self.global
fail if all.size > 1
create! if all.empty?
all.first
end
end
end


63 changes: 63 additions & 0 deletions lib/gitdocs/initializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# -*- encoding : utf-8 -*-

require 'active_record'

module Gitdocs
class Initializer
# @return [nil]
def self.initialize_all
initialize_database
initialize_old_paths
end

# @return [nil]
def self.initialize_database
FileUtils.mkdir_p(root_dirname)
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: database
)
ActiveRecord::Migrator.migrate(
File.expand_path('../migration', __FILE__)
)
end

# @return [nil]
def self.initialize_old_paths
old_path_dirname = File.expand_path('paths', root_dirname)
return unless File.exist?(old_path_dirname)

File.read(old_path_dirname).split("\n").each do |path|
begin
Share.create_by_path!(path)
rescue # rubocop:disable ExceptionHandling
# Nothing to do, because we want the process to keep going.
end
end
end

# @return [String]
def self.root_dirname
@root_dirname ||= File.expand_path('.gitdocs', ENV['HOME'])
end

# @param [nil, String] value
# @return [nil]
def self.root_dirname=(value)
return if value.nil?
@root_dirname = value
end

# @return [String]
def self.database
@database ||= File.join(root_dirname, 'config.db')
end

# @param [nil, String] value
# @return [nil]
def self.database=(value)
return if value.nil?
@database = value
end
end
end
34 changes: 6 additions & 28 deletions lib/gitdocs/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ module Gitdocs
Restart = Class.new(RuntimeError)

class Manager
attr_reader :config, :debug
attr_reader :debug

def initialize(config_root, debug)
@config = Configuration.new(config_root)
@logger = Logger.new(File.expand_path('log', @config.config_root))
@debug = debug
Initializer.root_dirname = config_root
@logger = Logger.new(File.expand_path('log', Initializer.root_dirname))
@debug = debug
yield @config if block_given?
end

def start(web_port = nil)
log("Starting Gitdocs v#{VERSION}...")
log("Using configuration root: '#{config.config_root}'")
log("Using configuration root: '#{Initializer.root_dirname}'")
shares = Share.all
log("Shares: (#{shares.length}) #{shares.map(&:inspect).join(', ')}")

begin
Expand Down Expand Up @@ -59,28 +60,5 @@ def stop
def log(msg, level = :info)
@debug ? puts(msg) : @logger.send(level, msg)
end

def start_web_frontend
config.start_web_frontend
end

def web_frontend_port
config.web_frontend_port
end

def shares
config.shares
end

# @see Gitdocs::Configuration#update_all
def update_all(new_config)
config.update_all(new_config)
EM.add_timer(0.1) { restart }
end

# @see Gitdocs::Configuration#remove_by_id
def remove_by_id(id)
config.remove_by_id(id)
end
end
end
2 changes: 1 addition & 1 deletion lib/gitdocs/migration/004_add_index_for_path.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

class AddIndexForPath < ActiveRecord::Migration
def self.up
shares = Gitdocs::Configuration::Share.all.reduce(Hash.new { |h, k| h[k] = [] }) { |h, s| h[s.path] << s; h }
shares = Gitdocs::Share.all.reduce(Hash.new { |h, k| h[k] = [] }) { |h, s| h[s.path] << s; h }
shares.each do |path, shares|
shares.shift
shares.each(&:destroy) unless shares.empty?
Expand Down
2 changes: 1 addition & 1 deletion lib/gitdocs/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Gitdocs::Repository
# @see #valid?
# @see #invalid_reason
#
# @param [String, Configuration::Share] path_or_share
# @param [String, Share] path_or_share
def initialize(path_or_share)
path = path_or_share
if path_or_share.respond_to?(:path)
Expand Down
5 changes: 2 additions & 3 deletions lib/gitdocs/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@ def initialize(manager, port = 8888, repositories)
end

def self.start_and_wait(manager, override_port, repositories)
return false unless manager.start_web_frontend
return false unless Configuration.start_web_frontend

web_port = override_port || manager.web_frontend_port
web_port = override_port || Configuration.web_frontend_port
server = Server.new(manager, web_port, repositories)
server.start
server.wait_for_start
true
end

def start
Gitdocs::SettingsApp.set :manager, @manager
Gitdocs::BrowserApp.set :repositories, @repositories

Thin::Logging.debug = @manager.debug
Expand Down
Loading

0 comments on commit fcacb46

Please sign in to comment.