|
@@ -4,15 +4,19 @@ import org.cobbzilla.util.io.FileUtil; |
|
|
import org.cobbzilla.util.io.FilesystemWalker; |
|
|
import org.cobbzilla.util.io.FilesystemWalker; |
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
import java.io.File; |
|
|
import java.util.Arrays; |
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
import java.util.Objects; |
|
|
|
|
|
|
|
|
import java.util.*; |
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
import java.util.regex.Matcher; |
|
|
import java.util.regex.Matcher; |
|
|
|
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
|
|
|
|
import static org.cobbzilla.util.daemon.ZillaRuntime.empty; |
|
|
|
|
|
import static org.cobbzilla.util.daemon.ZillaRuntime.shortError; |
|
|
import static org.cobbzilla.util.io.FileUtil.*; |
|
|
import static org.cobbzilla.util.io.FileUtil.*; |
|
|
|
|
|
|
|
|
public class FileHeaderMain extends BaseMain<FileHeaderOptions> { |
|
|
public class FileHeaderMain extends BaseMain<FileHeaderOptions> { |
|
|
|
|
|
|
|
|
|
|
|
public static final String FILE_HEADER_IGNORE = ".file_header_ignore"; |
|
|
|
|
|
|
|
|
public static void main (String[] args) { main(FileHeaderMain.class, args); } |
|
|
public static void main (String[] args) { main(FileHeaderMain.class, args); } |
|
|
|
|
|
|
|
|
@Override protected void run() throws Exception { |
|
|
@Override protected void run() throws Exception { |
|
@@ -38,6 +42,10 @@ public class FileHeaderMain extends BaseMain<FileHeaderOptions> { |
|
|
err("skipping non-file: "+abs(file)); |
|
|
err("skipping non-file: "+abs(file)); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
if (isIgnored(file)) { |
|
|
|
|
|
err("skipping ignored file: "+abs(file)); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
final String ext = FileUtil.extension(file); |
|
|
final String ext = FileUtil.extension(file); |
|
|
final FileHeader header = headers.get(ext.length() > 0 ? ext.substring(1) : ext); |
|
|
final FileHeader header = headers.get(ext.length() > 0 ? ext.substring(1) : ext); |
|
|
if (header != null) { |
|
|
if (header != null) { |
|
@@ -69,4 +77,36 @@ public class FileHeaderMain extends BaseMain<FileHeaderOptions> { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private final Map<String, List<Pattern>> ignoreFileCache = new ConcurrentHashMap<>(100); |
|
|
|
|
|
|
|
|
|
|
|
private boolean isIgnored(File file) { |
|
|
|
|
|
final File dir = file.getParentFile(); |
|
|
|
|
|
final File ignoreFile = new File(dir, FILE_HEADER_IGNORE); |
|
|
|
|
|
if (ignoreFile.exists()) { |
|
|
|
|
|
final List<Pattern> patterns = ignoreFileCache.computeIfAbsent(abs(dir), k -> { |
|
|
|
|
|
final List<String> regexes; |
|
|
|
|
|
try { |
|
|
|
|
|
regexes = FileUtil.toStringList(ignoreFile); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
err("isIgnored: error reading "+abs(ignoreFile)+" (all files will be ignored): "+shortError(e)); |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
final List<Pattern> list = new ArrayList<>(); |
|
|
|
|
|
for (String regex : regexes) { |
|
|
|
|
|
regex = regex.trim(); |
|
|
|
|
|
if (empty(regex)) continue; |
|
|
|
|
|
try { |
|
|
|
|
|
list.add(Pattern.compile(regex)); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
err("isIgnored: skipping invalid regex in "+abs(ignoreFile)+": '"+regex+"': "+shortError(e)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return list; |
|
|
|
|
|
}); |
|
|
|
|
|
final String name = file.getName(); |
|
|
|
|
|
return patterns == null || patterns.isEmpty() || patterns.stream().anyMatch(p -> p.matcher(name).matches()); |
|
|
|
|
|
} |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |