Compare commits

...
14 Commits
Author SHA1 Message Date
Tom Robinson f90e98baaa Only enable debug logger in browsers, not command line utilities. 2010-03-31 17:29:09 -07:00
Francisco Ryan Tolmasky I 6d150e6609 Fix for menu bar being broken if displayed after a window is ordered front in IE.
Reviewed by me.
2010-03-31 17:08:05 -07:00
Paul BaumgartandTom Robinson 222900aa2a Add some dependency checking to bootstrap.sh: make sure correct JVM is
being used and ensure other dependencies are installed and on the $PATH.
2010-03-31 15:02:17 -07:00
Tom Robinson 0e18551500 Use "CommonJS" task as the dependency for "test" task for now. 2010-03-31 13:52:17 -07:00
Randall Luecke 3ec5c2fc6c Made drag feedback view in the tableview more correct, fixed encoding issues. 2010-03-31 16:06:35 -04:00
Ross Boucher 2e6061a5f3 Fix for a potential error in IE when setting a width to a negative value. 2010-03-31 11:09:14 -07:00
Francisco Ryan Tolmasky I f67dfd85ef Fix for loading Cappuccino apps locally on Windows.
Reviewed by me.
2010-03-30 16:30:45 -07:00
Tom Robinson 3712da3bba Enable default logger in debug frameworks. Add configurable options to index-debug.html. 2010-03-30 14:16:10 -07:00
Ross Boucher 862e8db063 Sprite images recursively. 2010-03-30 12:09:35 -07:00
Ross Boucher db13748e6c Revert "Add guard div to protect against iframes consuming events during tracking."
This reverts commit 0e4d476d76.
2010-03-30 10:59:53 -07:00
Ross Boucher 77a648db94 Fix a nil variable error that caused problems in Firefox 2. 2010-03-30 10:58:54 -07:00
Francisco Ryan Tolmasky I e3cb8c4264 One more fix for image spriting.
Reviewed by me.
2010-03-30 00:46:01 -07:00
Francisco Ryan Tolmasky I 83fade3b29 Fail more gracefully when main cib is not found.
Reviewed by me.
2010-03-29 23:28:48 -07:00
Randall Luecke f9a111bfec Fixed nib2cib bug with cornerview where resources were not loaded from the correct location. 2010-03-30 01:42:24 -04:00
27 changed files with 191 additions and 80 deletions
+5
View File
@@ -1224,6 +1224,11 @@ var _CPAppBootstrapperActions = nil;
[self performActions];
}
+ (void)cibDidFailToLoad:(CPCib)aCib
{
throw new Error("Could not load main cib file (Did you forget to nib2cib it?).");
}
+ (void)reset
{
_CPAppBootstrapperActions = nil;
+2 -2
View File
@@ -227,8 +227,8 @@ var SelectionColor = nil,
CGContextClosePath(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor);
CGContextSetFillColor(context, _color);
CGContextSetShadowWithColor(context, CGSizeMake(0.0, 1.0), 1.1, _shadowColor || [CPColor whiteColor]);
CGContextSetFillColor(context, _color || [CPColor blackColor]);
CGContextFillPath(context);
}
+9 -10
View File
@@ -261,14 +261,14 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
[_headerView setTableView:self];
_cornerView = [[_CPCornerView alloc] initWithFrame:CGRectMake(0, 0, [CPScroller scrollerWidth], CGRectGetHeight([_headerView frame]))];
_lastSelectedRow = -1;
_selectedColumnIndexes = [CPIndexSet indexSet];
_selectedRowIndexes = [CPIndexSet indexSet];
_currentHighlightedTableColumn = nil;
_sortDescriptors = [CPArray array];
_draggedRowIndexes = [CPIndexSet indexSet];
_verticalMotionCanDrag = YES;
_isSelectingSession = NO;
@@ -276,10 +276,6 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil;
_dragOperationDefaultMask = nil;
_destinationDragStyle = CPTableViewDraggingDestinationFeedbackStyleRegular;
_dropOperationFeedbackView = [[_dropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()];
[self addSubview:_dropOperationFeedbackView];
[_dropOperationFeedbackView setHidden:YES];
[_dropOperationFeedbackView setTableView:self];
_tableDrawView = [[_CPTableDrawView alloc] initWithTableView:self];
[_tableDrawView setBackgroundColor:[CPColor clearColor]];
@@ -294,6 +290,9 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
// FIX ME: we have a lot of redundent init stuff in initWithFrame: and initWithCoder: we should move it all into here.
- (void)_init
{
_dropOperationFeedbackView = [[_dropOperationDrawingView alloc] initWithFrame:_CGRectMakeZero()];
[_dropOperationFeedbackView setTableView:self];
_lastColumnShouldSnap = NO;
_backgroundColor = [CPColor whiteColor];
@@ -2757,7 +2756,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
*/
- (void)draggingExited:(id)sender
{
[_dropOperationFeedbackView setHidden:YES];
[_dropOperationFeedbackView removeFromSuperview];
}
/*
@@ -2773,7 +2772,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
_retargetedDropOperation = nil;
_retargetedDropRow = nil;
_draggedRowIndexes = [CPIndexSet indexSet];
[_dropOperationFeedbackView setHidden:YES];
[_dropOperationFeedbackView removeFromSuperview];
}
/*
@ignore
@@ -2906,7 +2905,7 @@ CPTableViewFirstColumnOnlyAutoresizingStyle = 5;
{
// FIX ME: is there anything else that needs to happen here?
// actual validation is called in dragginUpdated:
[_dropOperationFeedbackView setHidden:YES];
[_dropOperationFeedbackView removeFromSuperview];
return (_implementedDataSourceMethods & CPTableViewDataSource_tableView_validateDrop_proposedRow_proposedDropOperation_);
}
+6 -1
View File
@@ -171,12 +171,17 @@ var CPCibObjectDataKey = @"CPCibObjectDataKey";
- (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
{
// FIXME: Why aren't we getting connection:didFailWithError:
if (!data)
return [self connection:aConnection didFailWithError:nil];
_data = [CPData dataWithRawString:data];
}
- (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
{
alert("cib: connection failed.");
if ([_loadDelegate respondsToSelector:@selector(cibDidFailToLoad:)])
[_loadDelegate cibDidFailToLoad:self];
_loadDelegate = nil;
}
+5
View File
@@ -118,4 +118,9 @@ var CPCibOwner = @"CPCibOwner";
[_loadDelegate cibDidFinishLoading:aCib];
}
- (void)cibDidFailToLoad:(CPCib)aCib
{
[_loadDelegate cibDidFailToLoad:aCib];
}
@end
+4 -3
View File
@@ -40,6 +40,10 @@ var screenNeedsInitialization = NO,
return;
screenNeedsInitialization = [CPPlatform isBrowser];
// We do this here because doing it later breaks IE.
if (document.documentElement)
document.documentElement.style.overflow = "hidden";
}
+ (BOOL)isBrowser
@@ -121,9 +125,6 @@ var screenNeedsInitialization = NO,
bodyElement.style.overflow = "hidden";
if (document.documentElement)
document.documentElement.style.overflow = "hidden";
[[CPNotificationCenter defaultCenter]
postNotificationName:CPPlatformDidClearBodyElementNotification
object:self];
@@ -129,8 +129,6 @@ var CPDOMEventGetClickCount,
CPDOMEventStop,
StopDOMEventPropagation;
var _DOMEventGuard;
//right now we hard code q, w, r and t as keys to propogate
//these aren't normal keycodes, they are with modifier key codes
//might be mac only, we should investigate futher later.
@@ -257,19 +255,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
// Make sure the pastboard element is blurred.
_DOMPasteboardElement.blur();
// Create a full screen div to protect against iframes and other elements from consuming events during tracking
// FIXME: multiple windows
_DOMEventGuard = theDocument.createElement("div");
_DOMEventGuard.style.position = "absolute";
_DOMEventGuard.style.top = "0px";
_DOMEventGuard.style.left = "0px";
_DOMEventGuard.style.width = "100%";
_DOMEventGuard.style.height = "100%";
_DOMEventGuard.style.zIndex = "999";
_DOMEventGuard.style.display = "none";
_DOMEventGuard.className = "cpdontremove";
_DOMBodyElement.appendChild(_DOMEventGuard);
}
- (void)registerDOMWindow
@@ -1116,9 +1101,6 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop];
if (StopDOMEventPropagation && (!supportsNativeDragAndDrop || type !== "mousedown" && !isDragging))
CPDOMEventStop(aDOMEvent, self);
// if there are any tracking event listeners then show the event guard so we don't lose events to iframes
_DOMEventGuard.style.display = (CPApp._eventListeners.length === 0) ? "none" : "";
[[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
}
+20 -8
View File
@@ -5,13 +5,18 @@
{
}
- (void)_init
{
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]];
}
- (id)initWithFrame:(CGRect)aFrame
{
if (self = [super initWithFrame:aFrame])
{
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]];
[self _init];
}
return self;
}
@@ -20,16 +25,23 @@
var context = [[CPGraphicsContext currentContext] graphicsPort];
CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"dce0e2"]);
var points = [
CGPointMake(aRect.origin.x, aRect.origin.y),
CGPointMake(aRect.origin.x + aRect.size.width, aRect.origin.y),
var points = [
CGPointMake(aRect.origin.x, aRect.origin.y + 0.5),
CGPointMake(aRect.origin.x, aRect.origin.y + aRect.size.height)
];
CGContextStrokeLineSegments(context, points, 2);
}
- (id)initWithCoder:(CPCoder)aCoder
{
self = [super initWithCoder:aCoder];
{
[self _init];
}
return self;
}
@end
+7 -7
View File
@@ -574,8 +574,8 @@ var HORIZONTAL_MARGIN = 3.0,
_DOMImageElement.width = imageWidth;
_DOMImageElement.height = imageHeight;
imageStyle.width = imageWidth + "px";
imageStyle.height = imageHeight + "px";
imageStyle.width = MAX(imageWidth, 0) + "px";
imageStyle.height = MAX(imageHeight, 0) + "px";
if (_imagePosition === CPImageBelow)
{
@@ -619,7 +619,7 @@ var HORIZONTAL_MARGIN = 3.0,
textRectY = _CGRectGetMinY(textRect),
textRectWidth = _CGRectGetWidth(textRect),
textRectHeight = _CGRectGetHeight(textRect);
if (_verticalAlignment !== CPTopVerticalTextAlignment)
{
if (!_textSize)
@@ -646,8 +646,8 @@ var HORIZONTAL_MARGIN = 3.0,
textStyle.top = ROUND(textRectY) + "px";
textStyle.left = ROUND(textRectX) + "px";
textStyle.width = ROUND(textRectWidth) + "px";
textStyle.height = ROUND(textRectHeight) + "px";
textStyle.width = MAX(ROUND(textRectWidth), 0) + "px";
textStyle.height = MAX(ROUND(textRectHeight), 0) + "px";
if (shadowStyle)
{
@@ -656,8 +656,8 @@ var HORIZONTAL_MARGIN = 3.0,
shadowStyle.top = ROUND(textRectY + _textShadowOffset.height) + "px";
shadowStyle.left = ROUND(textRectX + _textShadowOffset.width) + "px";
shadowStyle.width = ROUND(textRectWidth) + "px";
shadowStyle.height = ROUND(textRectHeight) + "px";
shadowStyle.width = MAX(ROUND(textRectWidth), 0) + "px";
shadowStyle.height = MAX(ROUND(textRectHeight), 0) + "px";
}
}
#endif
+8 -2
View File
@@ -163,9 +163,15 @@ var CPArrayClass = Ni
@param data the data from which to read the graph
@return the unarchived object
*/
+ (id)unarchiveObjectWithData:(CPData)data
+ (id)unarchiveObjectWithData:(CPData)aData
{
var unarchiver = [[self alloc] initForReadingWithData:data],
if (!aData)
{
CPLog.error("Null data passed to -[CPKeyedUnarchiver unarchiveObjectWithData:].");
return nil;
}
var unarchiver = [[self alloc] initForReadingWithData:aData],
object = [unarchiver decodeObjectForKey:@"root"];
[unarchiver finishDecoding];
+1 -1
View File
@@ -247,7 +247,7 @@ task ("demos", function()
// Testing
task("test", ["build", "test-only"]);
task("test", ["CommonJS", "test-only"]);
task("test-only", function()
{
+25 -7
View File
@@ -314,7 +314,7 @@ function resolveURL(aURL)
resolvedPathComponents.splice(basePathComponents.length - 1, 1);
// If this doesn't start with a "..", then we're simply appending to already standardized paths.
if (pathComponents.length && pathComponents[0] === "..")
if (pathComponents.length && (pathComponents[0] === ".." || pathComponents[0] === "."))
standardizePathComponents(resolvedPathComponents, YES);
resolvedParts.pathComponents = resolvedPathComponents;
@@ -352,19 +352,26 @@ function standardizePathComponents(/*Array*/ pathComponents, /*BOOL*/ inPlace)
var index = 0,
resultIndex = 0,
count = pathComponents.length,
result = inPlace ? pathComponents : [];
result = inPlace ? pathComponents : [],
startsWithPeriod = NO;
for (; index < count; ++index)
{
var component = pathComponents[index];
if (component === "" || component === ".")
if (component === "")
continue;
if (component === ".")
{
startsWithPeriod = resultIndex === 0;
continue;
}
if (component !== ".." || resultIndex === 0 || result[resultIndex - 1] === "..")
{
//if (resultIndex !== index)
result[resultIndex] = component;
result[resultIndex] = component;
resultIndex++;
@@ -375,6 +382,9 @@ function standardizePathComponents(/*Array*/ pathComponents, /*BOOL*/ inPlace)
--resultIndex;
}
if (startsWithPeriod && resultIndex === 0)
result[resultIndex++] = ".";
result.length = resultIndex;
return result;
@@ -505,10 +515,11 @@ CFURL.prototype.hasDirectoryPath = function()
var lastPathComponent = this.lastPathComponent();
hasDirectoryPath = lastPathComponent === "." || lastPathComponent === "..";
this._hasDirectoryPath = hasDirectoryPath;
}
return this._hasDirectoryPath;
return hasDirectoryPath;
}
DISPLAY_NAME(CFURL.prototype.hasDirectoryPath);
@@ -646,7 +657,14 @@ CFURL.prototype.asDirectoryPathURL = function()
if (this.hasDirectoryPath())
return this;
return new CFURL(this.lastPathComponent() + "/", this);
var lastPathComponent = this.lastPathComponent();
// We do this because on Windows the path may start with C: and be
// misinterpreted as a scheme.
if (lastPathComponent !== "/")
lastPathComponent = "./" + lastPathComponent;
return new CFURL(lastPathComponent + "/", this);
}
DISPLAY_NAME(CFURL.prototype.asDirectoryPathURL);
+7
View File
@@ -357,3 +357,10 @@ function _CPLogInitPopup(logWindow)
}, false);
}
#endif
#if COMMONJS
CPLogDefault = CPLogPrint;
#else
CPLogDefault = (typeof window === "object" && window.console) ? CPLogConsole : CPLogPopup;
#endif
@@ -16,8 +16,7 @@ var Task = Jake.Task,
function isImage(/*String*/ aFilename)
{
return FILE.isFile(aFilename) &&
UTIL.has([".png", ".jpg", ".jpeg", ".gif", ".tif", ".tiff"], FILE.extension(aFilename).toLowerCase());
return UTIL.has([".png", ".jpg", ".jpeg", ".gif", ".tif", ".tiff"], FILE.extension(aFilename).toLowerCase());
}
function mimeType(/*String*/ aFilename)
@@ -350,11 +349,6 @@ BundleTask.prototype.packageType = function()
return 1;
}
function isDataResource(aFilename)
{
return FILE.isFile(aFilename) && isImage(aFilename);
}
BundleTask.prototype.infoPlist = function()
{
var infoPlistPath = this.infoPlistPath();
@@ -379,7 +373,7 @@ BundleTask.prototype.infoPlist = function()
var environmentsWithImageSprites = this.environments().filter(
function(anEnvironment)
{
return anEnvironment.spritesImages() && task(this.buildProductDataURLPathForEnvironment(anEnvironment)).prerequisites().filter(isDataResource).length > 0;
return anEnvironment.spritesImages() && task(this.buildProductDataURLPathForEnvironment(anEnvironment)).prerequisites().filter(isImage).length > 0;
}, this).map(function(anEnvironment)
{
return anEnvironment.name();
@@ -607,7 +601,7 @@ BundleTask.prototype.defineSpritedImagesTask = function()
filedir (dataURLPath, function(aTask)
{
var prerequisites = aTask.prerequisites().filter(isDataResource);
var prerequisites = aTask.prerequisites().filter(isImage);
if (!prerequisites.length)
{
@@ -645,7 +639,7 @@ BundleTask.prototype.defineSpritedImagesTask = function()
filedir (MHTMLPath, function(aTask)
{
var prerequisites = aTask.prerequisites().filter(isDataResource);
var prerequisites = aTask.prerequisites().filter(isImage);
if (!prerequisites.length)
{
@@ -679,7 +673,7 @@ BundleTask.prototype.defineSpritedImagesTask = function()
filedir (MHTMLDataPath, function(aTask)
{
var prerequisites = aTask.prerequisites().filter(isDataResource);
var prerequisites = aTask.prerequisites().filter(isImage);
if (!prerequisites.length)
{
+4
View File
@@ -20,6 +20,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef BROWSER
CPLogRegister(CPLogDefault);
#endif
// formatting helpers
function objj_debug_object_format(aReceiver)
+7 -1
View File
@@ -143,8 +143,14 @@ StaticResource.resourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*/ resolveA
resource = resource._children[name];
else if (resolveAsDirectoriesIfNecessary)
resource = new StaticResource(new CFURL(name, resource.URL()), resource, YES, YES);
{
// We do this because on Windows the path may start with C: and be
// misinterpreted as a scheme.
if (name !== "/")
name = "./" + name;
resource = new StaticResource(new CFURL(name, resource.URL()), resource, YES, YES);
}
else
throw new Error("Static Resource at " + aURL + " is not resolved (\"" + name + "\")");
}
+29
View File
@@ -60,4 +60,33 @@
}
}
- (void)testPeriods
{
var URLStrings =
{
"." : "./",
"./" : "./",
".//" : "./",
"/." : "/",
"/./" : "/",
"/.//" : "/",
"./a/" : "a/",
"./a" : "a",
".." : "../",
"../" : "../",
"..//" : "../",
"/.." : "/",
"/../" : "/",
"/..//" : "/",
"../a/" : "../a/",
"../a" : "../a"
};
var URLString;
for (URLString in URLStrings)
if (URLStrings.hasOwnProperty(URLString))
[self assert:new CFURL(URLString).absoluteString() equals:URLStrings[URLString]];
}
@end
@@ -27,7 +27,7 @@ app ("__project.nameasidentifier__", function(task)
task.setEmail("__organization.email__");
task.setSummary("__project.name__");
task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**")));
task.setResources(new FileList("Resources/*"));
task.setResources(new FileList("Resources/**"));
task.setIndexFilePath("index.html");
task.setInfoPlistPath("Info.plist");
@@ -35,6 +35,13 @@
// Uncomment (along with both above) to print backtraces on type check errors:
//objj_typecheck_prints_backtrace = true;
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
//CPLogUnregister(CPLogDefault);
// Uncomment to enable a specific logger:
//CPLogRegister(CPLogConsole);
//CPLogRegister(CPLogPopup);
</script>
<style type="text/css">
@@ -19,7 +19,7 @@
OBJJ_MAIN_FILE = "main.j";
</script>
<script src="Frameworks/Objective-J/Objective-J.js" type = "text/javascript"></script>
<script src="Frameworks/Objective-J/Objective-J.js" type="text/javascript"></script>
<style type="text/css">
body{margin:0; padding:0;}
@@ -27,7 +27,7 @@ app ("__project.nameasidentifier__", function(task)
task.setEmail("__organization.email__");
task.setSummary("__project.name__");
task.setSources((new FileList("**/*.j")).exclude(FILE.join("Build", "**")));
task.setResources(new FileList("Resources/*"));
task.setResources(new FileList("Resources/**"));
task.setIndexFilePath("index.html");
task.setInfoPlistPath("Info.plist");
task.setNib2CibFlags("-R Resources/");
@@ -20,7 +20,7 @@
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
</script>
<script src="Frameworks/Debug/Objective-J/Objective-J.js" type = "text/javascript"></script>
<script src="Frameworks/Debug/Objective-J/Objective-J.js" type="text/javascript"></script>
<script type="text/javascript">
objj_msgSend_reset();
@@ -35,6 +35,13 @@
// Uncomment (along with both above) to print backtraces on type check errors:
//objj_typecheck_prints_backtrace = true;
// Uncomment to disable the default logger (CPLogConsole if window.console exists, CPLogPopup otherwise):
//CPLogUnregister(CPLogDefault);
// Uncomment to enable a specific logger:
//CPLogRegister(CPLogConsole);
//CPLogRegister(CPLogPopup);
</script>
<style type="text/css">
@@ -19,7 +19,7 @@
OBJJ_MAIN_FILE = "main.j";
</script>
<script src="Frameworks/Objective-J/Objective-J.js" type = "text/javascript"></script>
<script src="Frameworks/Objective-J/Objective-J.js" type="text/javascript"></script>
<style type="text/css">
body{margin:0; padding:0;}
@@ -20,7 +20,7 @@
OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
</script>
<script src="Frameworks/Debug/Objective-J/Objective-J.js" type = "text/javascript"></script>
<script src="Frameworks/Debug/Objective-J/Objective-J.js" type="text/javascript"></script>
<style type="text/css">
body{margin:0; padding:0;}
@@ -19,7 +19,7 @@
OBJJ_MAIN_FILE = "main.j";
</script>
<script src="Frameworks/Objective-J/Objective-J.js" type = "text/javascript"></script>
<script src="Frameworks/Objective-J/Objective-J.js" type="text/javascript"></script>
<style type="text/css">
body{margin:0; padding:0;}
-2
View File
@@ -40,8 +40,6 @@
self = [super NS_initWithCoder:aCoder];
if (self)
{
[self setBackgroundColor:[CPColor colorWithPatternImage:CPAppKitImage("tableview-headerview.png", CGSizeMake(1.0, 23.0))]];
_frame.size.height = 23.0;
_bounds.size.height = 23.0;
}
+26
View File
@@ -78,6 +78,32 @@ function check_and_exit () {
fi
}
function check_build_environment () {
# make sure user is running HotSpot JVM
java -version 2>&1 | grep HotSpot &> /dev/null
if [ ! "$?" = "0" ]; then
java_ver=`java -version 2>&1 | egrep "(Client|Server)"`
if [ "$java_ver" = "" ]; then
java_ver="your JVM"
fi
echo "Error: Narwhal is not compatible with $java_ver. Please switch to the Sun (HotSpot) JVM and re-run bootstrap.sh."
exit 1
fi
# make sure other dependencies are installed and on the $PATH
OTHER_DEPS=(gcc unzip curl)
for dep in ${OTHER_DEPS[@]}; do
which "$dep" &> /dev/null
if [ ! "$?" = "0" ]; then
echo "Error: $dep is required to build Cappuccino. Please install $dep and re-run bootstrap.sh."
exit 1
fi
done
}
check_build_environment
if [ -w "/usr/local" ]; then
default_directory="/usr/local/narwhal"
else