This repository has been archived by the owner on Jun 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 436
/
file_list.coffee
152 lines (133 loc) · 4.24 KB
/
file_list.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
'use strict'
debug = require('debug')('brunch:file-list')
{EventEmitter} = require 'events'
Asset = require './asset'
SourceFile = require './source_file'
helpers = require '../helpers'
sysPath = require 'path'
startsWith = (string, substring) ->
string.lastIndexOf(substring, 0) is 0
# A list of `fs_utils.SourceFile` or `fs_utils.Asset`
# with some additional methods used to simplify file reading / removing.
module.exports = class FileList extends EventEmitter
# Maximum time between changes of two files that will be considered
# as a one compilation.
resetTime: 65
constructor: (@config) ->
@files = []
@assets = []
@on 'change', @_change
@on 'unlink', @_unlink
@compiling = {}
@compiled = {}
@copying = {}
@initial = true
interval = @config.fileListInterval
@resetTime = interval if typeof interval is 'number'
getAssetErrors: ->
invalidAssets = @assets.filter((asset) -> asset.error?)
if invalidAssets.length > 0
invalidAssets.map (invalidAsset) ->
helpers.formatError invalidAsset.error, invalidAsset.path
else
null
# Files that are not really app files.
isIgnored: (path, test = @config.conventions.ignored) ->
return true if path in @config._normalized.paths.allConfigFiles
switch toString.call(test)
when '[object RegExp]'
path.match test
when '[object Function]'
test path
when '[object String]'
startsWith sysPath.normalize(path), sysPath.normalize(test)
when '[object Array]'
test.some((subTest) => @isIgnored path, subTest)
else
false
is: (name, path) ->
convention = @config._normalized.conventions[name]
return false unless convention
if typeof convention isnt 'function'
throw new TypeError "Invalid convention #{convention}"
convention path
# Called every time any file was changed.
# Emits `ready` event after `resetTime`.
resetTimer: =>
clearTimeout @timer if @timer?
@timer = setTimeout =>
# Clean disposed files.
@files = @files.filter (file) => not file.disposed
if Object.keys(@compiling).length is 0 and Object.keys(@copying).length is 0
@emit 'ready'
@compiled = {}
else
@resetTimer()
, @resetTime
find: (path) ->
@files.filter((file) -> file.path is path)[0]
findAsset: (path) ->
@assets.filter((file) -> file.path is path)[0]
compileDependencyParents: (path) ->
debug "Compiling dependency '#{path}' parent(s)"
@files
.filter (dependent) =>
dependent.dependencies.length > 0
.filter (dependent) =>
path in dependent.dependencies
.filter (dependent) =>
not @compiled[dependent.path]
.forEach(@compile)
compile: (file) =>
path = file.path
if @compiling[path]
@resetTimer()
else
@compiling[path] = true
file.compile (error) =>
delete @compiling[path]
@resetTimer()
return if error?
debug "Compiled file '#{path}'..."
@compiled[path] = true
@emit 'compiled', path
copy: (asset) =>
path = asset.path
@copying[path] = true
asset.copy (error) =>
delete @copying[path]
@resetTimer()
return if error?
debug "Copied asset '#{path}'"
_add: (path, compiler, linters, isHelper) ->
isVendor = @is 'vendor', path
wrapper = @config._normalized.modules.wrapper
file = new SourceFile path, compiler, linters, wrapper, isHelper, isVendor
@files.push file
file
_addAsset: (path) ->
file = new Asset path, @config
@assets.push file
file
_change: (path, compiler, linters, isHelper) =>
ignored = @isIgnored path
if @is 'assets', path
unless ignored
@copy (@findAsset(path) ? @_addAsset path)
else
if ignored or not compiler?.length
@compileDependencyParents path unless @initial
else
@compile (@find(path) ? @_add path, compiler, linters, isHelper)
_unlink: (path) =>
ignored = @isIgnored path
if @is 'assets', path
unless ignored
@assets.splice(@assets.indexOf(path), 1)
else
if ignored
@compileDependencyParents path
else
file = @find path
file.removed = true if file and not file.disposed
@resetTimer()