static async Task <int> MainAsync(string [] args) { if (args.Length == 0 || args [0] == null) { System.Console.Error.WriteLine("usage: WORKBOOK_PATH"); return(1); } var path = new FilePath(args [0]); Uri.TryCreate("file://" + path.FullPath, UriKind.Absolute, out var fileUri); if (!ClientSessionUri.TryParse(fileUri.AbsoluteUri, out var uri)) { System.Console.Error.WriteLine("Invalid URI"); return(1); } new ConsoleClientApp().Initialize( logProvider: new LogProvider(LogLevel.Info, null)); var session = new ClientSession(uri); session.InitializeViewControllers(new ConsoleClientSessionViewControllers()); await session.InitializeAsync(new ConsoleWorkbookPageHost()); await session.WorkbookPageViewModel.EvaluateAllAsync(); return(0); }
public override void ViewDidLoad() { base.ViewDidLoad(); liveInspectionRadioButton.State = NSCellStateValue.On; connectButton.KeyEquivalent = "\r"; locationTextField.Changed += (sender, e) => { if (ClientSessionUri.TryParse(locationTextField?.StringValue, out clientSessionUri)) { clientSessionUriTextField.StringValue = clientSessionUri.ToString(); } else { clientSessionUriTextField.StringValue = "Invalid Location"; } ValidateUserInterface(); }; ValidateUserInterface(); locationTextField.BecomeFirstResponder(); }
public async Task <IAgentTicket> RequestAgentTicketAsync( ClientSessionUri clientSessionUri, IMessageService messageService, Action disconnectedHandler, CancellationToken cancellationToken = default(CancellationToken)) { if (processManager == null) { return(null); } if (ticketType != null) { return((IAgentTicket)Activator.CreateInstance( ticketType, processManager, messageService, disconnectedHandler)); } var ticket = new AgentProcessTicket( processManager, messageService, disconnectedHandler); await ticket.GetAgentProcessStateAsync(cancellationToken); return(ticket); }
public void WithHostAndPort() { var original = new ClientSessionUri("localhost", 54321); original.ShouldBeSameAs(original.WithHostAndPort(null, null)); original.ShouldBeSameAs(original.WithHostAndPort("localhost", null)); original.ShouldBeSameAs(original.WithHostAndPort(null, 54321)); original.ShouldBeSameAs(original.WithHostAndPort("localhost", 54321)); var modifiedHost = original.WithHostAndPort("127.0.0.1", null); original.ShouldNotEqual(modifiedHost); modifiedHost.Host.ShouldEqual("127.0.0.1"); modifiedHost.Port.ShouldEqual(original.Port); original.ShouldEqual(modifiedHost.WithHostAndPort(original.Host, null)); var modifiedPort = original.WithHostAndPort(null, 50000); original.ShouldNotEqual(modifiedPort); modifiedPort.Host.ShouldEqual(original.Host); modifiedPort.Port.ShouldEqual((ushort)50000); original.ShouldEqual(modifiedPort.WithHostAndPort(null, original.Port)); var modifiedBoth = original.WithHostAndPort("127.0.0.1", 50000); original.ShouldNotEqual(modifiedBoth); modifiedBoth.Host.ShouldEqual("127.0.0.1"); modifiedBoth.Port.ShouldEqual((ushort)50000); original.ShouldEqual(modifiedBoth.WithHostAndPort(original.Host, original.Port)); }
public AgentProcessTicket( IAgentProcessManager agentProcessManager, ClientSessionUri clientSessionUri, IMessageService messageService, Action disconnectedHandler) { if (agentProcessManager == null) { throw new ArgumentNullException(nameof(agentProcessManager)); } if (clientSessionUri == null) { throw new ArgumentNullException(nameof(clientSessionUri)); } if (disconnectedHandler == null) { throw new ArgumentNullException(nameof(disconnectedHandler)); } AgentProcessManager = agentProcessManager; ClientSessionUri = clientSessionUri; MessageService = messageService; this.disconnectedHandler = disconnectedHandler; Id = Interlocked.Increment(ref lastId); }
public static void ShouldNotEqual(this ClientSessionUri a, ClientSessionUri b) { ((object)a).ShouldNotEqual(b); ((object)new ClientSessionUri(new Uri(a.ToString()))) .ShouldNotEqual(new ClientSessionUri(new Uri(b.ToString()))); (a == b).ShouldBeFalse(); (a != b).ShouldBeTrue(); }
public static void LaunchClientAppForDebugging(Agent agent) { #if DEBUG if (!Debugger.IsAttached) { return; } var clientAssemblyLocation = Assembly.GetExecutingAssembly().Location; var agentType = agent.ClientSessionUri.AgentType; InteractiveInstallation.InitializeDefault(null); var clientPath = InteractiveInstallation .Default .LocateClientApplication(agent.ClientSessionUri.SessionKind); if (string.IsNullOrEmpty(clientPath)) { return; } var connectUri = new ClientSessionUri( agent.Identity.AgentType, agent.ClientSessionUri.SessionKind, agent.Identity.Host, agent.Identity.Port); if (HostEnvironment.OS == HostOS.macOS) { var executableName = Directory.GetFiles( Path.Combine(clientPath, "Contents", "MacOS")) [0]; clientPath = Path.Combine(clientPath, "Contents", "MacOS", executableName); } Exec.Log += (sender, e) => { if (e.ExitCode == null) { Log.Debug(TAG, $"Exec[{e.ExecId}] ({e.Flags}): {e.Arguments}"); } else { Log.Debug(TAG, $"Exec[{e.ExecId}] exited: {e.ExitCode}"); } }; Exec.RunAsync( segment => Debug.WriteLine($"!! {segment.Data.TrimEnd ()}"), clientPath, connectUri).ContinueWith(task => { if (task.Exception != null) { Log.Error(TAG, task.Exception); } }); #endif }
/// <summary> /// Provides very basic workbook parsing and shunting of code cells /// into the evaluation service. Does not display non-code-cell contents /// but does evaluate a workbook from top-to-bottom. Restores nuget /// packages from the workbook's manifest. /// </summary> static async Task <int> WorkbookPlayerMain(InteractiveSession session, ClientSessionUri sessionUri) { var path = new FilePath(sessionUri.WorkbookPath); if (!path.FileExists) { Error.WriteLine($"File does not exist: {path}"); return(1); } // load the workbook file var workbook = new WorkbookPackage(path); await workbook.Open( quarantineInfo => Task.FromResult(true), path); #pragma warning disable 0618 // TODO: WorkbookDocumentManifest needs to eliminate AgentType like we've done on web // to avoid having to use the the flavor mapping in AgentIdentity. var targetPlatformIdentifier = AgentIdentity.GetFlavorId(workbook.PlatformTargets [0]); #pragma warning restore 0618 // initialize the session based on manifest metadata from the workbook file language = workbook.GetLanguageDescriptions().First(); await session.InitializeAsync(new InteractiveSessionDescription ( language, targetPlatformIdentifier, new EvaluationEnvironment(Environment.CurrentDirectory))); // restore NuGet packages await session.PackageManagerService.RestoreAsync( workbook.Pages.SelectMany(page => page.Packages)); // insert and evaluate cells in the workbook foreach (var cell in workbook.IndexPage.Contents.OfType <CodeCell> ()) { var buffer = cell.CodeAnalysisBuffer.Value; lastCodeCellId = await session.EvaluationService.InsertCodeCellAsync( buffer, lastCodeCellId); ForegroundColor = ConsoleColor.DarkYellow; Write(GetPrompt()); ResetColor(); WriteLine(buffer); await session.EvaluationService.EvaluateAsync(lastCodeCellId); if (lastCellEvaluationStatus != CodeCellEvaluationStatus.Success) { break; } } return(0); }
public void OpenWorkbook(string path) { var systemUri = new Uri(path); var uri = new ClientSessionUri(systemUri); uri.WorkbookPath.ShouldEqual(systemUri.LocalPath); uri.SessionKind.ShouldEqual(ClientSessionKind.Workbook); uri.ToString().ShouldEqual(systemUri.ToString()); }
void Open(ClientSessionUri uri) { var sessionKind = liveInspectionRadioButton.State == NSCellStateValue.On ? ClientSessionKind.LiveInspection : ClientSessionKind.Workbook; if (NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl(uri.WithSessionKind(sessionKind)))) { View.Window.Close(); } }
public void Schemes() { Assert.Throws <ArgumentException> ( () => new ClientSessionUri(new Uri("http://foo"))); Assert.Throws <ArgumentException> ( () => new ClientSessionUri(new Uri("relative path", UriKind.Relative))); Assert.DoesNotThrow(() => new ClientSessionUri(new Uri("file://foo"))); Assert.DoesNotThrow(() => new ClientSessionUri(new Uri("C:\\file"))); Assert.DoesNotThrow(() => CSU("localhost:54321")); ClientSessionUri.IsSchemeSupported("xamarin-interactive").ShouldBeTrue(); ClientSessionUri.IsSchemeSupported("file").ShouldBeTrue(); ClientSessionUri.IsSchemeSupported("gopher").ShouldBeFalse(); }
public void WorkingDirectory() { const string uriString = "bacon:60000/v1?workingDirectory=/a/b/c"; var referenceUri = new ClientSessionUri( AgentType.Unknown, ClientSessionKind.Unknown, "bacon", 60000, workingDirectory: "/a/b/c"); CSU(uriString).ShouldEqual(referenceUri); CSU(uriString) .WithWorkingDirectory("overwritten") .ShouldEqual(referenceUri.WithWorkingDirectory("overwritten")); }
public Agent Start(AgentStartOptions startOptions = null) { agentServer.Start(); Identity = Identity .WithHost(agentServer.BaseUri.Host) .WithPort((ushort)agentServer.BaseUri.Port); // Default to LiveInspection, and correct later if wrong. // Only inspection extensions respond to InspectorSupport.AgentStarted. ClientSessionUri = new ClientSessionUri( Identity.AgentType, startOptions?.ClientSessionKind ?? ClientSessionKind.LiveInspection, Identity.Host, Identity.Port); startOptions?.AgentStarted?.Invoke(ClientSessionUri); try { var identifyAgentRequest = GetIdentifyAgentRequest(); if (identifyAgentRequest != null) { ClientSessionUri = ClientSessionUri.WithSessionKind(ClientSessionKind.Workbook); WriteAgentIdentityAsync(identifyAgentRequest).ContinueWithOnMainThread(task => { if (task.IsFaulted) { Log.Error( TAG, $"{nameof (WriteAgentIdentityAsync)}", task.Exception); IdentificationFailure?.Invoke(this, EventArgs.Empty); } }); } } catch (Exception e) { Log.Error(TAG, e); IdentificationFailure?.Invoke(this, EventArgs.Empty); } Log.Info(TAG, $"{Identity.AgentType} '{Identity.ApplicationName}' " + $"is available for interaction: {ClientSessionUri}"); return(this); }
public void WithParameters() { var original = new ClientSessionUri(AgentType.iOS, ClientSessionKind.Workbook); original.ShouldBeSameAs(original.WithParameters(null)); original.ShouldBeSameAs(original.WithParameters(Array.Empty <KeyValuePair <string, string> > ())); var parameters = new [] { new KeyValuePair <string, string> ("feature", "xamarin.forms"), new KeyValuePair <string, string> ("random thing", "blah & blah") }; var modified = original.WithParameters(parameters); modified.Parameters.Length.ShouldEqual(2); modified.Parameters.SequenceShouldEqual(parameters); var fromSystemUri = CSU("/v1?sessionKind=Workbook&agentType=iOS&feature=xamarin.forms&random%20thing=blah%20%26%20blah"); fromSystemUri.ShouldEqual(modified); }
public static AgentSessionWindow Open(ClientSessionUri clientSessionUri) { AgentSessionWindow window; if (!SessionController.TryGetApplicationState(clientSessionUri, out window)) { window = new AgentSessionWindow(clientSessionUri); } window.Show(); window.Activate(); // Sometimes (like when clicking the Inspect button in VS), Activate fails to // bring the client window to the foreground (very obvious if it is behind VS). // This hack temporarily sets the window to be always-on-top to force it to // the foreground, then immediately unsets that property. window.Topmost = true; window.Topmost = false; return(window); }
AgentSessionWindow(ClientSessionUri clientSessionUri) { MessageViewDelegate = new WpfMessageViewDelegate(this); DialogMessageViewDelegate = new WpfDialogMessageViewDelegate(this); Session = new ClientSession(clientSessionUri); Session.InitializeViewControllers( new WpfClientSessionViewControllers(MessageViewDelegate, DialogMessageViewDelegate)); SessionController.AddSession(Session, this); InitializeComponent(); DataContext = this; ViewModel = new ViewInspectorViewModel <AgentSessionWindow> (Session, this); menuManager = new MenuManager(mainMenu, this, Session.SessionKind != ClientSessionKind.LiveInspection); replWebView.Loaded += HandleWebViewControlLoaded; replWebView.LoadCompleted += HandleWebViewSourceLoadCompleted; propertyEditor.EditorProvider = new InteractiveEditorProvider(Session, new WpfPropertyViewHelper()); }
public void TryParse( string uriString, bool expectedResult, string host, int port, ClientSessionKind clientSessionKind) { ClientSessionUri uri; ClientSessionUri.TryParse(uriString, out uri).ShouldEqual(expectedResult); if (!expectedResult) { return; } uri.Host.ShouldEqual(host); uri.Port.ShouldEqual((ushort)port); uri.SessionKind.ShouldEqual(clientSessionKind); Assert.DoesNotThrow(() => uri.ToString()); }
public void WithAssemblySearchPaths() { var original = new ClientSessionUri(AgentType.iOS, ClientSessionKind.LiveInspection); original.ShouldBeSameAs(original.WithAssemblySearchPaths(null)); original.ShouldBeSameAs(original.WithAssemblySearchPaths(new string [0])); var modified = original.WithAssemblySearchPaths(new [] { "hello" }); modified.AssemblySearchPaths.Length.ShouldEqual(1); modified.AssemblySearchPaths [0].ShouldEqual("hello"); original = new ClientSessionUri("localhost", 54321, new [] { "a", "b", "c" }); original.ShouldBeSameAs(original.WithAssemblySearchPaths(new [] { "a", "b", "c" })); original.WithAssemblySearchPaths(null).AssemblySearchPaths.Length.ShouldEqual(0); original.WithAssemblySearchPaths(new string [0]).AssemblySearchPaths.Length.ShouldEqual(0); modified = original.WithAssemblySearchPaths(new [] { "x", "y" }); modified.AssemblySearchPaths.Length.ShouldEqual(2); modified.AssemblySearchPaths [0].ShouldEqual("x"); modified.AssemblySearchPaths [1].ShouldEqual("y"); }
internal static InteractiveSession CreateLiveInspectionSession( ClientSessionUri liveInspectAgentUri) => new InteractiveSession(
public SessionDocument OpenDocument(ClientSessionUri uri) => OpenDocument(new NSUrl(uri));
static async Task <int> MainAsync(string [] args) { ClientSessionUri sessionUri = null; TextWriter logWriter = null; var showHelp = false; var options = new OptionSet { { "usage: xic [OPTIONS]+ [URI]" }, { "" }, { "Options:" }, { "" }, { "l|log=", "Write debugging log to file", v => logWriter = new StreamWriter(v) }, { "h|help", "Show this help", v => showHelp = true } }; try { args = options.Parse(args).ToArray(); } catch (Exception e) { Error.WriteLine($"Invalid option: {e.Message}"); showHelp = true; } if (showHelp) { options.WriteOptionDescriptions(Out); return(1); } if (args.Length > 0) { if (!ClientSessionUri.TryParse(args [0], out sessionUri)) { Error.WriteLine($"Invalid URI: {args [0]}"); return(1); } } // set up the very basic global services/environment var clientApp = new ConsoleClientApp(); clientApp.Initialize( logProvider: new LogProvider(LogLevel.Info, logWriter)); // Now create and get ready to deal with the session; a more complete // client should handle more than just OnNext from the observer. var session = new InteractiveSession(agentUri: sessionUri); session.Events.Subscribe(new Observer <InteractiveSessionEvent> (OnSessionEvent)); if (sessionUri?.WorkbookPath != null) { await WorkbookPlayerMain(session, sessionUri); } else { await ReplPlayerMain(session); } // Nevermind this... it'll get fixed! await Task.Delay(Timeout.Infinite); return(0); }
public int Run() { var workbooksApp = Path.Combine( Environment.CurrentDirectory, InteractiveInstallation.Default.LocateClientApplication( ClientSessionKind.Workbook)); var launchUris = new List <ClientSessionUri> (); foreach (var uriString in ClientLaunchUris) { ClientSessionUri uri = null; if (File.Exists(uriString) || Directory.Exists(uriString)) { try { var fileUri = new Uri( Path.Combine(Environment.CurrentDirectory, uriString)); uri = new ClientSessionUri(fileUri); } catch { } } if (uri == null && !ClientSessionUri.TryParse(uriString, out uri)) { AgentType agentType; if (String.Equals(uriString, "mac", StringComparison.OrdinalIgnoreCase)) { agentType = AgentType.MacNet45; } else if (!Enum.TryParse(uriString, true, out agentType)) { throw new Exception($"Invalid URI or platform '{uriString}'"); } uri = new ClientSessionUri(agentType, ClientSessionKind.Workbook); } launchUris.Add(uri); } if (launchUris.Count == 0) { launchUris.Add(new ClientSessionUri(AgentType.Console, ClientSessionKind.Workbook)); } var workingDirectory = Environment.CurrentDirectory; var arguments = new List <string> (); foreach (var launchUri in launchUris) { var uri = launchUri; if (uri.WorkbookPath == null) { uri = uri.WithWorkingDirectory(workingDirectory); } arguments.Add($"\"{uri}\""); } if (InteractiveInstallation.Default.IsMac) { arguments.Insert(0, $"\"{workbooksApp}\""); arguments.Insert(0, "-a"); Exec("open", arguments); } else { Exec(workbooksApp, arguments); } return(0); }
public int Run() { var isMac = Environment.OSVersion.Platform == PlatformID.Unix; string workbooksApp; var driverLocation = Assembly.GetExecutingAssembly().Location; if (isMac) { workbooksApp = new FilePath(Path.GetDirectoryName(driverLocation)).Combine( "..", "..").FullPath; } else { workbooksApp = Assembly.GetExecutingAssembly().Location; } var launchUris = new List <ClientSessionUri> (); foreach (var uriString in ClientLaunchUris) { ClientSessionUri uri = null; if (File.Exists(uriString) || Directory.Exists(uriString)) { try { var fileUri = new Uri( Path.Combine(Environment.CurrentDirectory, uriString)); uri = new ClientSessionUri(fileUri); } catch { } } if (uri == null && !ClientSessionUri.TryParse(uriString, out uri)) { AgentType agentType; if (String.Equals(uriString, "mac", StringComparison.OrdinalIgnoreCase)) { agentType = AgentType.MacNet45; } else if (!Enum.TryParse(uriString, true, out agentType)) { throw new Exception($"Invalid URI or platform '{uriString}'"); } uri = new ClientSessionUri(agentType, ClientSessionKind.Workbook); } launchUris.Add(uri); } if (launchUris.Count == 0) { launchUris.Add(new ClientSessionUri(AgentType.Console, ClientSessionKind.Workbook)); } var workingDirectory = Environment.CurrentDirectory; var arguments = new List <string> (); foreach (var launchUri in launchUris) { var uri = launchUri; if (uri.WorkbookPath == null) { uri = uri.WithWorkingDirectory(workingDirectory); } arguments.Add($"\"{uri}\""); } if (isMac) { arguments.Insert(0, $"\"{workbooksApp}\""); arguments.Insert(0, "-a"); Exec("open", arguments); } else { Exec(workbooksApp, arguments); } return(0); }
public static void LaunchClientAppForDebugging(Agent agent) { #if DEBUG if (!Debugger.IsAttached) { return; } var clientAssemblyLocation = Assembly.GetExecutingAssembly().Location; var buildDepth = 5; var agentType = agent.ClientSessionUri.AgentType; // The Mac executable is more deeply nested, so we need to go up a little further // to get the base build path. if (agentType == AgentType.MacMobile || agentType == AgentType.MacNet45) { buildDepth = 7; } var buildDir = clientAssemblyLocation; for (var i = 0; i < buildDepth; i++) { buildDir = Path.GetDirectoryName(buildDir); } InteractiveInstallation.InitializeDefault( isMac: Environment.OSVersion.Platform == PlatformID.Unix, buildPath: buildDir); var clientPath = InteractiveInstallation .Default .LocateClientApplication(agent.ClientSessionUri.SessionKind); if (string.IsNullOrEmpty(clientPath)) { return; } var connectUri = new ClientSessionUri( agent.Identity.AgentType, agent.ClientSessionUri.SessionKind, agent.Identity.Host, agent.Identity.Port); if (InteractiveInstallation.Default.IsMac) { var executableName = Directory.GetFiles( Path.Combine(clientPath, "Contents", "MacOS")) [0]; clientPath = Path.Combine(clientPath, "Contents", "MacOS", executableName); } Exec.Log += (sender, e) => { if (e.ExitCode == null) { Log.Debug(TAG, $"Exec[{e.ExecId}] ({e.Flags}): {e.Arguments}"); } else { Log.Debug(TAG, $"Exec[{e.ExecId}] exited: {e.ExitCode}"); } }; Exec.RunAsync( segment => Debug.WriteLine($"!! {segment.Data.TrimEnd ()}"), clientPath, connectUri).ContinueWith(task => { if (task.Exception != null) { Log.Error(TAG, task.Exception); } }); #endif }