controll 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +134 -0
- data/LICENSE.txt +20 -0
- data/README.md +320 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/controll.gemspec +184 -0
- data/lib/controll.rb +14 -0
- data/lib/controll/assistant.rb +19 -0
- data/lib/controll/command.rb +24 -0
- data/lib/controll/commander.rb +24 -0
- data/lib/controll/errors.rb +1 -0
- data/lib/controll/executor.rb +6 -0
- data/lib/controll/executor/base.rb +16 -0
- data/lib/controll/executor/notificator.rb +12 -0
- data/lib/controll/flow_handler.rb +11 -0
- data/lib/controll/flow_handler/base.rb +19 -0
- data/lib/controll/flow_handler/control.rb +85 -0
- data/lib/controll/flow_handler/errors.rb +5 -0
- data/lib/controll/flow_handler/event_helper.rb +18 -0
- data/lib/controll/flow_handler/redirect.rb +51 -0
- data/lib/controll/flow_handler/redirect/action.rb +45 -0
- data/lib/controll/flow_handler/redirect/mapper.rb +41 -0
- data/lib/controll/flow_handler/render.rb +51 -0
- data/lib/controll/helper.rb +101 -0
- data/lib/controll/helper/event_matcher.rb +21 -0
- data/lib/controll/helper/hash_access.rb +26 -0
- data/lib/controll/helper/notify.rb +74 -0
- data/lib/controll/helper/params.rb +20 -0
- data/lib/controll/helper/path_resolver.rb +45 -0
- data/lib/controll/helper/session.rb +20 -0
- data/lib/controll/notify.rb +7 -0
- data/lib/controll/notify/base.rb +75 -0
- data/lib/controll/notify/flash.rb +52 -0
- data/lib/controll/notify/typed.rb +39 -0
- data/spec/acceptance/app_test.rb +156 -0
- data/spec/app/.gitignore +15 -0
- data/spec/app/Gemfile +6 -0
- data/spec/app/Gemfile.lock +108 -0
- data/spec/app/README.rdoc +261 -0
- data/spec/app/Rakefile +7 -0
- data/spec/app/app/controllers/application_controller.rb +6 -0
- data/spec/app/app/controllers/posts_controller.rb +52 -0
- data/spec/app/app/models/.gitkeep +0 -0
- data/spec/app/app/models/post.rb +88 -0
- data/spec/app/app/views/layouts/application.html.erb +13 -0
- data/spec/app/app/views/posts/_form.html.erb +31 -0
- data/spec/app/app/views/posts/edit.html.erb +6 -0
- data/spec/app/app/views/posts/index.html.erb +23 -0
- data/spec/app/app/views/posts/new.html.erb +5 -0
- data/spec/app/app/views/posts/show.html.erb +8 -0
- data/spec/app/config.ru +4 -0
- data/spec/app/config/application.rb +16 -0
- data/spec/app/config/boot.rb +6 -0
- data/spec/app/config/environment.rb +5 -0
- data/spec/app/config/environments/development.rb +21 -0
- data/spec/app/config/environments/test.rb +29 -0
- data/spec/app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/app/config/initializers/inflections.rb +15 -0
- data/spec/app/config/initializers/mime_types.rb +5 -0
- data/spec/app/config/initializers/secret_token.rb +7 -0
- data/spec/app/config/initializers/session_store.rb +8 -0
- data/spec/app/config/locales/en.yml +5 -0
- data/spec/app/config/routes.rb +62 -0
- data/spec/app/db/seeds.rb +7 -0
- data/spec/app/lib/assets/.gitkeep +0 -0
- data/spec/app/lib/tasks/.gitkeep +0 -0
- data/spec/app/log/.gitkeep +0 -0
- data/spec/app/public/404.html +26 -0
- data/spec/app/public/422.html +26 -0
- data/spec/app/public/500.html +25 -0
- data/spec/app/public/favicon.ico +0 -0
- data/spec/app/public/index.html +241 -0
- data/spec/app/public/javascripts/application.js +9663 -0
- data/spec/app/public/robots.txt +5 -0
- data/spec/app/public/stylesheets/application.css +83 -0
- data/spec/app/script/rails +6 -0
- data/spec/app/spec/controllers/posts_controller_spec.rb +59 -0
- data/spec/app/spec/isolated_spec_helper.rb +6 -0
- data/spec/app/spec/spec_helper.rb +5 -0
- data/spec/app/spec/unit/controllers/posts_controller_isolated_spec.rb +63 -0
- data/spec/app/spec/unit/controllers/posts_controller_spec.rb +59 -0
- data/spec/app/test/functional/.gitkeep +0 -0
- data/spec/app/test/functional/posts_controller_test.rb +67 -0
- data/spec/app/test/isolated_test_helper.rb +7 -0
- data/spec/app/test/test_helper.rb +6 -0
- data/spec/app/test/unit/.gitkeep +0 -0
- data/spec/app/test/unit/controllers/posts_controller_isolated_test.rb +71 -0
- data/spec/app/test/unit/controllers/posts_controller_test.rb +67 -0
- data/spec/app/vendor/assets/javascripts/.gitkeep +0 -0
- data/spec/app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/app/vendor/plugins/.gitkeep +0 -0
- data/spec/controll/asssistant_spec.rb +5 -0
- data/spec/controll/command_spec.rb +56 -0
- data/spec/controll/commander_spec.rb +68 -0
- data/spec/controll/executor/notificator_spec.rb +27 -0
- data/spec/controll/flow_handler/control_spec.rb +159 -0
- data/spec/controll/flow_handler/redirect/action_spec.rb +48 -0
- data/spec/controll/flow_handler/redirect/mapper_spec.rb +69 -0
- data/spec/controll/flow_handler/redirect_spec.rb +93 -0
- data/spec/controll/flow_handler/render_spec.rb +110 -0
- data/spec/controll/helper/event_matcher_spec.rb +21 -0
- data/spec/controll/helper/hash_access_spec.rb +25 -0
- data/spec/controll/helper/notify_spec.rb +48 -0
- data/spec/controll/helper/params_spec.rb +28 -0
- data/spec/controll/helper/path_resolver_spec.rb +49 -0
- data/spec/controll/helper/session_spec.rb +28 -0
- data/spec/controll/helper_spec.rb +108 -0
- data/spec/controll/notify/base_spec.rb +123 -0
- data/spec/controll/notify/flash_spec.rb +27 -0
- data/spec/controll/notify/message_handler.rb +72 -0
- data/spec/controll/notify/typed_spec.rb +28 -0
- data/spec/functional_test_helper.rb +25 -0
- data/spec/helper.rb +33 -0
- data/spec/rspec_controller_class.rb +15 -0
- data/spec/rspec_functional_helper.rb +25 -0
- data/spec/rspec_helper.rb +42 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/test_helper.rb +183 -0
- data/spec/unit/functional_test_helper_test.rb +65 -0
- data/spec/unit/macros_test.rb +43 -0
- data/spec/unit/mixin_test.rb +147 -0
- data/spec/unit/rspec_functional_helper.rb +42 -0
- data/spec/unit/rspec_helper_test.rb +91 -0
- data/spec/unit/test_helper_test.rb +235 -0
- metadata +289 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
module Controll
|
2
|
+
module Helper
|
3
|
+
module Params
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Controll::Helper::HashAccess
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def param_methods *args
|
9
|
+
options = args.extract_options!
|
10
|
+
names = args
|
11
|
+
hash_access_method *names, options.merge(hash: :params)
|
12
|
+
end
|
13
|
+
|
14
|
+
def param_method name, options = {}
|
15
|
+
hash_access_method name, options.merge(hash: :params)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Controll
|
2
|
+
module Helper
|
3
|
+
class PathResolver
|
4
|
+
class PathResolverError < StandardError; end
|
5
|
+
|
6
|
+
attr_reader :caller
|
7
|
+
|
8
|
+
def initialize caller
|
9
|
+
@caller = caller
|
10
|
+
end
|
11
|
+
|
12
|
+
def extract_path type, *args
|
13
|
+
if args.first.kind_of?(Symbol)
|
14
|
+
raise "Caller must have a notice method" unless caller.respond_to? :notice
|
15
|
+
caller.notice args.first
|
16
|
+
resolve_path type
|
17
|
+
else
|
18
|
+
args.empty? ? resolve_path(type) : args.first
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def resolve_path type
|
23
|
+
raise "Caller must have a #main_event method" unless caller.respond_to? :main_event
|
24
|
+
caller.send(type).each do |path, events|
|
25
|
+
return path.to_s if matches? events
|
26
|
+
end
|
27
|
+
raise PathResolverError, "Path could not be resolved for: #{event_name}"
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def matches? events
|
33
|
+
event_matcher.match?(events)
|
34
|
+
end
|
35
|
+
|
36
|
+
def event_matcher
|
37
|
+
@event_matcher ||= EventMatcher.new event
|
38
|
+
end
|
39
|
+
|
40
|
+
def event
|
41
|
+
@event ||= caller.main_event
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Controll
|
2
|
+
module Helper
|
3
|
+
module Session
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include Controll::Helper::HashAccess
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def session_methods *args
|
9
|
+
options = args.extract_options!
|
10
|
+
names = args
|
11
|
+
hash_access_method *names, options.merge(hash: :session)
|
12
|
+
end
|
13
|
+
|
14
|
+
def session_method name, options = {}
|
15
|
+
hash_access_method name, options.merge(hash: :session)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'liquid'
|
2
|
+
require 'controll/notify/flash'
|
3
|
+
|
4
|
+
module Controll
|
5
|
+
module Notify
|
6
|
+
class Base < Flash
|
7
|
+
class NotifyMappingError < StandardError; end
|
8
|
+
|
9
|
+
def notify name, options = {}
|
10
|
+
@options.merge! options if options.kind_of? Hash
|
11
|
+
signal notify_msg(name)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.inherited(base)
|
15
|
+
base.extend ClassMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
attr_reader :signal_type
|
20
|
+
|
21
|
+
def type name
|
22
|
+
@signal_type = name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def notify_msg name, opts = {}
|
29
|
+
opts = options.merge(opts).stringify_keys
|
30
|
+
|
31
|
+
msg = send(name) if respond_to? name
|
32
|
+
msg ||= messages[name.to_sym] if respond_to? :messages
|
33
|
+
msg ||= name.to_sym
|
34
|
+
|
35
|
+
# if name is not mapped to a message, it could well be, that the
|
36
|
+
# event should not generate a nofification message
|
37
|
+
return nil if !msg
|
38
|
+
|
39
|
+
# try various approaches!
|
40
|
+
case msg
|
41
|
+
when Symbol
|
42
|
+
translate msg, opts
|
43
|
+
when String
|
44
|
+
msg.strip!
|
45
|
+
return replace_args(msg, opts) if msg =~ /{{.*}}/
|
46
|
+
msg
|
47
|
+
else
|
48
|
+
msg_error!
|
49
|
+
end
|
50
|
+
rescue
|
51
|
+
end
|
52
|
+
|
53
|
+
def msg_error!
|
54
|
+
raise NotifyMappingError, "Notify message could not be generated for: #{name}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def translate msg, opts = {}
|
58
|
+
I18n.t i18n_key(msg), opts.symbolize_keys
|
59
|
+
end
|
60
|
+
|
61
|
+
def replace_args msg, opts
|
62
|
+
# Parses and compiles the template
|
63
|
+
Liquid::Template.parse(msg).render(opts)
|
64
|
+
end
|
65
|
+
|
66
|
+
def i18n_key msg
|
67
|
+
parts = self.class.name.split('::')
|
68
|
+
middle = parts[1..-2].join('.').underscore
|
69
|
+
type = parts.last.sub(/Msg$/, '').underscore
|
70
|
+
ns = [middle, type].join('.').sub /^./, ''
|
71
|
+
[ns,msg].join('.')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Controll
|
2
|
+
module Notify
|
3
|
+
class Flash
|
4
|
+
attr_reader :controller
|
5
|
+
|
6
|
+
def initialize controller, options = {}
|
7
|
+
@controller = controller
|
8
|
+
@options = options if options.kind_of? Hash
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def options
|
14
|
+
@options ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
delegate :flash, to: :controller
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_writer :types
|
21
|
+
|
22
|
+
def types
|
23
|
+
@types ||= [:notice, :error, :warning, :success]
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_types *types
|
27
|
+
@types += types.flatten
|
28
|
+
end
|
29
|
+
alias_method :add_type, :add_types
|
30
|
+
end
|
31
|
+
|
32
|
+
def signal msg, type = nil
|
33
|
+
return if msg.blank?
|
34
|
+
type ||= signal_type || :notice
|
35
|
+
raise ArgumentError, "Unsupported flash type: #{type}. Register via #{self.class.name}#types or #add_type" unless valid_type? type
|
36
|
+
flash[type] = msg unless type.blank?
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid_type? type
|
40
|
+
types.include? type.to_sym
|
41
|
+
end
|
42
|
+
|
43
|
+
def types
|
44
|
+
self.class.types
|
45
|
+
end
|
46
|
+
|
47
|
+
def signal_type
|
48
|
+
self.class.signal_type
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'controll/notify/flash'
|
2
|
+
|
3
|
+
module Controll
|
4
|
+
module Notify
|
5
|
+
class Typed < Flash
|
6
|
+
class MissingNotifyClass < StandardError; end
|
7
|
+
|
8
|
+
def notice
|
9
|
+
raise MissingNotifyClass, "#{msg_class(:notice)} class missing" unless msg_class(:notice)
|
10
|
+
@notice ||= msg_class(:notice).new flash #, options
|
11
|
+
end
|
12
|
+
|
13
|
+
def error
|
14
|
+
raise MissingNotifyClass, "#{msg_class(:warning)} class missing" unless msg_class(:error)
|
15
|
+
@error ||= msg_class(:error).new flash #, options
|
16
|
+
end
|
17
|
+
|
18
|
+
def success
|
19
|
+
raise MissingNotifyClass, "#{msg_class(:success)} class missing" unless msg_class(:success)
|
20
|
+
@success ||= msg_class(:success).new flash #, options
|
21
|
+
end
|
22
|
+
|
23
|
+
def warning
|
24
|
+
raise MissingNotifyClass, "#{msg_class(:warning)} class missing" unless msg_class(:warning)
|
25
|
+
@warning ||= msg_class(:warning).new flash #, options
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def msg_class name
|
31
|
+
msg_classes[name] ||= "#{self.class}::#{name.to_s.camelize}Msg".constantize
|
32
|
+
end
|
33
|
+
|
34
|
+
def msg_classes
|
35
|
+
@msg_classes ||= {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'capybara'
|
3
|
+
require 'capybara_minitest_spec'
|
4
|
+
require 'capybara/poltergeist'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
module FocusedController
|
8
|
+
module Test
|
9
|
+
def self.port
|
10
|
+
@port ||= begin
|
11
|
+
server = TCPServer.new('127.0.0.1', 0)
|
12
|
+
port = server.addr[1]
|
13
|
+
ensure
|
14
|
+
server.close if server
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Capybara.run_server = false
|
21
|
+
Capybara.app_host = "http://127.0.0.1:#{FocusedController::Test.port}"
|
22
|
+
|
23
|
+
describe 'acceptance test' do
|
24
|
+
def app_root
|
25
|
+
TEST_ROOT + '/app'
|
26
|
+
end
|
27
|
+
|
28
|
+
def within_test_app
|
29
|
+
Bundler.with_clean_env do
|
30
|
+
Dir.chdir(app_root) do
|
31
|
+
begin
|
32
|
+
prev_gemfile, ENV['BUNDLE_GEMFILE'] = ENV['BUNDLE_GEMFILE'], "#{app_root}/Gemfile"
|
33
|
+
prev_rubyopt, ENV['RUBYOPT'] = ENV['RUBYOPT'], nil
|
34
|
+
ENV['RAILS_VERSION'] = ActionPack::VERSION::STRING
|
35
|
+
yield
|
36
|
+
ensure
|
37
|
+
ENV['BUNDLE_GEMFILE'] = prev_gemfile
|
38
|
+
ENV['RUBYOPT'] = prev_rubyopt
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def run_without_bundle_exec(command)
|
45
|
+
within_test_app do
|
46
|
+
`#{command}`
|
47
|
+
$?.must_equal 0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_command(command)
|
52
|
+
run_without_bundle_exec "bundle exec #{command}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def read_output(stream)
|
56
|
+
read = IO.select([stream], [], [stream], 0.1)
|
57
|
+
output = ""
|
58
|
+
loop { output << stream.read_nonblock(1024) } if read
|
59
|
+
output
|
60
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, EOFError
|
61
|
+
output
|
62
|
+
end
|
63
|
+
|
64
|
+
# This spawns a server process to run the app under test,
|
65
|
+
# and then waits for it to successfully come up so we can
|
66
|
+
# actually run the test.
|
67
|
+
def start_server
|
68
|
+
within_test_app do
|
69
|
+
IO.popen("bundle exec rails s -p #{FocusedController::Test.port} 2>&1") do |out|
|
70
|
+
start = Time.now
|
71
|
+
started = false
|
72
|
+
output = ""
|
73
|
+
timeout = 60.0
|
74
|
+
|
75
|
+
while !started && !out.eof? && Time.now - start <= timeout
|
76
|
+
output << read_output(out)
|
77
|
+
sleep 0.1
|
78
|
+
|
79
|
+
begin
|
80
|
+
TCPSocket.new('127.0.0.1', FocusedController::Test.port)
|
81
|
+
rescue Errno::ECONNREFUSED
|
82
|
+
else
|
83
|
+
started = true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
raise "Server failed to start:\n#{output}" unless started
|
88
|
+
|
89
|
+
yield
|
90
|
+
|
91
|
+
Process.kill('KILL', out.pid)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
before do
|
97
|
+
run_without_bundle_exec "bundle check >/dev/null || bundle update >/dev/null"
|
98
|
+
end
|
99
|
+
|
100
|
+
let(:s) { Capybara::Session.new(:poltergeist, nil) }
|
101
|
+
|
102
|
+
it 'does basic CRUD actions successfully' do
|
103
|
+
start_server do
|
104
|
+
s.visit '/posts'
|
105
|
+
|
106
|
+
s.click_link 'New Post'
|
107
|
+
s.fill_in 'Title', :with => 'Hello world'
|
108
|
+
s.fill_in 'Body', :with => 'Omg, first post'
|
109
|
+
s.click_button 'Create Post'
|
110
|
+
|
111
|
+
s.click_link 'Back'
|
112
|
+
s.must_have_content 'Hello world'
|
113
|
+
s.must_have_content 'Omg, first post'
|
114
|
+
|
115
|
+
s.click_link 'Show'
|
116
|
+
s.must_have_content 'Hello world'
|
117
|
+
s.must_have_content 'Omg, first post'
|
118
|
+
|
119
|
+
s.click_link 'Edit'
|
120
|
+
s.fill_in 'Title', :with => 'Goodbye world'
|
121
|
+
s.fill_in 'Body', :with => 'Omg, edited'
|
122
|
+
s.click_button 'Update Post'
|
123
|
+
s.must_have_content 'Goodbye world'
|
124
|
+
s.must_have_content 'Omg, edited'
|
125
|
+
|
126
|
+
s.click_link 'Back'
|
127
|
+
s.click_link 'Destroy'
|
128
|
+
s.wont_have_content 'Goodbye world'
|
129
|
+
s.wont_have_content 'Omg, edited'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'runs a functional test' do
|
134
|
+
run_command "ruby -Itest test/functional/posts_controller_test.rb"
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'runs a unit test' do
|
138
|
+
run_command "ruby -Itest test/unit/controllers/posts_controller_test.rb"
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'runs an isolated unit test' do
|
142
|
+
run_command "ruby -Itest test/unit/controllers/posts_controller_isolated_test.rb"
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'runs a functional spec' do
|
146
|
+
run_command "rspec spec/controllers/posts_controller_spec.rb"
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'runs a unit spec' do
|
150
|
+
run_command "rspec spec/unit/controllers/posts_controller_spec.rb"
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'runs an isolated unit spec' do
|
154
|
+
run_command "rspec spec/unit/controllers/posts_controller_isolated_spec.rb"
|
155
|
+
end
|
156
|
+
end
|
data/spec/app/.gitignore
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
6
|
+
|
7
|
+
# Ignore bundler config
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
12
|
+
|
13
|
+
# Ignore all logfiles and tempfiles.
|
14
|
+
/log/*.log
|
15
|
+
/tmp
|