< Summary

Class:DCL.Protobuf.ProtobufEditor
Assembly:DCL.Protobuf
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ProtocolBuffers/Editor/ProtobufEditor.cs
Covered lines:0
Uncovered lines:263
Coverable lines:263
Total lines:627
Line coverage:0% (0 of 263)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ProtobufEditor()0%2100%
VerboseLog(...)0%2100%
UpdateModels()0%2100%
UpdateModels(...)0%6200%
DownloadLatestProtoDefinitions()0%2100%
DownloadProtoDefinitions(...)0%42600%
GetComponents()0%20400%
GetComponentsCommon()0%12300%
GenerateComponentCode()0%2100%
GenerateComponentCode(...)0%72800%
CreateTempDefinitions()0%6200%
GenerateComponentIdEnum(...)0%20400%
CompileAllComponents(...)0%12300%
CompileComponentsCommon(...)0%12300%
ExecProtoCompilerCommand(...)0%6200%
AddNamespaceAndPackage()0%42600%
IsProtoVersionValid()0%6200%
GetVersion(...)0%6200%
WriteVersion(...)0%2100%
WriteVersion(...)0%2100%
GetDownloadedVersion()0%2100%
GetCompiledVersion()0%2100%
GetLatestProtoVersion()0%6200%
DownloadProtobuffExecutable()0%20400%
GetPathToProto()0%2100%
AddExecutablePermisson(...)0%6200%
Untar(...)0%12300%
Unzip(...)0%2100%
OnProjectCompile(...)0%2100%
OnProjectCompile()0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ProtocolBuffers/Editor/ProtobufEditor.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Diagnostics;
 4using System.IO;
 5using System.Linq;
 6using System.Net;
 7using System.Text;
 8using System.Text.RegularExpressions;
 9using UnityEditor;
 10using UnityEngine;
 11using Debug = UnityEngine.Debug;
 12
 13using Newtonsoft.Json;
 14
 15using System.IO.Compression;
 16using UnityEditor.Compilation;
 17using ICSharpCode.SharpZipLib.GZip;
 18using ICSharpCode.SharpZipLib.Tar;
 19using ICSharpCode.SharpZipLib.Zip;
 20
 21namespace DCL.Protobuf
 22{
 23    [InitializeOnLoad]
 24    public static class ProtobufEditor
 25    {
 26        static ProtobufEditor()
 27        {
 028            CompilationPipeline.compilationStarted += OnProjectCompile;
 029            OnProjectCompile();
 030        }
 31
 32        private const bool VERBOSE = true;
 33
 34        private const string PATH_TO_GENERATED = "/DCLPlugins/ECS7/ProtocolBuffers/Generated/";
 35        private const string REALPATH_TO_COMPONENTS_DEFINITIONS = "/DCLPlugins/ECS7/ProtocolBuffers/Definitions";
 36        private const string PATH_TO_COMPONENTS = "/DCLPlugins/ECS7/ProtocolBuffers/Generated/PBFiles";
 37        private const string SUBPATH_TO_COMPONENTS_COMMON = "/Common";
 38        private const string TEMPPATH_TO_COMPONENTS_DEFINITIONS = "/DCLPlugins/ECS7/ProtocolBuffers/DefinitionsTemp";
 39        private const string PATHNAME_TO_COMPONENTS_DEFINITIONS_COMMON = "common";
 40        private const string PATH_TO_COMPONENT_IDS = "/DCLPlugins/ECS7/ProtocolBuffers/Generated/ComponentID/ComponentID
 41        private const string PATH_TO_FOLDER = "/DCLPlugins/ECS7/ProtocolBuffers/Editor/";
 42        private const string PATH_TO_PROTO = "/DCLPlugins/ECS7/ProtocolBuffers/Editor/bin/";
 43
 44        private const string PROTO_FILENAME = "protoc";
 45        private const string DOWNLOADED_VERSION_FILENAME = "downloadedVersion.gen.txt";
 46        private const string COMPILED_VERSION_FILENAME = "compiledVersion.gen.txt";
 47        private const string EXECUTABLE_VERSION_FILENAME = "executableVersion.gen.txt";
 48
 49        private const string PROTO_VERSION = "3.20.1";
 50
 51        // Use this parameter when you want a fixed version of the @dcl/protocol, otherwise leave it empty
 52        //private const string FIXED_NPM_PACKAGE_LINK = "https://sdk-team-cdn.decentraland.org/@dcl/protocol/branch//dcl
 53        private const string FIXED_NPM_PACKAGE_LINK = "";
 54
 55        private const string NPM_PACKAGE = "@dcl/protocol";
 56        private const string NPM_PACKAGE_PROTO_DEF = "/package/ecs/components/";
 57
 58        private struct ProtoComponent
 59        {
 60            public string componentName;
 61            public int componentId;
 62        }
 63
 64        private static void VerboseLog(string message)
 65        {
 66            if (VERBOSE)
 67            {
 068                Debug.Log(message);
 69            }
 070        }
 71
 72        [MenuItem("Decentraland/Protobuf/UpdateModels with the latest version")]
 73        public static void UpdateModels()
 74        {
 075            var lastVersion = GetLatestProtoVersion();
 076            UpdateModels(lastVersion);
 077        }
 78
 79        public static void UpdateModels(string version)
 80        {
 081            if (!IsProtoVersionValid())
 082                DownloadProtobuffExecutable();
 83
 084             DownloadProtoDefinitions(version);
 085             GenerateComponentCode(version);
 086             CompilationPipeline.RequestScriptCompilation();
 087        }
 88
 89        [MenuItem("Decentraland/Protobuf/Download latest proto definitions (For debugging)")]
 90        public static void DownloadLatestProtoDefinitions()
 91        {
 092            var nextVersion = GetLatestProtoVersion();
 093            DownloadProtoDefinitions(nextVersion);
 094        }
 95
 96        public static void DownloadProtoDefinitions(string version)
 97        {
 98            WebClient client;
 99            Stream data;
 100            StreamReader reader;
 101            string libraryJsonString;
 102            Dictionary<string, object> libraryContent, libraryInfo;
 103
 0104            VerboseLog("Downloading " + NPM_PACKAGE + " version: " + version);
 105
 106            // Download the "package.json" of {NPM_PACKAGE}@version
 0107            client = new WebClient();
 0108            data = client.OpenRead(@"https://registry.npmjs.org/" + NPM_PACKAGE + "/" + version);
 0109            reader = new StreamReader(data);
 0110            libraryJsonString = reader.ReadToEnd();
 0111            data.Close();
 0112            reader.Close();
 113
 114            // Process the response
 0115            libraryContent = JsonConvert.DeserializeObject<Dictionary<string, object>>(libraryJsonString);
 0116            libraryInfo = JsonConvert.DeserializeObject<Dictionary<string, object>>(libraryContent["dist"].ToString());
 117
 0118            string tgzUrl = libraryInfo["tarball"].ToString();
 119
 120            // If we have a fixed version, use it
 0121            if (FIXED_NPM_PACKAGE_LINK.Length > 0) {
 0122                tgzUrl = FIXED_NPM_PACKAGE_LINK;
 123            }
 124
 0125            VerboseLog(NPM_PACKAGE + "@" + version + "url: " + tgzUrl);
 126
 127            // Download package
 0128            string packageWithoutSlash = NPM_PACKAGE.Replace("/", "-"); // Replace / because in the file system is inter
 0129            string packageName = packageWithoutSlash + "-" + version + ".tgz";
 0130            client = new WebClient();
 0131            client.DownloadFile(tgzUrl, packageName);
 0132            VerboseLog("File downloaded " + packageName);
 133
 0134            string destPackage = packageWithoutSlash + "-" + version;
 0135            if (Directory.Exists(destPackage))
 0136                Directory.Delete(destPackage, true);
 137
 138            try
 139            {
 0140                Directory.CreateDirectory(destPackage);
 141
 0142                Untar(packageName,destPackage);
 0143                VerboseLog("Untar " + packageName);
 144
 0145                if (File.Exists(destPackage + NPM_PACKAGE_PROTO_DEF + "/" + PATHNAME_TO_COMPONENTS_DEFINITIONS_COMMON + 
 146                {
 0147                    File.Delete(destPackage + NPM_PACKAGE_PROTO_DEF + "/" + PATHNAME_TO_COMPONENTS_DEFINITIONS_COMMON + 
 148                }
 149
 0150                string componentDefinitionPath = Application.dataPath + REALPATH_TO_COMPONENTS_DEFINITIONS;
 151
 0152                if (Directory.Exists(componentDefinitionPath))
 0153                    Directory.Delete(componentDefinitionPath, true);
 154
 155                // We move the definitions to their correct path
 0156                Directory.Move(destPackage + NPM_PACKAGE_PROTO_DEF, componentDefinitionPath);
 157
 0158                VerboseLog("Success copying definitions in " + componentDefinitionPath);
 159
 0160            }
 0161            catch (Exception e)
 162            {
 0163                Debug.LogError("The download has failed " + e.Message);
 0164            }
 165            finally // We delete the downloaded package
 166            {
 0167                Directory.Delete(destPackage, true);
 0168                if (File.Exists(packageName))
 0169                    File.Delete(packageName);
 0170            }
 0171        }
 172
 173        private static List<ProtoComponent> GetComponents()
 174        {
 175            // We get all the files that are proto
 0176            DirectoryInfo dir = new DirectoryInfo(Application.dataPath + REALPATH_TO_COMPONENTS_DEFINITIONS);
 0177            FileInfo[] info = dir.GetFiles("*.proto");
 0178            List<ProtoComponent> components = new List<ProtoComponent>();
 179
 0180            foreach (FileInfo file in info)
 181            {
 182                // We ensure that only proto files are converted, this shouldn't be necessary but just in case
 0183                if (!file.Name.Contains(".proto"))
 184                    continue;
 185
 0186                string protoContent = File.ReadAllText(file.FullName);
 187
 0188                ProtoComponent component = new ProtoComponent();
 0189                component.componentName = file.Name.Substring(0, file.Name.Length - 6);
 0190                component.componentId = -1;
 191
 0192                Regex regex = new Regex(@" *option +\(ecs_component_id\) += +[0-9]+ *;");
 0193                var result = regex.Match(protoContent);
 0194                if (result.Length > 0)
 195                {
 0196                    string componentIdStr = result.Value.Split('=')[1].Split(';')[0];
 0197                    component.componentId = int.Parse(componentIdStr);
 198                }
 199
 0200                components.Add(component);
 201            }
 202
 0203            return components;
 204        }
 205
 206        private static List<string> GetComponentsCommon()
 207        {
 208            // We get all the files that are proto
 0209            DirectoryInfo dir = new DirectoryInfo(Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS + "/" + PATH
 0210            FileInfo[] info = dir.GetFiles("*.proto");
 0211            List<string> components = new List<string>();
 212
 0213            foreach (FileInfo file in info)
 214            {
 215                // We ensure that only proto files are converted, this shouldn't be necessary but just in case
 0216                if (!file.Name.Contains(".proto"))
 217                    continue;
 218
 0219                components.Add(file.Name);
 220            }
 221
 0222            return components;
 223        }
 224        [MenuItem("Decentraland/Protobuf/Regenerate models (For debugging)")]
 225        public static void GenerateComponentCode()
 226        {
 0227            GenerateComponentCode("LocalMachine");
 0228        }
 229
 230        public static void GenerateComponentCode(string versionNameToCompile)
 231        {
 0232            Debug.Log("Starting regenerate ");
 0233            bool ok = false;
 234
 0235            string tempOutputPath = Application.dataPath + PATH_TO_COMPONENTS + "temp";
 236            try
 237            {
 0238                List<ProtoComponent> components = GetComponents();
 0239                components = components.OrderBy( component => component.componentId).ToList();
 240
 0241                if (Directory.Exists(tempOutputPath))
 242                {
 0243                    Directory.Delete(tempOutputPath, true);
 244                }
 0245                Directory.CreateDirectory(tempOutputPath);
 0246                Directory.CreateDirectory(tempOutputPath + SUBPATH_TO_COMPONENTS_COMMON);
 247
 0248                CreateTempDefinitions();
 0249                AddNamespaceAndPackage();
 250
 0251                ok = CompileAllComponents(components, tempOutputPath);
 0252                ok &= CompileComponentsCommon(tempOutputPath + SUBPATH_TO_COMPONENTS_COMMON);
 253
 0254                if (ok)
 0255                    GenerateComponentIdEnum(components);
 0256            }
 0257            catch (Exception e)
 258            {
 0259                Debug.LogError("The component code generation has failed: " + e.Message);
 0260            }
 261
 0262            if (ok)
 263            {
 0264                string outputPath = Application.dataPath + PATH_TO_COMPONENTS;
 0265                if (Directory.Exists(outputPath))
 0266                    Directory.Delete(outputPath, true);
 267
 0268                Directory.Move(tempOutputPath, outputPath);
 269
 0270                string path = Application.dataPath + PATH_TO_FOLDER;
 0271                WriteVersion(versionNameToCompile, COMPILED_VERSION_FILENAME, path);
 0272            }
 0273            else if (Directory.Exists(tempOutputPath))
 274            {
 0275                Directory.Delete(tempOutputPath, true);
 276            }
 277
 0278            if (Directory.Exists(Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS)) {
 0279                Directory.Delete(Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS, true);
 280            }
 0281        }
 282
 283        private static void CreateTempDefinitions()
 284        {
 0285            if (Directory.Exists(Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS))
 0286                Directory.Delete(Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS, true);
 287
 0288            ProtobufEditorHelper.CloneDirectory(Application.dataPath + REALPATH_TO_COMPONENTS_DEFINITIONS, Application.d
 0289        }
 290
 291        private static void GenerateComponentIdEnum(List<ProtoComponent> components)
 292        {
 0293            string componentCsFileContent = "/* Autogenerated file, DO NOT EDIT! */\n\nnamespace DCL.ECS7\n{\n    public
 294
 0295            componentCsFileContent += $"        public const int TRANSFORM = 1;\n";
 0296            foreach (ProtoComponent component in components )
 297            {
 0298                string componentUpperCaseName = ProtobufEditorHelper.ToSnakeCase(component.componentName).ToUpper();
 299
 300                // Special case where NFT is created from NFTProto, instead of N_F_T_SHAPE we set NFT_SHAPE
 0301                if (componentUpperCaseName.Contains("N_F_T"))
 0302                    componentUpperCaseName = "NFT_SHAPE";
 303
 304                // Special case where GLTF is created from GLTFProto, instead of G_L_T_F_SHAPE we set GLTF_SHAPE
 0305                if (componentUpperCaseName.Contains("G_L_T_F"))
 0306                    componentUpperCaseName = "GLTF_SHAPE";
 307
 0308                componentCsFileContent += $"        public const int {componentUpperCaseName} = {component.componentId.T
 309            }
 0310            componentCsFileContent += "    }\n}\n";
 311
 0312            File.WriteAllText(Application.dataPath + PATH_TO_COMPONENT_IDS, componentCsFileContent);
 0313        }
 314
 315        private static bool CompileAllComponents(List<ProtoComponent> components, string outputPath)
 316        {
 0317            if (components.Count == 0)
 318            {
 0319                UnityEngine.Debug.LogError("There are no components to generate!!");
 0320                return false;
 321            }
 322
 323            // We prepare the paths for the conversion
 0324            string filePath = Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS;
 325
 0326            List<string> paramsArray = new List<string>
 327            {
 328                $"--csharp_out \"{outputPath}\"",
 329                $"--proto_path \"{filePath}\""
 330            };
 331
 0332            foreach(ProtoComponent component in components)
 333            {
 0334                paramsArray.Add($"\"{filePath}/{component.componentName}.proto\"");
 335            }
 336
 0337            return ExecProtoCompilerCommand(string.Join(" ", paramsArray));
 338        }
 339
 340        private static bool CompileComponentsCommon(string outputPath)
 341        {
 0342            List<string> commonFiles = GetComponentsCommon();
 343
 0344            if (commonFiles.Count == 0)
 0345                return true;
 346
 347            // We prepare the paths for the conversion
 0348            string filePath = Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS + "/" + PATHNAME_TO_COMPONENTS_D
 349
 0350            List<string> paramsArray = new List<string>
 351            {
 352                $"--csharp_out \"{outputPath}\"",
 353                $"--proto_path \"{filePath}\""
 354            };
 355
 0356            foreach(string protoFile in commonFiles)
 357            {
 0358                paramsArray.Add($"\"{filePath}/{protoFile}\"");
 359            }
 360
 0361            return ExecProtoCompilerCommand(string.Join(" ", paramsArray));
 362        }
 363
 364        private static bool ExecProtoCompilerCommand(string finalArguments)
 365        {
 0366            string proto_path = GetPathToProto();
 367
 368            // This is the console to convert the proto
 0369            ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = proto_path, Arguments = finalArguments };
 370
 0371            Process proc = new Process() { StartInfo = startInfo };
 0372            proc.StartInfo.UseShellExecute = false;
 0373            proc.StartInfo.RedirectStandardOutput = true;
 0374            proc.StartInfo.RedirectStandardError = true;
 0375            proc.Start();
 376
 0377            string error = proc.StandardError.ReadToEnd();
 0378            proc.WaitForExit();
 379
 0380            if (error != "")
 381            {
 0382                UnityEngine.Debug.LogError("Protobuf Unity failed : " + error);
 0383                return false;
 384            }
 0385            return true;
 386        }
 387
 388        private static void AddNamespaceAndPackage()
 389        {
 390            // We get all the files that are proto
 0391            DirectoryInfo dir = new DirectoryInfo(Application.dataPath + TEMPPATH_TO_COMPONENTS_DEFINITIONS);
 0392            FileInfo[] info = dir.GetFiles("*.proto");
 393
 0394            foreach (FileInfo file in info)
 395            {
 396                // We ensure that only proto files are converted, this shouldn't be necessary but just in case
 0397                if (!file.Name.Contains(".proto"))
 398                    continue;
 399
 0400                string protoContent = File.ReadAllText(file.FullName);
 0401                List<string> lines = protoContent.Split('\n').ToList();
 0402                List<string> outLines = new List<string>();
 403
 0404                foreach ( string line in lines )
 405                {
 0406                    if (line.IndexOf(PATHNAME_TO_COMPONENTS_DEFINITIONS_COMMON + "/id.proto") == -1 && line.IndexOf("(ec
 407                    {
 0408                        outLines.Add(line);
 409                    }
 410                }
 411
 0412                outLines.Add("package decentraland.ecs;");
 0413                outLines.Add("option csharp_namespace = \"DCL.ECSComponents\";");
 414
 0415                File.WriteAllLines(file.FullName, outLines.ToArray());
 416            }
 0417        }
 418
 419        private static bool IsProtoVersionValid()
 420        {
 0421            string path = Application.dataPath + PATH_TO_GENERATED + EXECUTABLE_VERSION_FILENAME;
 0422            string version = GetVersion(path);
 0423            string protoPath = GetPathToProto();
 424
 425            // If we are in windows, we add the extension of the file
 426#if UNITY_EDITOR_WIN
 427            protoPath += ".exe";
 428#endif
 0429            return version == PROTO_VERSION && File.Exists(protoPath);
 430        }
 431
 432        private static string GetVersion(string path)
 433        {
 0434            if (!File.Exists(path))
 0435                return "";
 436
 0437            StreamReader reader = new StreamReader(path);
 0438            string version = reader.ReadToEnd();
 0439            reader.Close();
 440
 0441            return version;
 442        }
 443
 444        private static void WriteVersion(string version, string filename)
 445        {
 0446            string path = Application.dataPath + PATH_TO_GENERATED + "/";
 0447            WriteVersion(version, filename, path);
 0448        }
 449
 450        private static void WriteVersion(string version, string filename, string path)
 451        {
 0452            string filePath = path + filename;
 0453            var sr = File.CreateText(filePath);
 0454            sr.Write(version);
 0455            sr.Close();
 0456        }
 457
 458        private static string GetDownloadedVersion()
 459        {
 0460            string path = Application.dataPath + PATH_TO_GENERATED + "/" + DOWNLOADED_VERSION_FILENAME;
 0461            return GetVersion(path);
 462        }
 463
 464        private static string GetCompiledVersion()
 465        {
 0466            string path = Application.dataPath + PATH_TO_FOLDER + COMPILED_VERSION_FILENAME;
 0467            return GetVersion(path);
 468        }
 469
 470        public static string GetLatestProtoVersion()
 471        {
 472            WebClient client;
 473            Stream data;
 474            StreamReader reader;
 475            string libraryJsonString;
 476            Dictionary<string, object> libraryContent, libraryInfo;
 477
 478            // Download the data of decentraland-/ecs
 0479            client = new WebClient();
 0480            data = client.OpenRead(@"https://registry.npmjs.org/" + NPM_PACKAGE);
 0481            if (data == null)
 482            {
 0483                return "";
 484            }
 485
 0486            reader = new StreamReader(data);
 0487            libraryJsonString = reader.ReadToEnd();
 0488            data.Close();
 0489            reader.Close();
 490
 491            // Process the response
 0492            libraryContent = JsonConvert.DeserializeObject<Dictionary<string, object>>(libraryJsonString);
 0493            libraryInfo = JsonConvert.DeserializeObject<Dictionary<string, object>>(libraryContent["dist-tags"].ToString
 494
 0495            string nextVersion = libraryInfo["next"].ToString();
 0496            return nextVersion;
 497        }
 498
 499        [MenuItem("Decentraland/Protobuf/Download proto executable")]
 500        public static void DownloadProtobuffExecutable()
 501        {
 502            // Download package
 0503            string machine  = null;
 0504            string executableName = "protoc";
 505#if UNITY_EDITOR_WIN
 506            machine = "win64";
 507            executableName = "protoc.exe";
 508#elif UNITY_EDITOR_OSX
 509            machine = "osx-x86_64";
 510#elif UNITY_EDITOR_LINUX
 0511            machine = "linux-x86_64";
 512#endif
 513            // We download the proto executable
 0514            string name = $"protoc-{PROTO_VERSION}-{machine}.zip";
 0515            string url = $"https://github.com/protocolbuffers/protobuf/releases/download/v{PROTO_VERSION}/{name}";
 0516            string zipProtoFileName = "protoc";
 0517            WebClient client = new WebClient();
 0518            client.DownloadFile(url, zipProtoFileName);
 0519            string destPackage = "protobuf";
 520
 521            try
 522            {
 0523                Directory.CreateDirectory(destPackage);
 524
 525                // We unzip the proto executable
 0526                Unzip(zipProtoFileName,destPackage);
 527
 528                if (VERBOSE)
 0529                    UnityEngine.Debug.Log("Unzipped protoc");
 530
 0531                string outputPathDir = Application.dataPath + PATH_TO_PROTO ;
 0532                string outputPath = outputPathDir + executableName;
 533
 0534                if (File.Exists(outputPath))
 0535                    File.Delete(outputPath);
 536
 0537                if (!Directory.Exists(outputPathDir))
 0538                    Directory.CreateDirectory(outputPathDir);
 539
 540                // We move the executable to his correct path
 0541                Directory.Move(destPackage + "/bin/" + executableName, outputPath);
 542
 543#if UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX
 0544                AddExecutablePermisson(GetPathToProto());
 545#endif
 546
 0547                WriteVersion(PROTO_VERSION, EXECUTABLE_VERSION_FILENAME);
 0548            }
 0549            catch (Exception e)
 550            {
 0551                Debug.LogError("The download of the executable has failed " + e.Message);
 0552            }
 553            finally
 554            {
 555                // We removed everything has has been created and it is not usefull anymore
 0556                File.Delete(zipProtoFileName);
 0557                if (Directory.Exists(destPackage))
 0558                    Directory.Delete(destPackage, true);
 0559            }
 0560        }
 561
 562        private static string GetPathToProto()
 563        {
 0564            return Application.dataPath + PATH_TO_PROTO + PROTO_FILENAME;
 565        }
 566
 567#if UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX
 568        private static bool AddExecutablePermisson(string path)
 569        {
 570            // This is the console to convert the proto
 0571            ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "chmod", Arguments = $"+x \"{path}\"" };
 572
 0573            Process proc = new Process() { StartInfo = startInfo };
 0574            proc.StartInfo.UseShellExecute = false;
 0575            proc.StartInfo.RedirectStandardOutput = true;
 0576            proc.StartInfo.RedirectStandardError = true;
 0577            proc.Start();
 578
 0579            string error = proc.StandardError.ReadToEnd();
 0580            proc.WaitForExit();
 581
 0582            if (error != "")
 583            {
 0584                UnityEngine.Debug.LogError("`chmod +x protoc` failed : " + error);
 0585                return false;
 586            }
 0587            return true;
 588        }
 589#endif
 590
 591
 592        private static void Untar(string name, string path)
 593        {
 0594            using (Stream inStream = File.OpenRead (name))
 0595            using (Stream gzipStream = new GZipInputStream (inStream)) {
 0596                TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream, Encoding.ASCII);
 0597                tarArchive.ExtractContents (path);
 0598            }
 0599        }
 600
 601        private static void Unzip(string name, string path)
 602        {
 0603            FastZip fastZip = new FastZip();
 0604            string fileFilter = null;
 605
 0606            fastZip.ExtractZip(name, path, fileFilter);
 0607        }
 608
 609        private static void OnProjectCompile(object test)
 610        {
 0611            OnProjectCompile();
 0612        }
 613
 614        [MenuItem("Decentraland/Protobuf/Test project compile (For debugging)")]
 615        private static void OnProjectCompile()
 616        {
 617            // TODO: Delete this return line to make the generation of the proto based on your machine
 0618            return;
 619
 620            // The compiled version is a file that lives in the repo, if your local version is distinct it will generate
 621            var currentDownloadedVersion = GetDownloadedVersion();
 622            var currentVersion = GetCompiledVersion();
 623            if (currentVersion != currentDownloadedVersion)
 624                UpdateModels(currentVersion);
 625        }
 626    }
 627}