/// <exception cref="SocketException" /> /// <exception cref="UnableToResolveHostNameException" /> /// <exception cref="BuildFailed" /> /// <exception cref="RunFailed" /> public void BuildAndRunExported(PreviewArguments args, IMessagingService client, IFileSystem shell, IFuse fuse) { var buildEvents = new Subject <IBinaryMessage>(); var builder = UnoBuildWrapper.Create( shell, fuse.Version, buildEvents, false, new MissingRequiredPackageReferences(), new InstallAndroidRequired()); var projectId = ProjectIdComputer.IdFor(args.Project); using (PushEventsToDaemon.Start(buildEvents, client, args.Project, projectId, GetBuildTarget(args.Target))) using (buildEvents.Subscribe(_output.WriteBuildEvent)) { if (args.Endpoints.Count == 0) { args = args.AddEndpoints(GetProxyEndPoints()); } var build = builder .LoadOrBuildRunnable(args, CancellationToken.None) .GetResultAndUnpackExceptions(); if (args.CompileOnly == false) { build.Run(buildEvents.ToProgress()); } } }
async Task LaunchDesignerAndSubscribe(PreviewArguments args) { var client = await GetMessagingService(args); var projectId = ProjectIdComputer.IdFor(args.Project); var closed = SubscribeForProjectClosed(client, projectId); SubscribeForBuildStarted(client, projectId); SubscribeForLog(client, projectId); var openArgs = args.Project.ToString().Yield() .Concat(args.Defines.Select(d => "-D" + d)) .Concat(args.IsVerboseBuild ? Optional.Some("-v") : Optional.None()) .ToArray(); _fuse.Report.Info("Opening " + string.Join(",", openArgs.Select(a => "'" + a + "'")), ReportTo.LogAndUser); _fuse.StartFuse("open", openArgs); await closed; }
public override void Run(string[] args, CancellationToken ct) { _report.Info("Building with arguments '" + string.Join(" ", args) + "'"); try { using (var client = _daemonSpawner.ConnectOrSpawn( identifier: "Builder", timeout: TimeSpan.FromMinutes(1))) { Func <string, Optional <string> > parseNameArg = s => TryParseArg("n", "name", s); Func <string, Optional <string> > parseTargetArg = s => TryParseArg("t", "target", s); Func <Optional <string>, BuildTarget> targetToTargetEnum = s => { if (!s.HasValue) { return(BuildTarget.Unknown); } try { return((BuildTarget)Enum.Parse(typeof(BuildTarget), s.Value)); } catch (ArgumentException) { return(BuildTarget.Unknown); } }; var nameArgs = args.Select(parseNameArg).NotNone(); var nameArg = nameArgs.FirstOrNone(); var targetArgs = args.Select(parseTargetArg).NotNone(); var targetArg = targetArgs.FirstOrNone(); args = args.Where(s => !parseNameArg(s).HasValue).ToArray(); //uno does not accept name arg so strip it var buildId = Guid.NewGuid(); //_report.Info(string.Format("Calling '{0} {1}', with buildId '{2}'", startInfo.FileName, startInfo.Arguments, buildId)); var maybeFileOrProject = args .FirstOrNone(a => !a.StartsWith("-")) .Select(_fileSystem.ResolveAbsolutePath); var projPath = _projectDetector.GetCurrentProject(maybeFileOrProject); var target = targetToTargetEnum(targetArg); client.Broadcast( new BuildStartedData { BuildId = buildId, Target = target, BuildType = BuildTypeData.FullCompile, ProjectId = ProjectIdComputer.IdFor(projPath), ProjectPath = projPath.NativePath, BuildTag = nameArg.Or("") }); var outputData = new Subject <string>(); var errorData = new Subject <string>(); // ReSharper disable once AccessToDisposedClosure using (Observable.Merge(outputData, errorData).Subscribe(line => BroadCastBuildLog(line, client, buildId))) using (outputData.Select(line => line + "\n").Subscribe(_outWriter.Write)) using (errorData.Select(line => line + "\n").Subscribe(_errorWriter.Write)) { Process proc; try { proc = _uno.Start(new ProcessStartInfo { WindowStyle = ProcessWindowStyle.Hidden, Arguments = "build " + args.Select( s => { if (s.EndsWith("\\")) { return("\"" + s + " \""); } else { return("\"" + s + "\""); } }).Join(" "), RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false }); } catch (Exception e) { throw new FailedToStartBuild(e); } proc.ConsumeOutAndErr(outputData, errorData).Wait(); proc.WaitForExit(); var status = proc.ExitCode == 0 ? BuildStatus.Success : BuildStatus.Error; client.Broadcast( new BuildEndedData { BuildId = buildId, Status = status }); if (status == BuildStatus.Success) { _report.Info("Build " + buildId + " succeeded"); } else { _report.Error("Build " + buildId + " failed"); throw new UserCodeContainsErrors(); } } } } catch (DaemonException e) { throw new ExitWithError(e.Message); } catch (InvalidPath e) { throw new ExitWithError(e.Message); } catch (SecurityException e) { throw new ExitWithError(e.Message); } catch (ProjectNotFound e) { throw new ExitWithError(e.Message); } catch (FailedToStartBuild e) { throw new ExitWithError(e.Message); } catch (UserCodeContainsErrors e) { throw new ExitWithError(e.Message); } }
public Window Execute(IDocument document, string[] args) { var hack = new ReplaySubject <IObservable <BytecodeGenerated> >(1); var project = new LiveProject(document, _shell, hack.Switch().ObserveOn(Application.MainThread)); var ignore = RecentProjects.Bump(document, project.Name.ObserveOn(Application.MainThread)); var preview = _previewService.StartPreview(project); hack.OnNext(preview.Bytecode); #pragma warning disable 0219 var garbage = ExternalSelection.UpdateProjectContext(_daemon, project); #pragma warning restore 0219 var inspector = Fuse.Inspector.Inspector.Create(project); var buildArgs = new BuildArgs(args); var usbMode = new USBMode(new AndroidPortReverser(), Observable.Return(preview.Port), _previewService); var previewOnDevice = new PreviewOnDevice(_fuse, project, buildArgs); var build = new Build(project, preview, previewOnDevice, usbMode.EnableUsbModeCommand, buildArgs); var export = new Export(project, _fuse, buildArgs); var projHost = new ProjectHost(build.BuildArguments, preview, project, self => _projectsOpen.OnNext(_projectsOpen.Value.Remove(self))); _projectsOpen.OnNext(_projectsOpen.Value.Add(projHost)); var codeView = new CodeView(preview.AccessCode, NetworkHelper .GetInterNetworkIps() .ToArray()); // Viewport stuff var selectionEnabled = Property.Create(false); var glVersion = new Subject <OpenGlVersion>(); var viewport = new ViewportFactory( preview, selectionEnabled, preview.Port, project, _fuse, glVersion); var mode = UserSettings.Enum <Mode>("WindowMode").Or(Mode.Normal); var previewDevices = new PreviewDevices(project, _shell); var workspace = new StageController( viewport, previewDevices, selectionEnabled); var topMost = Property.Create(false); var windowMenu = Menu.Toggle( name: "Compact mode", toggle: mode.Convert( convert: m => m == Mode.Compact, convertBack: b => b ? Mode.Compact : Mode.Normal), hotkey: HotKey.Create(ModifierKeys.Meta, Key.M)) + Menu.Separator + Menu.Toggle( name: "Keep window on top", toggle: topMost, hotkey: HotKey.Create((_fuse.Platform == OS.Windows ? ModifierKeys.Shift : ModifierKeys.Alt) | ModifierKeys.Meta, Key.T)) + Menu.Separator + Menu.Option( value: Themes.OriginalLight, name: "Light theme", property: Theme.CurrentTheme) + Menu.Option( value: Themes.OriginalDark, name: "Dark theme", property: Theme.CurrentTheme); var messages = preview.Messages.Replay(TimeSpan.FromSeconds(2)).RefCount(); project.FilePath.SubscribeUsing(projPath => PushEventsToDaemon.Start( messages: messages, daemon: _daemon, projectPath: projPath, projectId: ProjectIdComputer.IdFor(projPath), target: BuildTarget.DotNetDll)); var sketchConverter = new SketchWatcher(_fuse.Report, _shell); var classExtractor = new ClassExtractor(project); var buildStartedOrLicenseChanged = project.FilePath .CombineLatest(build.Rebuilt.StartWith(Unit.Default)); var allLogMessages = messages.ToLogMessages() .Merge(_setupGuide.LogMessages) .Merge(export.LogMessages) .Merge(project.LogMessages) .Merge(previewOnDevice.LogMessages) .Merge(classExtractor.LogMessages) .Merge(_hostRequestMessages) .Merge(_errors.Select(e => e.Message)) .Merge(AutoReload.Log.Select(msg => "[Fusion AutoReload]: " + msg) .Merge(glVersion.Take(1).ToLogMessages(_fuse.Report))) .Merge(preview.LogMessages) .Merge(_previewService.LogMessages) .Merge(sketchConverter.LogMessages) .Merge(previewDevices.LogMessages); var stopPreview = preview.Start(build.BuildArguments); // start with a viewport workspace.NewViewport.ExecuteOnce(); var projectMenu = ProjectMenu.CommandItems(project.FilePath.Select(Optional.Some), _shell) + Menu.Separator + ProjectMenu.FileItems(project, _shell) + Menu.Separator + Menu.Item("Sketch import", sketchConverter.ShowDialog()); var help = new Help(); var debug = new Debug(project); var elementContext = new ElementContext(project.Context, project, _daemon); var errorView = new ErrorView(messages, project.FilePath, _daemon, preview.ClientRemoved); var logView = new LogView(allLogMessages, messages, errorView); var sketchWatch = sketchConverter.Watch(project); var window = MainWindow.Create( projectName: project.Name, search: Control.Empty, //search.Control, outline: CreateLeftPane(project, elementContext, project.Context, _shell, classExtractor), bookmarks: Control.Empty, stage: workspace, notifications: Layout.StackFromTop( SimulatorNotifications.CreateBusyIndicator(messages), SimulatorNotifications.Create(messages, build.Rebuild, logView.IsExpanded)), inspector: inspector, attributes: Control.Empty, //DataContext.Create(workspace.Viewport, selection.Element), logview: logView, menu: MainMenu.Create( _fuse, _shell, workspace, help, elementContext.CreateMenu(project.Context.CurrentSelection), projectMenu, build, export, _setupGuide, windowMenu, debug), closed: Command.Enabled(() => { stopPreview.Dispose(); preview.Dispose(); projHost.Dispose(); project.FilePath.Take(1).Subscribe(path => _daemon.Broadcast(new ProjectClosed { ProjectId = ProjectIdComputer.IdFor(path) })); project.Dispose(); workspace.Dispose(); sketchWatch.Dispose(); }), selectionEnabled: selectionEnabled, topMost: topMost, mode: mode, mainWindowFocused: _mainWindowFocused.Update(Unit.Default), context: project.Context, codeView: codeView); return(window); }