You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by bi...@apache.org on 2012/12/19 09:50:14 UTC

svn commit: r1423796 - in /incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella: ./ src/ src/org/apacheflex/mustella/ src/org/apacheflex/mustella/oneclick/

Author: bigosmallm
Date: Wed Dec 19 08:50:09 2012
New Revision: 1423796

URL: http://svn.apache.org/viewvc?rev=1423796&view=rev
Log:
OneClickMustella can now:
1.  Run a webserver, listen on port 80 (or any other port you like)
2.  Open and run commands via terminal (Windows only for now)
3.  Invoke svn status to get a list of changed files
4.  Create the dependencyDB of classes
5   Generate changes.txt which contains the tests required to be run for the current set of files that have been changed
6.  Run the mini_run.bat with various options such as -all, -failures, -rerun, -changes, etc.  


This is just the first cut.  Lots of hacks, treat this as a POC.  More coming...

Added:
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/CommandTerminal.mxml   (with props)
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaDependencyDB.mxml   (with props)
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaTestChooser.mxml   (with props)
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/WebServer.mxml   (with props)
Modified:
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/   (props changed)
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella-app.xml
    incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella.mxml

Propchange: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Dec 19 08:50:09 2012
@@ -0,0 +1,5 @@
+.actionScriptProperties
+.flexProperties
+.project
+.settings
+bin-debug

Modified: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella-app.xml
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella-app.xml?rev=1423796&r1=1423795&r2=1423796&view=diff
==============================================================================
--- incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella-app.xml (original)
+++ incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella-app.xml Wed Dec 19 08:50:09 2012
@@ -116,6 +116,7 @@
 	<!-- (i.e., to only mobile devices) then add this element and list -->
 	<!-- only the profiles which your application does support. -->
 	<!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> -->
+	<supportedProfiles>extendedDesktop</supportedProfiles>
 
 	<!-- The subpath of the standard default installation location to use. Optional. -->
 	<!-- <installFolder></installFolder> -->

Modified: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella.mxml?rev=1423796&r1=1423795&r2=1423796&view=diff
==============================================================================
--- incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella.mxml (original)
+++ incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/OneClickMustella.mxml Wed Dec 19 08:50:09 2012
@@ -2,7 +2,7 @@
 <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
 					   xmlns:s="library://ns.adobe.com/flex/spark" 
 					   xmlns:mx="library://ns.adobe.com/flex/mx"
-					   xmlns:webserver="org.apacheflex.webserver.*"
+					   xmlns:oneclick="org.apacheflex.mustella.oneclick.*"
 					   creationComplete="windowedapplication1_creationCompleteHandler(event)"
 					   width="800"
 					   height="800" >
@@ -16,7 +16,8 @@
 			[Bindable] protected var _pathSVNStr:String;
 			[Bindable] protected var  _pathFlexStr:String;
 			[Bindable] protected var  _pathMustellaTestStr:String;
-			[Bindable] protected var  _pathShellStr:String;
+			[Bindable] protected var  _pathMustellaStr:String;
+			[Bindable] protected var  _shellPathStr:String;
 			
 			private const LSO_APACHE_FLEX_SDK:String = "LSO_APACHE_FLEX_SDK";
 			private const LSO_SVN:String = "LSO_SVN";
@@ -25,11 +26,10 @@
 			
 			protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
 			{
+				maximize();
 				if(so.data[LSO_APACHE_FLEX_SDK] != null)
 				{
-					_pathFlexStr = 	so.data[LSO_APACHE_FLEX_SDK];
-					_pathMustellaTestStr = _pathFlexStr + File.separator + "mustella" + File.separator + "tests";
-					webserver.setWebRoot(_pathMustellaTestStr);
+					setFlexSDKPaths(so.data[LSO_APACHE_FLEX_SDK]);
 				}
 				if(so.data[LSO_SVN] != null)
 				{
@@ -37,32 +37,50 @@
 				}
 				if(so.data[LSO_SHELL] != null)
 				{
-					_pathShellStr = 	so.data[LSO_SHELL];
+					_shellPathStr = 	so.data[LSO_SHELL];
+					terminal.shellPathStr = _shellPathStr;
 				}
 				
 			}
 			
+			protected function setFlexSDKPaths(path:String):void
+			{
+				_pathFlexStr = 	path;
+				_pathMustellaStr = _pathFlexStr + File.separator + "mustella";
+				_pathMustellaTestStr = _pathMustellaStr + File.separator + "tests";
+				webserver.setWebRoot(_pathMustellaTestStr);
+				dependencyDB.setMustellaDirectory(_pathMustellaStr);
+				testChooser.setMustellaDirectory(_pathMustellaStr);
+				terminal.pathFlexStr = _pathFlexStr;
+			}
+			
 			protected function handleSVNPathBrowse():void
 			{
-				openDirectoryForBrowse("Select SVN location", handleSVNPathSelect);
+				openBrowseForDirectory("Select SVN location", handleSVNPathSelect);
 			}
 			
 			protected function handleFlexPathBrowse():void
 			{
-				openDirectoryForBrowse("Select Apache Flex Directory", handleFlexPathSelect);
+				openBrowseForDirectory("Select Apache Flex Directory", handleFlexPathSelect);
 			}
-
+			
 			protected function handleShellPathBrowse():void
 			{
-				openDirectoryForBrowse("Select Apache Flex Directory", handleShellPathSelect);
+				openBrowseForFile("Select Shell Path", handleShellPathSelect);
 			}
 			
-			protected function openDirectoryForBrowse(title:String,resultFunction:Function):void{
+			protected function openBrowseForDirectory(title:String,resultFunction:Function):void{
 				var f:File = new File();
 				f.addEventListener(Event.SELECT,resultFunction);
 				f.browseForDirectory(title);
 			}
 			
+			protected function openBrowseForFile(title:String,resultFunction:Function):void{
+				var f:File = new File();
+				f.addEventListener(Event.SELECT,resultFunction);
+				f.browseForOpen(title);
+			}
+			
 			protected function handleSVNPathSelect(event:Event):void
 			{
 				_pathSVNStr = so.data[LSO_SVN] = event.target.nativePath;
@@ -70,33 +88,93 @@
 			
 			protected function handleFlexPathSelect(event:Event):void
 			{
-				_pathFlexStr = so.data[LSO_APACHE_FLEX_SDK] = event.target.nativePath;
-				_pathMustellaTestStr = _pathFlexStr + File.separator + "mustella" + File.separator + "tests";
-				webserver.setWebRoot(_pathMustellaTestStr);
+				setFlexSDKPaths(event.target.nativePath);
 			}
-
+			
 			protected function handleShellPathSelect(event:Event):void
 			{
-				_pathShellStr = so.data[LSO_SHELL] = event.target.nativePath;
+				_shellPathStr = so.data[LSO_SHELL] = event.target.nativePath;
+				terminal.shellPathStr = _shellPathStr;
+			}
+			
+			protected function handleRunAllBtnClick():void
+			{
+				terminal.run("./mini_run.sh -all");
+			}
+			
+			protected function handleRunFailuresBtnClick():void
+			{
+				terminal.cd(_pathMustellaStr);
+				terminal.run("./mini_run.sh -rerun");
 			}
 			
+			protected function handleRunOnlyChangesBtnClick():void
+			{
+				terminal.cd(_pathMustellaStr);
+				terminal.run("./mini_run.sh -changes");
+			}
+			
+			protected function handleStopBtnClick():void
+			{
+				terminal.stop();
+			}
+			
+			protected function dependencyDB_completeHandler(event:Event):void
+			{
+				
+			}
+			
+			protected function handleGetModifiedFilesBtnClick():void
+			{
+				terminal.getSVNStatus(handleSVNStatusResult);
+			}
+			
+			private var _svnStatus:String;
+			protected function handleSVNStatusResult(status:String):void
+			{
+				if(status.charAt(0) == "M" && status.charAt(1) == " ")
+				{
+					testChooser.setSVNStatus(status);
+				}
+			}
 			
 		]]>
 	</fx:Script>
 	<s:layout>
-		<s:VerticalLayout />
+		<s:HorizontalLayout />
 	</s:layout>
-	<s:HGroup verticalAlign="middle">
-		<s:Label text="SVN Path:" />
-		<s:TextInput id="svnPathTxtInput" width="500"
-					 text="{_pathSVNStr}"/>
-		<s:Button label="Browse" click="handleSVNPathBrowse()" />
-	</s:HGroup>
-	<s:HGroup verticalAlign="middle">
-		<s:Label text="Apache Flex SDK Path:" />
-		<s:TextInput id="flexPathTxtInput" width="500" 
-					 text="{_pathFlexStr}"/>
-		<s:Button label="Browse" click="handleFlexPathBrowse()" />
-	</s:HGroup>
-	<webserver:WebServer id="webserver" title="Web server" width="100%" height="100%" />
+	<s:VGroup width="50%" height="100%">
+		
+		<s:HGroup verticalAlign="middle">
+			<s:Label text="SVN Path:" />
+			<s:TextInput id="svnPathTxtInput" width="500"
+						 text="{_pathSVNStr}"/>
+			<s:Button label="Browse" click="handleSVNPathBrowse()" />
+		</s:HGroup>
+		<s:HGroup verticalAlign="middle">
+			<s:Label text="Apache Flex SDK Path:" />
+			<s:TextInput id="flexPathTxtInput" width="500" 
+						 text="{_pathFlexStr}"/>
+			<s:Button label="Browse" click="handleFlexPathBrowse()" />
+		</s:HGroup>
+		<s:HGroup verticalAlign="middle">
+			<s:Label text="Shell Path:" />
+			<s:TextInput id="shellPathTxtInput" width="500" 
+						 text="{_shellPathStr}"/>
+			<s:Button label="Browse" click="handleShellPathBrowse()" />
+		</s:HGroup>
+		<oneclick:WebServer id="webserver" title="Web server" width="100%" height="100%" />
+		<oneclick:MustellaDependencyDB id="dependencyDB" title="Dependency DB" width="100%" height="100%" complete="dependencyDB_completeHandler(event)" />
+		<oneclick:MustellaTestChooser id="testChooser" title="Test Chooser" width="100%" height="100%" />
+	</s:VGroup>
+	<s:VGroup width="50%" height="100%">
+		<s:HGroup width="100%">
+			<s:Button label="Run All" click="handleRunAllBtnClick()" />
+			<s:Button label="Run Failures" click="handleRunFailuresBtnClick()" />
+			<s:Button label="Get Modified Files" click="handleGetModifiedFilesBtnClick()" />
+			<s:Button label="Run only changes" click="handleRunOnlyChangesBtnClick()" />
+			<s:Button label="Stop" click="handleStopBtnClick()" />
+		</s:HGroup>
+		<oneclick:CommandTerminal id="terminal" width="100%" height="100%" />
+	</s:VGroup>
 </s:WindowedApplication>
\ No newline at end of file

Added: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/CommandTerminal.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/CommandTerminal.mxml?rev=1423796&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/CommandTerminal.mxml (added)
+++ incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/CommandTerminal.mxml Wed Dec 19 08:50:09 2012
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8"?>
+<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
+		 xmlns:s="library://ns.adobe.com/flex/spark" 
+		 xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
+	<fx:Declarations>
+		<!-- Place non-visual elements (e.g., services, value objects) here -->
+	</fx:Declarations>
+	<fx:Script>
+		<![CDATA[
+			private var _shellPathStr:String;
+			private var _shellPathStrChanged:Boolean;
+			private var _pathFlexStr:String;
+			private var _pathFlexStrChanged:Boolean;
+			private var _commandTerminal:File;
+			private var _nativeProcess:NativeProcess
+			private var _cygwinArg1:String = "/c";
+			private var _cygwinArg2:String = "C:\\cygwin\\Cygwin.bat";
+			private var _pipeOutputFunction:Function;
+			
+			public function get pathFlexStr():String
+			{
+				return _pathFlexStr;
+			}
+
+			public function set pathFlexStr(value:String):void
+			{
+				_pathFlexStr = value;
+				_pathFlexStrChanged = true;
+				invalidateProperties();
+			}
+
+			public function get shellPathStr():String
+			{
+				return _shellPathStr;
+			}
+			
+			public function set shellPathStr(value:String):void
+			{
+				_shellPathStr = value;
+				_shellPathStrChanged = true;
+				invalidateProperties();
+			}
+			
+			override protected function commitProperties():void
+			{
+				if(_shellPathStrChanged)
+				{
+					_shellPathStrChanged = false;
+					createCommandTerminal();
+				}
+				if(_pathFlexStrChanged)
+				{
+					_pathFlexStrChanged = false;
+					cd(_pathFlexStr);
+				}
+			}
+			
+			private function createCommandTerminal():void
+			{
+				_commandTerminal = new File(shellPathStr);
+				var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
+				
+				var arguments:Vector.<String> = new Vector.<String>();
+				arguments.push(_cygwinArg1);
+				arguments.push(_cygwinArg2);
+				startupInfo.arguments = arguments; 
+				
+				startupInfo.executable = _commandTerminal;
+				
+				_nativeProcess = new NativeProcess();
+				_nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, nativeProcessStdOutputData);
+				_nativeProcess.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, nativeProcessStdErrorData);
+				_nativeProcess.addEventListener(NativeProcessExitEvent.EXIT, nativeProcessExit); 
+				_nativeProcess.start(startupInfo);
+				cd(_shellPathStr);
+			}
+			
+			private function nativeProcessStdOutputData(e:ProgressEvent):void
+			{
+				try
+				{
+					var output:String = _nativeProcess.standardOutput.readUTFBytes(_nativeProcess.standardOutput.bytesAvailable);
+					log(output);
+				}
+				catch(e:Error)
+				{
+					log("Missed messagge from command line");
+				}
+			}
+			
+			private function nativeProcessStdErrorData(e:ProgressEvent):void
+			{
+				var output:String = _nativeProcess.standardError.readUTFBytes(_nativeProcess.standardError.bytesAvailable);
+				log(output);
+			}
+			
+			private function nativeProcessExit(e:NativeProcessExitEvent):void
+			{
+				log("Command terminal session ended.");
+			}
+			
+			public function log(v:String):void
+			{
+				if(_pipeOutputFunction != null)
+				{
+					_pipeOutputFunction.call(null,v);
+				}
+				logTxt.appendText(v);
+			}
+			
+			public function cd(path:String):void
+			{
+				_nativeProcess.standardInput.writeUTFBytes("cd " + fixPath(path) + "\n" );
+			}
+			
+			public function run(command:String):void
+			{
+				_nativeProcess.standardInput.writeUTFBytes(command + "\n" );
+			}
+			
+			public function stop():void
+			{
+				_nativeProcess.exit(true);
+			}
+
+			public function getSVNStatus(callback:Function):void
+			{
+				_pipeOutputFunction = callback;
+				_nativeProcess.standardInput.writeUTFBytes("svn status | grep '^M'\n" );
+			}
+			
+			private function fixPath(v:String):String
+			{
+				return "'" + v + "'";
+			}
+			
+			
+			
+		]]>
+	</fx:Script>
+	<s:TextArea id="logTxt" width="100%" height="100%" />
+</s:Group>

Propchange: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/CommandTerminal.mxml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaDependencyDB.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaDependencyDB.mxml?rev=1423796&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaDependencyDB.mxml (added)
+++ incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaDependencyDB.mxml Wed Dec 19 08:50:09 2012
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="utf-8"?>
+<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
+		 xmlns:s="library://ns.adobe.com/flex/spark" 
+		 xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
+	<fx:Declarations>
+		<!-- Place non-visual elements (e.g., services, value objects) here -->
+	</fx:Declarations>
+	<fx:Metadata>
+		[Event(name="complete", type="flash.events.Event")]
+	</fx:Metadata>
+	<fx:Script>
+		<![CDATA[
+			import mx.events.FlexEvent;
+			private static var skipDefs:Object = {
+				"AS3" : 1,
+				"ArgumentError" : 1,
+				"Array" : 1,
+				"Boolean" : 1,
+				"Class" : 1,
+				"Date" : 1,
+				"DefinitionError" : 1,
+				"Error" : 1,
+				"EvalError" : 1,
+				"Function" : 1,
+				"int" : 1,
+				"JSON" : 1,
+				"Math" : 1,
+				"Namespace" : 1,
+				"Number" : 1,
+				"Object": 1,
+				"QName" : 1,
+				"RangeError" : 1,
+				"ReferenceError" : 1,
+				"RegExp" : 1,
+				"SecurityError" : 1,
+				"String" : 1,
+				"SyntaxError" : 1,
+				"TypeError" : 1,
+				"uint" : 1,
+				"URIError" : 1,
+				"__AS3__.vec.Vector" : 1,
+				"XML" : 1,
+				"XMLList" : 1,
+				"trace" : 1,
+				
+				"mx.core:mx_internal" : 1
+			}
+			private var dirFile:File = new File();
+			private var fs:FileStream;
+			
+			public function setMustellaDirectory(path:String):void
+			{
+				dir.text = path;
+				dirFile = new File(path);
+			}
+			
+			private function browse():void
+			{
+				dirFile.addEventListener(Event.SELECT, selectHandler);
+				dirFile.browseForDirectory("Mustella Directory");
+			}
+			
+			private function selectHandler(event:Event):void
+			{
+				dir.text = dirFile.nativePath;	
+			}
+			
+			private function generateDB():void
+			{
+				callLater(readDB);
+			}
+			
+			private function readDB():void
+			{
+				var f:File = new File(dirFile.nativePath + "/" + "deps.xml");
+				try
+				{
+					var fs:FileStream = new FileStream();
+					fs.open(f, FileMode.READ);
+					var s:String = fs.readUTFBytes(fs.bytesAvailable);
+					var xml:XML = XML(s);
+					var scripts:XMLList = xml.scripts.script;
+					var n:int = scripts.length();
+					for (var i:int = 0; i < n; i++)
+					{
+						var script:XML = scripts[i];
+						var depMap:Object = db[script.@name] = {};
+						var deps:XMLList = script.deps;
+						var m:int= deps.length;
+						for (var j:int = 0; j < m; j++)
+						{
+							depMap[deps[j].@name] = 1;
+						}
+					}
+					fs.close();
+				}
+				catch (e:Error)
+				{
+					
+				}
+				
+				dirFile.nativePath = dir.text;
+				addFromFiles(dirFile);
+			}
+			
+			private var listings:Array = [];
+			private var counts:Array = [];
+			private var indexes:Array = [];
+			private var outputs:Array = [];
+			private var listing:Array;
+			private var count:int;
+			private var index:int;
+			
+			private function addFromFiles(dir:File):void
+			{
+				outputs.push(output.text);
+				output.text = "Scanning: " + dir.nativePath;
+				listing = dir.getDirectoryListing();
+				count = listing.length;
+				index = 0;
+				callLater(scanFiles);
+			}
+			
+			private function scanFiles():void
+			{
+				for (index; index < count; index++)
+				{
+					var f:File = listing[index];
+					if (f.isHidden) continue;
+					if (f.isDirectory)
+					{
+						listings.push(listing);
+						counts.push(count);
+						indexes.push(index);
+						addFromFiles(f);
+						return;
+					}
+					else if (f.nativePath.lastIndexOf(".lnk.xml") == f.nativePath.length - 8)
+					{
+						fs = new FileStream();
+						fs.open(f, FileMode.READ);
+						var s:String = fs.readUTFBytes(fs.bytesAvailable);
+						outputs.push(output.text);
+						output.text = "Parsing: " + f.nativePath;
+						fs.close();
+						callLater(parseFile, [s, f.nativePath.substring(dir.text.length, f.nativePath.length - 8)]);
+						return;
+					}
+				}
+				if (listings.length > 0)
+				{
+					listing = listings.pop();
+					count = counts.pop();
+					index = indexes.pop();
+					output.text = outputs.pop();
+					index++;
+					callLater(scanFiles);
+				}
+				else
+				{
+					output.text = "done!";
+					callLater(saveDB);
+				}
+				
+			}
+			
+			private function saveDB():void
+			{
+				var xml:XML = <Dependencies />;
+				for (var p:String in db)
+				{
+					var script:XML = <script />;
+					script.@name = p;
+					var deps:Object = db[p];
+					for (var q:String in deps)
+					{
+						var dep:XML = <dep />;
+						dep.@name = q;
+						script.appendChild(dep);
+					}
+					xml.appendChild(script);
+				}
+				var f:File = new File(dirFile.nativePath + "/" + "deps.xml");
+				var fs:FileStream = new FileStream();
+				fs.open(f, FileMode.WRITE);
+				var s:String = xml.toXMLString();
+				fs.writeUTFBytes(s);
+				fs.close();
+				callLater(handleComplete);
+			}
+			
+			private var db:Object = {};
+			
+			private function parseFile(s:String, mainClassPath:String):void
+			{
+				var xml:XML = XML(s);
+				var scripts:XMLList = xml.scripts.script;
+				var n:int = scripts.length();
+				for (var i:int = 0; i < n; i++)
+				{
+					var mxmlFile:Boolean = false;
+					var start:int;
+					var end:int;
+					var script:XML = scripts[i];
+					var name:String = script.def.@id;
+					var path:String = script.@name;
+					// if from a source file in the mustella dir
+					// use the path to it in case there are name collisions
+					if (path.indexOf(dir.text) == 0)
+					{
+						start = path.indexOf(".as");
+						if (start != -1)
+							name = path.substring(dir.text.length, start);
+						else
+						{
+							start = path.indexOf(".mxml");
+							if (start != -1)
+							{
+								name = path.substring(dir.text.length, start);
+								mxmlFile = true;
+							}
+						}
+					}
+					if (db[name] == null)
+					{
+						var depMap:Object = db[name] = {};
+						var deps:XMLList = script.dep;
+						var m:int;
+						var j:int;
+						m = deps.length();
+						for (j = 0; j < m; j++)
+						{
+							var dep:String = deps[j].@id;
+							if (skipDefs[dep])
+								continue; // skip as3 and mustella classes
+							if (dep.indexOf("flash.") == 0)
+								continue; // skip flash classes
+							depMap[dep] = 1;
+						}
+						deps = script.pre;
+						m = deps.length();
+						for (j = 0; j < m; j++)
+						{
+							dep = deps[j].@id;
+							if (skipDefs[dep])
+								continue; // skip as3 and mustella classes
+							if (dep.indexOf("flash.") == 0)
+								continue; // skip flash classes
+							depMap[dep] = 1;
+							if (dep == "UnitTester" && mxmlFile)
+							{
+								// this is a test script so inject a dependency on the
+								// main swf
+								depMap[mainClassPath] = 1;
+							}
+						}
+					}
+				}
+				index++;
+				output.text = outputs.pop();
+				callLater(scanFiles);
+			}
+			
+			private function handleComplete():void
+			{
+				dispatchEvent(new Event(Event.COMPLETE,true));
+			}
+		]]>
+	</fx:Script>
+	<s:layout>
+		<s:VerticalLayout />
+	</s:layout>
+	<s:HGroup>
+		<s:Label text="Mustella Directory:" />
+		<s:TextInput id="dir" width="220"/>
+		<s:Button label="Browse..." click="browse()" />
+		<s:Button label="Generate DB" click="generateDB()" />
+	</s:HGroup>
+	<s:Label id="output" />
+</s:Panel>

Propchange: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaDependencyDB.mxml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaTestChooser.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaTestChooser.mxml?rev=1423796&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaTestChooser.mxml (added)
+++ incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaTestChooser.mxml Wed Dec 19 08:50:09 2012
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
+					   xmlns:s="library://ns.adobe.com/flex/spark" 
+					   xmlns:mx="library://ns.adobe.com/flex/mx">
+	<fx:Declarations>
+		<!-- Place non-visual elements (e.g., services, value objects) here -->
+	</fx:Declarations>
+	<fx:Script>
+		<![CDATA[
+			private var dirFile:File = new File();
+			private var fs:FileStream;
+
+			private function browse():void
+			{
+				dirFile.addEventListener(Event.SELECT, selectHandler);
+				dirFile.browseForDirectory("Mustella Directory");
+			}
+			
+			public function setMustellaDirectory(path:String):void
+			{
+				dir.text = path;
+				dirFile = new File(path);
+			}
+			
+			public function setSVNStatus(status:String):void
+			{
+				statusLog.text = status;
+			}
+			
+			private function selectHandler(event:Event):void
+			{
+				dir.text = dirFile.nativePath;	
+			}
+			
+			
+			
+			private function computeTests():void
+			{
+				dirFile.nativePath = dir.text;
+				
+				var files:Array = statusLog.text.split("\n");
+				var modFiles:Array = [];
+				var n:int = files.length;
+				for (var i:int = 0; i < n; i++)
+				{
+					var file:String = files[i];
+					if (file.charAt(0) == "M")
+					{
+						modFiles.push(file);
+					}
+				}
+				
+				readDB();
+				
+				findTests();
+				
+				// flattenTests();
+				computeTestDependencies();
+				
+				n = modFiles.length;
+				for (i = 0; i < n; i++)
+				{
+					file = modFiles[i];
+					file = file.substr(8);
+					var c:int;
+					c = file.indexOf(".as");
+					if (c != -1)
+						file = file.substr(0, c);
+					else
+					{
+						c = file.indexOf(".mxml");
+						if (c != -1)
+							file = file.substr(0, c);
+					}
+					c = file.indexOf(File.separator + "src" + File.separator);
+					if (c != -1)
+						file = file.substr(c + 5);
+					c = file.lastIndexOf(File.separator);
+					if (c != -1)
+						file = file.substring(0, c) + ':' + file.substr(c + 1);
+					file = file.replace(new RegExp("\\" + File.separator,"g"), ".");
+					modFiles[i] = file;
+				}
+				var runTests:Array = [];
+				var m:int = testNames.length;				
+				for (i = 0; i < n; i++)
+				{
+					for (var j:int = 0; j < m; j++)
+					{
+						if (testDeps[testNames[j]][modFiles[i]])
+							runTests.push(testNames[j]);
+					}
+				}
+				runTests.sort();
+				var s:String = "";
+				n = runTests.length;
+				for (i = 0; i < n; i++)
+				{
+					//trace(runTests[i]);
+					s += runTests[i].substr(7) + "\n"; // clip leading '/tests/'
+				}
+				s = s.replace(/\\/g, "/"); 
+				output.text = s;
+				doneLabel.visible = true;
+				var f:File = new File(dirFile.nativePath + "/" + "changes.txt");
+				try
+				{
+					var fs:FileStream = new FileStream();
+					fs.open(f, FileMode.WRITE);
+					fs.writeUTFBytes(s);
+					fs.close();
+				}
+				catch (e:Error)
+				{
+					
+				}
+			}
+			
+			private var db:Object = {};
+			
+			private function readDB():void
+			{
+				var f:File = new File(dirFile.nativePath + "/" + "deps.xml");
+				try
+				{
+					var fs:FileStream = new FileStream();
+					fs.open(f, FileMode.READ);
+					var s:String = fs.readUTFBytes(fs.bytesAvailable);
+					var xml:XML = XML(s);
+					var scripts:XMLList = xml.script;
+					var n:int = scripts.length();
+					for (var i:int = 0; i < n; i++)
+					{
+						var script:XML = scripts[i];
+						var deps:XMLList = script.dep;
+						var m:int= deps.length();
+						var deplst:Object = {};
+						for (var j:int = 0; j < m; j++)
+						{
+							deplst[deps[j].@name] = 1;
+						}
+						db[script.@name] = deplst;
+					}
+					fs.close();
+				}
+				catch (e:Error)
+				{
+					
+				}
+			}
+
+			private var testNames:Array = [];
+			
+			private function findTests():void
+			{
+				// tests extend UnitTester
+				for (var p:String in db)
+				{
+					if (db[p]["UnitTester"] == 1)
+					{
+						// make sure it isn't a test step
+						if (p.indexOf("as3/src/") == -1) 
+							testNames.push(p);
+					}
+				}
+			}
+			
+			private var testDeps:Object = {};
+			
+			private function computeTestDependencies():void
+			{
+				for each (var p:String in testNames)
+				{
+					testDeps[p] = {};
+					addDeps(p, [testDeps[p]]);
+				}
+				
+			}
+			
+			private var inProgress:Object = {};
+			
+			private function addDeps(p:String, arr:Array):void
+			{
+				//trace(p);
+				
+				for each (var o:Object in arr)
+				{
+					o[p] = 1;
+				}
+				var deps:Object = db[p];
+				for (var q:String in deps)
+				{
+					o = testDeps[q];
+					if (o == null)
+					{
+						if (inProgress[q] == null)
+						{
+							o = {};
+							inProgress[q] = o;
+							arr.push(o);
+							addDeps(q, arr);
+							arr.pop();
+							testDeps[q] = o;
+							delete inProgress[q];
+						}
+					}
+					else
+					{
+						for (var r:String in o)
+						{
+							for each (var s:Object in arr)
+							{
+								s[r] = 1;
+							}
+						}
+					}
+					
+				}
+			}
+		]]>
+	</fx:Script>
+	<s:layout>
+		<s:VerticalLayout />
+	</s:layout>
+	<s:HGroup width="100%">
+		<s:Label text="Mustella Directory:" />
+		<s:TextInput id="dir" width="100%" toolTip="The mustella dir, not the tests dir"/>
+		<s:Button label="Browse..." click="browse()" />
+	</s:HGroup>
+	<s:Label text="Copy and paste SVN Status below" />
+	<s:TextArea id="statusLog" width="100%" change="doneLabel.visible=false"/>
+	<s:HGroup>
+		<s:Button label="Compute Tests" enabled="{statusLog.text.length > 0}" click="callLater(computeTests)" />
+		<s:Label id="doneLabel" visible="false" text="Wrote changes.txt. Use mini_run.sh -changes" />
+	</s:HGroup>
+	<s:TextArea id="output" width="100%" editable="false" lineBreak="explicit" horizontalScrollPolicy="auto" />
+</s:Panel>

Propchange: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/MustellaTestChooser.mxml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/WebServer.mxml
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/WebServer.mxml?rev=1423796&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/WebServer.mxml (added)
+++ incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/WebServer.mxml Wed Dec 19 08:50:09 2012
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" 
+		 xmlns:s="library://ns.adobe.com/flex/spark" 
+		 xmlns:mx="library://ns.adobe.com/flex/mx" 
+		 creationComplete="init()">
+	<s:layout>
+		<s:VerticalLayout paddingTop="8" paddingLeft="8" paddingRight="8" paddingBottom="8"/>
+	</s:layout>
+	
+	<fx:Script>
+		<![CDATA[
+			import flash.events.Event;
+			import flash.events.ProgressEvent;
+			import flash.events.ServerSocketConnectEvent;
+			import flash.net.ServerSocket;
+			import flash.net.Socket;
+			import flash.utils.ByteArray;
+			
+			import mx.controls.Alert;
+			
+			protected var serverSocket:ServerSocket;
+			
+			protected var mimeTypes:Object = new Object();
+			
+			[Bindable] protected var _webrootStr:String;
+			
+			protected function init():void
+			{
+				// The mime types supported by this mini web server
+				mimeTypes[".css"] 	= "text/css";
+				mimeTypes[".properties"] 	= "text/plain";
+				mimeTypes[".gif"] 	= "image/gif";
+				mimeTypes[".htm"] 	= "text/html";
+				mimeTypes[".html"] 	= "text/html";
+				mimeTypes[".ico"] 	= "image/x-icon";
+				mimeTypes[".jpg"] 	= "image/jpeg";
+				mimeTypes[".js"] 	= "application/x-javascript";
+				mimeTypes[".png"] 	= "image/png";
+				mimeTypes[".swf"] 	= "application/x-shockwave-flash";
+				
+			}
+			
+			public function setWebRoot(path:String):void
+			{
+				// Initialize the web server directory (in applicationStorageDirectory) with sample files
+				_webrootStr = path;
+			}
+			
+			protected function listen():void
+			{
+				try
+				{
+					serverSocket = new ServerSocket();
+					serverSocket.addEventListener(Event.CONNECT, socketConnectHandler);
+					serverSocket.bind(Number(port.text));
+					serverSocket.listen();
+					log.text += "Listening on port " + port.text + "...\n";
+				}
+				catch (error:Error)
+				{
+					Alert.show("Port " + port.text + 
+						" may be in use. Enter another port number and try again.\n(" +
+						error.message +")", "Error");
+				}
+			}
+			
+			protected function socketConnectHandler(event:ServerSocketConnectEvent):void
+			{
+				var socket:Socket = event.socket;
+				socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
+			}
+			
+			protected function socketDataHandler(event:ProgressEvent):void
+			{
+				try
+				{
+					var socket:Socket = event.target as Socket;
+					var bytes:ByteArray = new ByteArray();
+					socket.readBytes(bytes);
+					var request:String = "" + bytes;
+					log.text += request;
+					var filePath:String = request.substring(4, request.indexOf("HTTP/") - 1);
+					var realPath:String = sanitizeFilePath(_webrootStr + filePath);
+					var file:File = File.userDirectory.resolvePath(realPath);
+					if (file.exists && !file.isDirectory)
+					{
+						var stream:FileStream = new FileStream();
+						stream.open( file, FileMode.READ );
+						var content:ByteArray = new ByteArray();
+						stream.readBytes(content);
+						stream.close();
+						socket.writeUTFBytes("HTTP/1.1 200 OK\n");
+						socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n");
+						socket.writeBytes(content);
+					}
+					else
+					{
+						socket.writeUTFBytes("HTTP/1.1 404 Not Found\n");
+						socket.writeUTFBytes("Content-Type: text/html\n\n");
+						socket.writeUTFBytes("<html><body><h2>Page Not Found</h2></body></html>");
+					}
+					socket.flush();
+					socket.close();
+				}
+				catch (error:Error)
+				{
+					Alert.show(error.message, "Error");
+				}
+			}
+			
+			protected function getMimeType(path:String):String
+			{
+				var mimeType:String;
+				var index:int = path.lastIndexOf(".");
+				if (index > -1)
+				{
+					mimeType = mimeTypes[path.substring(index)];
+				}
+				return mimeType == null ? "text/html" : mimeType; // default to text/html for unknown mime types
+			}
+			
+			protected function sanitizeFilePath(path:String):String
+			{
+				var index:int = path.indexOf("?");
+				var realPath:String = path;
+				if(index > -1)
+				{
+					realPath = realPath.substring(0,index);
+				}
+				return realPath;
+			}
+			
+		]]>
+	</fx:Script>
+	
+	<s:HGroup verticalAlign="middle">
+		<s:Label text="Webroot: " />
+		<s:TextInput id="webrootTxt" text="{_webrootStr}" width="200" />
+		<s:Label text="Port:"/>
+		<s:TextInput id="port" text="80" width="50"/>
+		<s:Button label="Start Web Server" click="listen()"/>
+	</s:HGroup>
+	
+	<s:TextArea id="log" width="100%" height="100%" />
+</s:Panel>
\ No newline at end of file

Propchange: incubator/flex/sdk/branches/develop/mustella/utilities/OneClickMustella/src/org/apacheflex/mustella/oneclick/WebServer.mxml
------------------------------------------------------------------------------
    svn:eol-style = native