1 #region Copyright notice and license
2 
3 // Copyright 2018 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #endregion
18 
19 using System;
20 using System.IO;
21 using System.Runtime.CompilerServices;
22 using System.Runtime.InteropServices;
23 using System.Security;
24 
25 [assembly: InternalsVisibleTo("Grpc.Tools.Tests")]
26 
27 namespace Grpc.Tools
28 {
29     // Metadata names (MSBuild item attributes) that we refer to often.
30     static class Metadata
31     {
32         // On output dependency lists.
33         public static string Source = "Source";
34         // On Protobuf items.
35         public static string ProtoRoot = "ProtoRoot";
36         public static string OutputDir = "OutputDir";
37         public static string GrpcServices = "GrpcServices";
38         public static string GrpcOutputDir = "GrpcOutputDir";
39     };
40 
41     // A few flags used to control the behavior under various platforms.
42     internal static class Platform
43     {
44         public enum OsKind { Unknown, Windows, Linux, MacOsX };
45         public static readonly OsKind Os;
46 
47         public enum CpuKind { Unknown, X86, X64 };
48         public static readonly CpuKind Cpu;
49 
50         // This is not necessarily true, but good enough. BCL lacks a per-FS
51         // API to determine file case sensitivity.
52         public static bool IsFsCaseInsensitive => Os == OsKind.Windows;
53         public static bool IsWindows => Os == OsKind.Windows;
54 
Platform()55         static Platform()
56         {
57 #if NETCORE
58             Os = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? OsKind.Windows
59                : RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? OsKind.Linux
60                : RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? OsKind.MacOsX
61                : OsKind.Unknown;
62 
63             switch (RuntimeInformation.ProcessArchitecture)
64             {
65                 case Architecture.X86: Cpu = CpuKind.X86; break;
66                 case Architecture.X64: Cpu = CpuKind.X64; break;
67                 // We do not have build tools for other architectures.
68                 default: Cpu = CpuKind.Unknown; break;
69             }
70 #else
71             // Running under either Mono or full MS framework.
72             Os = OsKind.Windows;
73             if (Type.GetType("Mono.Runtime", throwOnError: false) != null)
74             {
75                 // Congratulations. We are running under Mono.
76                 var plat = Environment.OSVersion.Platform;
77                 if (plat == PlatformID.MacOSX)
78                 {
79                     Os = OsKind.MacOsX;
80                 }
81                 else if (plat == PlatformID.Unix || (int)plat == 128)
82                 {
83                     // This is how Mono detects OSX internally.
84                     Os = File.Exists("/usr/lib/libc.dylib") ? OsKind.MacOsX : OsKind.Linux;
85                 }
86             }
87 
88             // Hope we are not building on ARM under Xamarin!
89             Cpu = Environment.Is64BitProcess ? CpuKind.X64 : CpuKind.X86;
90 #endif
91         }
92     };
93 
94     // Exception handling helpers.
95     static class Exceptions
96     {
97         // Returns true iff the exception indicates an error from an I/O call. See
98         // https://github.com/Microsoft/msbuild/blob/v15.4.8.50001/src/Shared/ExceptionHandling.cs#L101
99         static public bool IsIoRelated(Exception ex) =>
100             ex is IOException ||
101             (ex is ArgumentException && !(ex is ArgumentNullException)) ||
102             ex is SecurityException ||
103             ex is UnauthorizedAccessException ||
104             ex is NotSupportedException;
105     };
106 
107     // String helpers.
108     static class Strings
109     {
110         // Compare string to argument using OrdinalIgnoreCase comparison.
EqualNoCase(this string a, string b)111         public static bool EqualNoCase(this string a, string b) =>
112             string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
113     }
114 }
115