using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using ln.build.commands; using ln.build.semver; using ln.json; using ln.logging; namespace ln.build.pipeline { public class DefaultPipeLine { public CommandEnvironment CommandEnvironment { get; } public CIService CIService { get; } List stages = new List(); public IEnumerable Stages => stages; public Versioning Versioning { get; set; } List loadedTemplates = new List(); public IEnumerable LoadedTemplates => loadedTemplates; public DefaultPipeLine(CIService ciService) { CIService = ciService; CommandEnvironment = new CommandEnvironment(); } public DefaultPipeLine(CIService ciService, CommandEnvironment commandEnvironment) { CIService = ciService; CommandEnvironment = new CommandEnvironment(commandEnvironment); } public void LoadJson(JSONObject jsonPipeLine) { if (jsonPipeLine.ContainsKey("templates")) { foreach (JSONString jsonTemplateName in jsonPipeLine["templates"].Children) { if (!loadedTemplates.Contains(jsonTemplateName.Value)) { loadedTemplates.Add(jsonTemplateName.Value); string repoTemplate = Path.Combine(CommandEnvironment.WorkingDirectory, String.Format("{0}.ln", jsonTemplateName.Value)); string systemTemplate = Path.Combine(CIService.ContextDirectory, "scripts", "pipeline", String.Format("{0}.ln", jsonTemplateName.Value)); if (File.Exists(repoTemplate)) { LoadJson(JSONParser.ParseFile(repoTemplate) as JSONObject); } else if (File.Exists(systemTemplate)) { LoadJson(JSONParser.ParseFile(systemTemplate) as JSONObject); } else throw new FileNotFoundException(String.Format("{0}.ln", jsonTemplateName.Value)); } } } if (jsonPipeLine.ContainsKey("env")) CommandEnvironment.Apply(jsonPipeLine["env"] as JSONObject); if (jsonPipeLine.ContainsKey("stages")) { JSONArray jsonStages = jsonPipeLine["stages"] as JSONArray; foreach (JSONObject jsonStage in jsonStages.Children) { Stage stage = GetStage(jsonStage["name"].ToNative().ToString()); stage.LoadJson(jsonStage); } } if (jsonPipeLine.ContainsKey("versioning")) Versioning = new Versioning(jsonPipeLine["versioning"] as JSONObject); } public void Run() { foreach (Stage stage in stages) { CommandEnvironment.Logger.Log(LogLevel.INFO,"-------------------------------------------------------------------------------------"); CommandEnvironment.Logger.Log(LogLevel.INFO,"STAGE: {0}", stage.Name); CommandEnvironment.Logger.Log(LogLevel.INFO,"-------------------------------------------------------------------------------------"); stage.Run(); } } public Stage GetStage(string stageName) { foreach (Stage stage in stages) { if (stageName.Equals(stage.Name)) return stage; } Stage _stage = new Stage(this); _stage.Name = stageName; stages.Add(_stage); return _stage; } } public class Stage { public DefaultPipeLine PipeLine { get; } public string Name { get; set; } public int Priority { get; set; } public CommandEnvironment CommandEnvironment { get; } public List commands = new List(); public Stage(DefaultPipeLine pipeLine) { PipeLine = pipeLine; CommandEnvironment = new CommandEnvironment(pipeLine.CommandEnvironment); } public void LoadJson(JSONObject jsonStage) { Name = jsonStage["name"].ToNative().ToString(); if (jsonStage.ContainsKey("priority")) Priority = (int)(long)jsonStage["priority"].ToNative(); if (jsonStage.ContainsKey("env")) { CommandEnvironment.Apply(jsonStage["env"] as JSONObject); } if (jsonStage.ContainsKey("commands")) { JSONArray jsonCommands = jsonStage["commands"] as JSONArray; foreach (JSONValue jsonValue in jsonCommands.Children) { Logging.Log(LogLevel.DEBUG, "stage {0} command: {1}", Name, jsonValue.ToNative().ToString()); commands.Add(jsonValue.ToNative().ToString()); } } if (jsonStage.ContainsKey("secrets")) { JSONObject jsonSecrets = jsonStage["secrets"] as JSONObject; foreach (string key in jsonSecrets.Keys) { CommandEnvironment.Set(key, CommandEnvironment.SecretStorage?.GetSecret(jsonSecrets[key]?.ToNative()?.ToString())); } } } public void Run() { foreach (string command in commands) PipeLine.CIService.StageCommands.Run(this, command.Split()); } } }