-
Notifications
You must be signed in to change notification settings - Fork 644
/
GBTemplateFilesHandler.m
154 lines (127 loc) · 5.77 KB
/
GBTemplateFilesHandler.m
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
153
154
//
// GBTemplateFilesHandler.m
// appledoc
//
// Created by Tomaz Kragelj on 10.2.11.
// Copyright 2011 Gentle Bytes. All rights reserved.
//
#import "GBTemplateHandler.h"
#import "GBTemplateFilesHandler.h"
@interface GBTemplateFilesHandler ()
- (BOOL)isPathRepresentingTemplateFile:(NSString *)path;
- (BOOL)isPathRepresentingIgnoredFile:(NSString *)path;
- (GBTemplateHandler *)templateHandlerFromTemplateFile:(NSString *)filename error:(NSError **)error;
@end
#pragma mark -
@implementation GBTemplateFilesHandler
#pragma mark Initialization & disposal
- (id)init {
self = [super init];
if (self) {
self.templateFiles = [NSMutableDictionary dictionary];
}
return self;
}
#pragma mark Template files handling
- (BOOL)copyTemplateFilesToOutputPath:(NSError **)error {
// Remove all previous template files.
[self.templateFiles removeAllObjects];
// Prepare source and destination paths.
NSString *sourceUserPath = self.templateUserPath;
NSString *destUserPath = self.outputUserPath;
NSString *sourcePath = [sourceUserPath stringByStandardizingPath];
NSString *destPath = [destUserPath stringByStandardizingPath];
GBLogVerbose(@"Copying template files from '%@' to '%@'...", sourceUserPath, destUserPath);
// Remove destination path if it exists. Exit if we fail.
if ([self.fileManager fileExistsAtPath:destPath]) {
GBLogDebug(@"Removing output at '%@'...", destUserPath);
if (![self.fileManager removeItemAtPath:destPath error:error]) {
GBLogWarn(@"Failed removing output files at '%@'!", destUserPath);
return NO;
}
}
// Create directory hierarchy minus the last one. This is necessary if more than one component is missing at destination path; copyItemAtPath:toPath:error would fail in such case. Note that we can't create the last directory as mentioned method request is that the destination doesn't exist!
NSString *createDestPath = [destPath stringByDeletingLastPathComponent];
if (![self.fileManager createDirectoryAtPath:createDestPath withIntermediateDirectories:YES attributes:nil error:error]) {
GBLogWarn(@"Failed creating directory '%@'!", createDestPath);
return NO;
}
// If there's no source file, there also no need to copy anything, so exit. In fact, copying would probably just result in errors.
if (![self.fileManager fileExistsAtPath:sourcePath]) {
GBLogDebug(@"No template file found at '%@', no need to copy.", sourceUserPath);
return YES;
}
// Copy the whole source directory over to output. Exit if we fail.
GBLogDebug(@"Copying template files from '%@' to '%@'...", sourceUserPath, destUserPath);
if (![self.fileManager copyItemAtPath:sourcePath toPath:destPath error:error]) {
GBLogWarn(@"Failed copying templates from '%@' to '%@'!", sourceUserPath, destUserPath);
return NO;
}
// Remove all ignored files and special template items from output. First enumerate all files. If this fails, report success; this step is only used to verscleanup the destination, we should still have valid output if these files are kept there. Note that we need to test for existing file before removing as it could happen file's parent dir was removed already in previous iterations so the file or subdir doesn't exist anymore - see https://github.com/tomaz/appledoc/issues#issue/59 for details.
GBLogDebug(@"Removing temporary files from '%@'...", destUserPath);
NSArray *items = [self.fileManager subpathsOfDirectoryAtPath:destPath error:error];
if (!items) {
GBLogWarn(@"Failed enumerating template files at '%@'!", destUserPath);
return YES;
}
for (NSString *path in items) {
BOOL delete = NO;
if ([self isPathRepresentingIgnoredFile:path]) {
GBLogDebug(@"Removing ignored file '%@' from output...", path);
delete = YES;
} else if ([self isPathRepresentingTemplateFile:path]) {
GBTemplateHandler *handler = [self templateHandlerFromTemplateFile:path error:error];
if (!handler) return NO;
GBLogDebug(@"Removing template file '%@' from output...", path);
[self.templateFiles setObject:handler forKey:path];
delete = YES;
}
if (delete) {
NSString *fullpath = [destPath stringByAppendingPathComponent:path];
if ([self.fileManager fileExistsAtPath:fullpath] && ![self.fileManager removeItemAtPath:fullpath error:error]) {
GBLogWarn(@"Can't clean leftover '%@' from '%@'.", path, destUserPath);
}
}
}
return YES;
}
- (NSString *)templatePathForTemplateEndingWith:(NSString *)suffix {
for (NSString *template in [self.templateFiles allKeys]) {
if ([template hasSuffix:suffix]) return template;
}
return nil;
}
- (NSString *)outputPathToTemplateEndingWith:(NSString *)suffix {
NSString *template = [self templatePathForTemplateEndingWith:suffix];
if (template) {
NSString *path = [template substringToIndex:[template length] - [suffix length]];
return [self.outputUserPath stringByAppendingPathComponent:path];
}
return nil;
}
#pragma mark Helper methods
- (GBTemplateHandler *)templateHandlerFromTemplateFile:(NSString *)filename error:(NSError **)error {
NSString *path = [[self templateUserPath] stringByAppendingPathComponent:filename];
GBLogDebug(@"Creating template handler for template file '%@'...", path);
GBTemplateHandler *result = [GBTemplateHandler handler];
if (![result parseTemplateFromPath:[path stringByStandardizingPath] error:error]) {
GBLogWarn(@"Failed parsing template '%@'!", filename);
return nil;
}
return result;
}
- (BOOL)isPathRepresentingTemplateFile:(NSString *)path {
NSString *filename = [[path lastPathComponent] stringByDeletingPathExtension];
if ([filename hasSuffix:@"-template"]) return YES;
return NO;
}
- (BOOL)isPathRepresentingIgnoredFile:(NSString *)path {
NSString *filename = [path lastPathComponent];
if ([filename hasPrefix:@"."]) return YES;
return NO;
}
#pragma mark Properties
@synthesize templateFiles;
@synthesize templateUserPath;
@synthesize outputUserPath;
@end