private void CopyExternalLibrariesToOutputDirectory(Entity target, Dictionary <Entity, VirtualFile> projectLibraries,
                                                            out IEnumerable <string> externalLibraries,
                                                            out IEnumerable <VirtualFile> copiedLibraries)
        {
            VirtualDirectory deployDirectory   = DeployEntity.Decorate(target).DeployDirectory;
            VirtualDirectory externalDirectory = deployDirectory.Directory("auto-deployed-external-libraries");

            externalDirectory.Clear();
            executionContext.Observable.OnNext(new Change(() => externalDirectory.UnClear(), "Cleared automatic copied external libraries."));
            externalLibraries = Enumerable.Empty <string>();
            copiedLibraries   = Enumerable.Empty <VirtualFile>();
            List <VirtualFile> newLibraryFiles = new List <VirtualFile>();

            if (deployDirectory.Files("*.so", true).Except(projectLibraries.Values).Any())
            {
                externalLibraries = deployDirectory.Files("*.so", true).Except(projectLibraries.Values)
                                    .Select(f => f.FullName).ToArray();
                //external libraries where copied by user; no further action is required
                return;
            }

            BuildEntity buildEntity = BuildEntity.Decorate(target);

            if (!buildEntity.HasBuildSystem)
            {
                TargetEntity targetEntity = TargetEntity.Decorate(target);
                executionContext.WriteWarning(new CMakeBuildSystemNotFoundException(targetEntity.FullName, buildEntity.BuildType).Message);
                return;
            }

            externalLibraries = buildEntity.BuildSystem.ExternalLibraries;
            TargetEntity entity = TargetEntity.Decorate(target);

            if (entity.Version >= new Version(20, 6))
            {
                foreach (string externalLibrary in buildEntity.BuildSystem.ExternalLibraries)
                {
                    VirtualFile newFile = fileSystem.GetFile(externalLibrary).CopyTo(deployDirectory);
                    newLibraryFiles.Add(newFile);
                    executionContext.Observable.OnNext(new Change(() => newFile.Delete(), $"Copied {externalLibrary} to {newFile.FullName}."));
                }
            }
            else
            {
                foreach (string externalLibrary in buildEntity.BuildSystem.ExternalLibraries)
                {
                    executionContext.WriteWarning($"The library {externalLibrary} must be transferred to the device {entity.FullName} into the directory \"usr/local/lib\" manually.");
                }
            }

            copiedLibraries = newLibraryFiles;
        }
示例#2
0
        static void Main(string[] args)
        {
            var entity = new DeployEntity();

            entity.AppId         = 100;
            entity.DeployCode    = "100";
            entity.DeployPackage = "100";
            entity.DeployContent = "100";
            entity.UploadUserId  = 100;
            entity.UploadTime    = DateTime.Now;
            entity.DeployType    = 100;

            var service = new DeployService();

            //插入
            service.Insert(entity);

            //查询所有
            var allList = service.GetAll <DeployEntity>();

            //多条件查询
            var pgMain = new PredicateGroup {
                Operator = GroupOperator.Or, Predicates = new List <IPredicate>()
            };

            var pga = new PredicateGroup()
            {
                Operator = GroupOperator.And, Predicates = new List <IPredicate>()
            };

            pga.Predicates.Add(Predicates.Field <DeployEntity>(f => f.DeployCode, Operator.Eq, "100"));
            pga.Predicates.Add(Predicates.Field <DeployEntity>(f => f.ID, Operator.Ge, 47));
            pga.Predicates.Add(Predicates.Field <DeployEntity>(f => f.ID, Operator.Le, 48));
            pgMain.Predicates.Add(pga);

            var pgb = new PredicateGroup()
            {
                Operator = GroupOperator.And, Predicates = new List <IPredicate>()
            };

            pgb.Predicates.Add(Predicates.Field <DeployEntity>(f => f.DeployCode, Operator.Eq, "10000"));
            pgMain.Predicates.Add(pgb);

            var specialList = service.GetList <DeployEntity>(pgMain).ToList();

            //分页查询
            long allRowsCount = 0;
            var  pageList     = service.GetPageList <DeployEntity>(1, 2, out allRowsCount);
        }
        //TODO Patch libmeta here
        public int Execute(Entity dataModel)
        {
            ProjectEntity        project           = ProjectEntity.Decorate(dataModel.Root);
            CodeEntity           projectCodeEntity = CodeEntity.Decorate(project);
            string               projectName       = projectCodeEntity.Namespace;
            IEnumerable <Entity> targets           = project.Targets.ToArray();

            if (!targets.Any())
            {
                throw new FormattableException("Please use --target to specify for which targets the library shall be generated.");
            }
            Dictionary <Entity, VirtualFile> projectLibraries = targets.ToDictionary(t => t, FindLibrary);
            List <string>      externalLibraries = new List <string>();
            List <VirtualFile> deletableFiles    = new List <VirtualFile>();

            foreach (Entity target in targets)
            {
                CopyExternalLibrariesToOutputDirectory(target, projectLibraries,
                                                       out IEnumerable <string> libraries,
                                                       out IEnumerable <VirtualFile> toBeDeleted);
                externalLibraries.AddRange(libraries);
                deletableFiles.AddRange(toBeDeleted);
            }
            CheckMetaFiles(targets.First());

            string commandOptionsFile = GenerateCommandOptions(project, projectLibraries, projectName);
            int    result             = ExecuteLibraryBuilderWithCommandOptions(commandOptionsFile, project);

            foreach (VirtualFile deletable in deletableFiles)
            {
                deletable.Delete();
            }

            return(result);

            VirtualFile FindLibrary(Entity target)
            {
                VirtualDirectory deployDirectory = DeployEntity.Decorate(target).DeployDirectory;

                string libFile = deployDirectory.Files("*.so", true)
                                 .OrderByDescending(f => f.Name.Equals($"lib{projectName}.so", StringComparison.OrdinalIgnoreCase))
                                 .ThenByDescending(f => f.LastWriteTime)
                                 .FirstOrDefault()
                                 ?.FullName;

                if (string.IsNullOrEmpty(libFile))
                {
                    throw new LibraryNotFoundException(deployDirectory.FullName);
                }

                VirtualFile file = fileSystem.GetFile(libFile);

                return(file);
            }

            void CheckMetaFiles(Entity target)
            {
                TemplateEntity   projectTemplateEntity = TemplateEntity.Decorate(project);
                VirtualDirectory deployDirectory       = DeployEntity.Decorate(target).DeployDirectory;

                if (!fileSystem.FileExists(Path.Combine(deployDirectory.FullName, $"{projectName}.libmeta")))
                {
                    throw new MetaLibraryNotFoundException(deployDirectory.FullName);
                }

                PatchLibmeta(fileSystem.GetFile(Path.Combine(deployDirectory.FullName, $"{projectName}.libmeta")));
                IEnumerable <VirtualFile> metaFiles = deployDirectory.Files(searchRecursive: true);

                IEnumerable <Entity> componentsWithoutMetaFile = projectTemplateEntity.EntityHierarchy
                                                                 .Where(e => e.Type.Equals("component", StringComparison.OrdinalIgnoreCase))
                                                                 .Where(c => !metaFiles.Any(f => f.Name.Equals($"{c.Name}.{Constants.CompmetaExtension}",
                                                                                                               StringComparison.Ordinal)))
                                                                 .ToArray();

                if (componentsWithoutMetaFile.Any())
                {
                    throw new MetaFileNotFoundException(deployDirectory.FullName, $"{componentsWithoutMetaFile.First().Name}.{Constants.CompmetaExtension}");
                }

                IEnumerable <Entity> programsWithoutMetaFile = projectTemplateEntity.EntityHierarchy
                                                               .Where(e => e.Type.Equals("program", StringComparison.OrdinalIgnoreCase))
                                                               .Where(p => !metaFiles.Any(f => f.Name.Equals($"{p.Name}.{Constants.ProgmetaExtension}",
                                                                                                             StringComparison.Ordinal)))
                                                               .ToArray();

                if (programsWithoutMetaFile.Any())
                {
                    throw new MetaFileNotFoundException(deployDirectory.FullName, $"{programsWithoutMetaFile.First().Name}.{Constants.ProgmetaExtension}");
                }
            }

            void PatchLibmeta(VirtualFile libmetaFile)
            {
                if (!externalLibraries.Any())
                {
                    return;
                }
                XmlSerializer             serializer = new XmlSerializer(typeof(MetaConfigurationDocument));
                MetaConfigurationDocument document;

                try
                {
                    using (Stream fileStream = libmetaFile.OpenRead())
                        using (XmlReader reader = XmlReader.Create(fileStream))
                        {
                            document = (MetaConfigurationDocument)serializer.Deserialize(reader);
                        }
                }
                catch (XmlException e)
                {
                    executionContext.WriteWarning($"Cannot parse libmeta file. Cannot patch dependencies. {e.Message}");
                    return;
                }

                document.schemaVersion = "4.0";
                LibraryDefinition    definition   = (LibraryDefinition)document.Item;
                IEnumerable <string> dependencies = externalLibraries.Select(Path.GetFileName)
                                                    .Concat(definition.Dependencies?.Select(d => d.path) ??
                                                            Enumerable.Empty <string>());

                definition.Dependencies = dependencies.Select(d => new DependencyDefinition {
                    path = d
                }).ToArray();

                using (Stream fileStream = libmetaFile.OpenWrite())
                    using (XmlWriter writer = XmlWriter.Create(fileStream, new XmlWriterSettings
                    {
                        Indent = true
                    }))
                    {
                        serializer.Serialize(writer, document);
                    }
            }
        }
        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));
            }
        }