// Copyright Keysight Technologies 2012-2019 // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, you can obtain one at http://mozilla.org/MPL/2.0/. using OpenTap.Cli; using System; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; namespace OpenTap.Sdk.New { public abstract class GenerateType : ICliAction { internal bool Validate(string name, bool allowWhiteSpace, bool allowLeadingNumbers, bool allowAlphaNumericOnly) { bool anyInvalid = false; var invalid = Path.GetInvalidFileNameChars(); var sb = new StringBuilder(); var leading = !allowLeadingNumbers; foreach (var ch in name) { if (leading && char.IsNumber(ch)) { sb.Append("^"); anyInvalid = true; continue; } leading = false; // Then detect any invalid filename or C# identifier chars if (invalid.Contains(ch) || (!allowWhiteSpace && char.IsWhiteSpace(ch)) || (allowAlphaNumericOnly && !char.IsLetterOrDigit(ch) && ch != '_')) { sb.Append("^"); anyInvalid = true; } else sb.Append(" "); } if (!anyInvalid) return true; var stringStart = "Invalid name specified: '"; log.Error($"{stringStart}{name}' contains illegal characters."); var hint = sb.ToString(); log.Error(hint.PadLeft(stringStart.Length + hint.Length)); return false; } public static TraceSource log = Log.CreateSource("New"); [CommandLineArgument("out", ShortName = "o", Description = "Path to generated file.")] public virtual string output { get; set; } private string workingDirectory; internal string WorkingDirectory { get { if (string.IsNullOrEmpty(workingDirectory)) return Directory.GetCurrentDirectory(); return workingDirectory; } set => workingDirectory = value; } public abstract int Execute(CancellationToken cancellationToken); public bool WriteFile(string filepath, string content, bool force = false) { if (File.Exists(filepath) && force == false) { log.Error("File already exists: '{0}'", Path.GetFileName(filepath)); log.Info("Do you want to override?"); var request = new OverrideRequest(); UserInput.Request(request, true); if (request.Override == RequestEnum.No) { log.Info("File was not overridden."); return false; } } if (!Directory.Exists(Path.GetDirectoryName(filepath)) && string.IsNullOrWhiteSpace(Path.GetDirectoryName(filepath)) == false) Directory.CreateDirectory(Path.GetDirectoryName(filepath)); File.WriteAllText(filepath, content); log.Info($"Generated file: '{filepath}'."); return true; } protected string TryGetNamespace() { string dir = output; if (output == null) dir = WorkingDirectory; else if (output.EndsWith("/") == false) dir = Path.GetDirectoryName(dir); var csprojFiles = Directory.GetFiles(dir, "*.csproj", SearchOption.AllDirectories); var csprojPath = csprojFiles.FirstOrDefault(); if (string.IsNullOrWhiteSpace(csprojPath) == false) { var match = Regex.Match(File.ReadAllText(csprojPath), "(.*/)"); if (match.Success) return match.Groups[1].Value; else return Path.GetFileNameWithoutExtension(csprojPath); } throw new Exception($"Could not find project file ('.csproj') in '{dir}'.\nNote: You can create a new project with 'tap sdk new project '."); } protected string ReplaceInTemplate(string content, params string[] fields) { content = Regex.Replace(content, "\\{(\\d)\\}", (m) => { if (int.TryParse(m.Groups[1].Value, out int index) && index < fields.Length) return fields[index]; else return ""; }); return content; } } public class OverrideRequest { [Layout(LayoutMode.FloatBottom | LayoutMode.FullRow)] [Submit] public RequestEnum Override { get; set; } } public enum RequestEnum { Yes, No } }