public override Entity Resolve(Entity owner, string key, bool fallback = false)
        {
            if (key == EntityKeys.InternalDeployPathKey)
            {
                TargetEntity     targetEntity  = TargetEntity.Decorate(owner);
                BuildEntity      buildEntity   = BuildEntity.Decorate(owner);
                Entity           project       = owner.Root;
                CommandEntity    commandOrigin = CommandEntity.Decorate(owner.Origin);
                VirtualDirectory outputRoot    = fileSystem.GetDirectory(commandOrigin.Output, project.Path);
                VirtualDirectory deployRoot    = outputRoot.Directory(targetEntity.FullName.Replace(',', '_'),
                                                                      buildEntity.BuildType);
                return(owner.Create(key, deployRoot.FullName, deployRoot));
            }

            CommandEntity command           = CommandEntity.Decorate(owner);
            FileEntity    projectFileEntity = FileEntity.Decorate(owner.Root);
            string        outputDirectory   = command.GetSingleValueArgument(Constants.OutputArgumentName);

            if (string.IsNullOrEmpty(outputDirectory))
            {
                outputDirectory = projectFileEntity.Directory
                                  .Directory(Constants.LibraryFolderName)
                                  .FullName;
            }

            return(owner.Create(key, outputDirectory));
        }
        private int ExecuteLibraryBuilderWithCommandOptions(string commandOptionsFile, ProjectEntity project)
        {
            FileEntity projectFileEntity  = FileEntity.Decorate(project);
            string     libraryBuilderName = FindLibraryBuilder();

            using (IProcess process = processManager.StartProcess(libraryBuilderName,
                                                                  $"{Constants.CommandFileOption} \"{commandOptionsFile}\"", executionContext,
                                                                  projectFileEntity.Directory.FullName))
            {
                process.WaitForExit();
                if (process.ExitCode == 0)
                {
                    //Only on success delete directory.
                    projectFileEntity.TempDirectory.Delete();
                }
                return(process.ExitCode);
            }

            string FindLibraryBuilder()
            {
                string command = binariesLocator.GetExecutableCommand("EngineeringLibraryBuilder");

                if (string.IsNullOrEmpty(command))
                {
                    throw new LibraryBuilderNotFoundException();
                }

                return(command);
            }
        }
Exemplo n.º 3
0
        protected override int Execute(SetTargetsCommandArgs args, ChangeObservable observable)
        {
            ProjectEntity project    = ProjectEntity.Decorate(entityFactory.Create(Guid.NewGuid().ToByteString(), args).Root);
            FileEntity    fileEntity = FileEntity.Decorate(project);

            if (!project.Settings.IsPersistent)
            {
                throw new TargetNotSettableForProjectException();
            }

            if (args.Add)
            {
                Target result = targetParser.AddTarget(project, args.Name, args.Version);
                userInterface.WriteInformation($"Successfully added target {result.Name} {result.LongVersion} to project {fileEntity.Directory.FullName}.");
            }
            else if (args.Remove)
            {
                Target result = targetParser.RemoveTarget(project, args.Name, args.Version);
                userInterface.WriteInformation($"Successfully removed target {result.Name} {result.LongVersion} from project {fileEntity.Directory.FullName}.");
            }
            else
            {
                throw new SetTargetsOptionMissingException();
            }

            return(0);
        }
        private JArray GetCodeModel(Entity owner, VirtualDirectory buildSystemDirectory)
        {
            VirtualDirectory temp      = FileEntity.Decorate(owner).TempDirectory;
            JArray           codeModel = null;

            try
            {
                codeModel = cmakeConversation.GetCodeModelFromServer(temp.Directory("cmake"),
                                                                     FileEntity.Decorate(owner.Root).Directory,
                                                                     buildSystemDirectory);
            }
            catch (TimeoutException e)
            {
                executionContext.WriteError($"Timeout during cmake server conversation: {e}", false);
            }
            if (codeModel == null)
            {
                throw new FormattableException("Could not fetch code model from cmake build system.");
            }
            return(codeModel);
        }
        private string GenerateCommandOptions(ProjectEntity project, Dictionary <Entity, VirtualFile> projectLibraries, string projectName)
        {
            FileEntity       projectFileEntity  = FileEntity.Decorate(project);
            VirtualFile      commandOptions     = projectFileEntity.TempDirectory.File("CommandOptions.txt");
            CommandEntity    commandOrigin      = CommandEntity.Decorate(project.Origin);
            VirtualDirectory outputRoot         = fileSystem.GetDirectory(commandOrigin.Output, project.Path, false);
            List <string>    processedMetaFiles = new List <string>();

            executionContext.Observable.OnNext(new Change(() => { }, $"Create command options file {commandOptions.FullName}"));

            using (Stream stream = commandOptions.OpenWrite())
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.WriteLine($"{Constants.OutputOption} \"{MakeRelative(Path.Combine(outputRoot.FullName, projectName))}.{Constants.EngineeringLibraryExtension}\"");
                    writer.WriteLine($"{Constants.GuidOption} {project.Id:D}");

                    RenameAndWriteLibraryFile(writer);
                    WriteMetadata(writer);
                    AddAdditionalFiles(writer);
                }

            return(commandOptions.FullName);

            void RenameAndWriteLibraryFile(StreamWriter writer)
            {
                foreach (TargetEntity target in projectLibraries.Keys.Select(TargetEntity.Decorate))
                {
                    VirtualFile renamedLibrary = projectFileEntity
                                                 .TempDirectory.Directory(target.FullName.Replace(",", "_"))
                                                 .File("lib" + projectName +
                                                       Path.GetExtension(projectLibraries[target.Base].Name));
                    executionContext.Observable.OnNext(new Change(() => { }, $"Rename library file to {renamedLibrary.FullName}"));
                    using (Stream source = projectLibraries[target.Base].OpenRead(true))
                        using (Stream destination = renamedLibrary.OpenWrite())
                        {
                            source.CopyTo(destination);
                        }
                    writer.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                                   Constants.PlcnextNativeLibraryOptionPattern,
                                                   renamedLibrary.Parent.FullName,
                                                   target.Name,
                                                   target.EngineerVersion,
                                                   guidFactory.Create().ToString("D", CultureInfo.InvariantCulture),
                                                   target.ShortFullName.Replace(",", "_")));
                }
            }

            void AddAdditionalFiles(StreamWriter writer)
            {
                foreach (Entity target in projectLibraries.Keys)
                {
                    VirtualDirectory          deployDirectory = DeployEntity.Decorate(target).DeployDirectory;
                    IEnumerable <VirtualFile> files           = deployDirectory
                                                                .Files(searchRecursive: true).Except(projectLibraries.Values)
                                                                .Where(f => !processedMetaFiles.Contains(f.GetRelativePath(deployDirectory)));
                    foreach (VirtualFile file in files)
                    {
                        writer.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                                       "/file \":{0}:{1}\"",
                                                       file.GetRelativeOrAbsolutePath(projectFileEntity.Directory),
                                                       TargetEntity.Decorate(target).ShortFullName.Replace(",", "_")));
                    }
                }
            }

            void WriteMetadata(StreamWriter writer)
            {
                VirtualDirectory           deployDirectory   = DeployEntity.Decorate(projectLibraries.Keys.First()).DeployDirectory;
                HashSet <VirtualDirectory> createDirectories = new HashSet <VirtualDirectory>();

                foreach (VirtualFile metaFile in deployDirectory.Files(searchRecursive: true))
                {
                    string destinationPath;
                    string fileType;
                    switch (Path.GetExtension(metaFile.Name)?.ToUpperInvariant() ?? string.Empty)
                    {
                    case ".LIBMETA":
                        destinationPath = string.Empty;
                        fileType        = Constants.LibmetaFileType;
                        break;

                    case ".TYPEMETA":
                        destinationPath = string.Empty;
                        fileType        = Constants.TypemetaFileType;
                        break;

                    case ".COMPMETA":
                        CreateComponentDirectory(metaFile.Parent);
                        destinationPath = metaFile.Parent.Name;
                        fileType        = Constants.CompmetaFileType;
                        break;

                    case ".PROGMETA":
                        CreateProgramDirectory(metaFile.Parent);
                        destinationPath = $"{metaFile.Parent.Parent.Name}/{metaFile.Parent.Name}";
                        fileType        = Constants.ProgmetaFileType;
                        break;

                    default:
                        //do nothing all other files are not interesting
                        continue;
                    }
                    writer.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                                   Constants.FileOptionPattern,
                                                   fileType,
                                                   MakeRelative(metaFile.FullName),
                                                   guidFactory.Create().ToString("D", CultureInfo.InvariantCulture),
                                                   destinationPath));
                    processedMetaFiles.Add(metaFile.GetRelativePath(deployDirectory));
                }

                void CreateComponentDirectory(VirtualDirectory componentDirectory)
                {
                    if (createDirectories.Contains(componentDirectory))
                    {
                        return;
                    }

                    writer.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                                   Constants.DirectoryOptionPattern,
                                                   $"Logical Elements/{componentDirectory.Name}",
                                                   Constants.ComponentFolderType,
                                                   guidFactory.Create().ToString("D", CultureInfo.InvariantCulture)));
                    createDirectories.Add(componentDirectory);
                }

                void CreateProgramDirectory(VirtualDirectory programDirectory)
                {
                    if (createDirectories.Contains(programDirectory))
                    {
                        return;
                    }

                    CreateComponentDirectory(programDirectory.Parent);
                    writer.WriteLine(string.Format(CultureInfo.InvariantCulture,
                                                   Constants.DirectoryOptionPattern,
                                                   $"Logical Elements/{programDirectory.Parent.Name}/{programDirectory.Name}",
                                                   Constants.ProgramFolderType,
                                                   guidFactory.Create().ToString("D", CultureInfo.InvariantCulture)));
                    createDirectories.Add(programDirectory);
                }
            }

            string MakeRelative(string path)
            {
                return(path.GetRelativePath(projectFileEntity.Directory.FullName));
            }
        }