From 223789b8cfbca3d55f420ccc01bec7a025807a14 Mon Sep 17 00:00:00 2001 From: Torben Rahbek Koch Date: Sat, 3 Sep 2016 10:53:36 +0200 Subject: [PATCH 1/5] Use file hash to check for file changes before transpiling (#299) --- src/React.Core/Babel.cs | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/React.Core/Babel.cs b/src/React.Core/Babel.cs index b42892473..7eebb6243 100644 --- a/src/React.Core/Babel.cs +++ b/src/React.Core/Babel.cs @@ -350,12 +350,36 @@ string filename ) { var outputPath = GetOutputPath(filename); - var sourceMapPath = GetSourceMapOutputPath(filename); var contents = _fileSystem.ReadAsString(filename); - var result = TransformWithHeader(filename, contents, null); - _fileSystem.WriteAsString(outputPath, result.Code); - _fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson()); - return outputPath; + if (MustTranspileFile(contents, outputPath)) + { + var result = TransformWithHeader(filename, contents, null); + + var sourceMapPath = GetSourceMapOutputPath(filename); + _fileSystem.WriteAsString(outputPath, result.Code); + _fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson()); + } + return outputPath; } + + /// + /// Checks whether an input file (given as inputFileContents) should be transpiled + /// by calculating the hash and comparing it to the hash value stored + /// in the file given by outputPath. If the outputPath file does not + /// exist the input file should always be transpiled. + /// + /// The contents of the input file. + /// The output path of the (possibly previously) generated file. + /// Returns true if the file should be transpiled, false otherwise. + public virtual bool MustTranspileFile(string inputFileContents, string outputPath) + { + if (!File.Exists(outputPath)) + return true; + + var hashForInputFile = _fileCacheHash.CalculateHash(inputFileContents); + var existingOutputContents = _fileSystem.ReadAsString(outputPath); + var fileHasNotChanged = _fileCacheHash.ValidateHash(existingOutputContents, hashForInputFile); + return !fileHasNotChanged; + } } } From 30cd33162e6d2e141fab1512adaf7784e70a7264 Mon Sep 17 00:00:00 2001 From: Torben Rahbek Koch Date: Sun, 4 Sep 2016 15:14:32 +0200 Subject: [PATCH 2/5] Add .editorconfig file --- src/.editorconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/.editorconfig diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 000000000..a127657e3 --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 4 +indent_style = tab +insert_final_newline = true + +[*.json] +indent_size = 2 +indent_style = space \ No newline at end of file From 36f9d1a2709d4bb826b18ee432aab5146e8ceb5c Mon Sep 17 00:00:00 2001 From: Torben Rahbek Koch Date: Sun, 4 Sep 2016 15:15:20 +0200 Subject: [PATCH 3/5] Add check for file hash check (#299) --- src/React.Core/Babel.cs | 53 ++++++++++--------- src/React.Tests/Core/BabelTransformerTests.cs | 28 ++++++++++ 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/React.Core/Babel.cs b/src/React.Core/Babel.cs index 7eebb6243..b891b5134 100644 --- a/src/React.Core/Babel.cs +++ b/src/React.Core/Babel.cs @@ -351,35 +351,36 @@ string filename { var outputPath = GetOutputPath(filename); var contents = _fileSystem.ReadAsString(filename); - if (MustTranspileFile(contents, outputPath)) - { - var result = TransformWithHeader(filename, contents, null); + if (CacheIsValid(contents, outputPath)) + return outputPath; + + var result = TransformWithHeader(filename, contents, null); - var sourceMapPath = GetSourceMapOutputPath(filename); - _fileSystem.WriteAsString(outputPath, result.Code); - _fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson()); - } - return outputPath; + var sourceMapPath = GetSourceMapOutputPath(filename); + _fileSystem.WriteAsString(outputPath, result.Code); + _fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson()); + + return outputPath; } - /// - /// Checks whether an input file (given as inputFileContents) should be transpiled - /// by calculating the hash and comparing it to the hash value stored - /// in the file given by outputPath. If the outputPath file does not - /// exist the input file should always be transpiled. - /// - /// The contents of the input file. - /// The output path of the (possibly previously) generated file. - /// Returns true if the file should be transpiled, false otherwise. - public virtual bool MustTranspileFile(string inputFileContents, string outputPath) - { - if (!File.Exists(outputPath)) - return true; + /// + /// Checks whether an input file (given as inputFileContents) should be transpiled + /// by calculating the hash and comparing it to the hash value stored + /// in the file given by outputPath. If the outputPath file does not + /// exist the input file should always be transpiled. + /// + /// The contents of the input file. + /// The output path of the (possibly previously) generated file. + /// Returns true if the file should be transpiled, false otherwise. + public virtual bool CacheIsValid(string inputFileContents, string outputPath) + { + if (!_fileSystem.FileExists(outputPath)) + return false; - var hashForInputFile = _fileCacheHash.CalculateHash(inputFileContents); - var existingOutputContents = _fileSystem.ReadAsString(outputPath); - var fileHasNotChanged = _fileCacheHash.ValidateHash(existingOutputContents, hashForInputFile); - return !fileHasNotChanged; - } + var hashForInputFile = _fileCacheHash.CalculateHash(inputFileContents); + var existingOutputContents = _fileSystem.ReadAsString(outputPath); + var fileHasNotChanged = _fileCacheHash.ValidateHash(existingOutputContents, hashForInputFile); + return fileHasNotChanged; + } } } diff --git a/src/React.Tests/Core/BabelTransformerTests.cs b/src/React.Tests/Core/BabelTransformerTests.cs index ed25300ce..cf0081dc1 100644 --- a/src/React.Tests/Core/BabelTransformerTests.cs +++ b/src/React.Tests/Core/BabelTransformerTests.cs @@ -32,6 +32,10 @@ public void SetUp() _fileSystem = new Mock(); _fileSystem.Setup(x => x.MapPath(It.IsAny())).Returns(x => x); + // Per default the output file should not exist, then individual tests + // can choose otherwise. + _fileSystem.Setup(x => x.FileExists(It.IsAny())).Returns(false); + _fileCacheHash = new Mock(); _babel = new Babel( @@ -150,8 +154,32 @@ public void ShouldSaveTransformationResult() var resultFilename = _babel.TransformAndSaveFile("foo.jsx"); Assert.AreEqual("foo.generated.js", resultFilename); StringAssert.EndsWith("React.DOM.div('Hello World')", result); + System.IO.File.WriteAllText("c:\\temp\\foo.generated.js", result, System.Text.Encoding.UTF8); } + [Test] + public void ShouldSkipTransformationIfCacheIsValid() + { + _fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("
Hello World
"); + _fileSystem.Setup(x => x.FileExists(It.IsAny())).Returns(true); + _fileCacheHash.Setup(x => x.ValidateHash(It.IsAny(), It.IsAny())).Returns(true); + _environment.Setup(x => x.ExecuteWithBabel( + "ReactNET_transform_sourcemap", + It.IsAny(), + It.IsAny(), // Babel config + "foo.jsx" // File name + )).Returns(new JavaScriptWithSourceMap { Code = "React.DOM.div('Hello World')" }); + + string result = null; + _fileSystem.Setup(x => x.WriteAsString("foo.generated.js", It.IsAny())).Callback( + (string filename, string contents) => result = contents + ); + + var resultFilename = _babel.TransformAndSaveFile("foo.jsx"); + Assert.AreEqual("foo.generated.js", resultFilename); + Assert.IsNull(result, "There should be no result. Cached result should have been used."); + } + private void SetUpEmptyCache() { _cache.Setup(x => x.Get("JSX_v3_foo.jsx", null)).Returns((JavaScriptWithSourceMap)null); From 4a84edb8a5d678f20a10240ab95eb06f13afe84d Mon Sep 17 00:00:00 2001 From: Torben Rahbek Koch Date: Sun, 4 Sep 2016 15:22:37 +0200 Subject: [PATCH 4/5] Remove debug File.WriteAllText from test. --- src/React.Tests/Core/BabelTransformerTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/React.Tests/Core/BabelTransformerTests.cs b/src/React.Tests/Core/BabelTransformerTests.cs index cf0081dc1..f281ee677 100644 --- a/src/React.Tests/Core/BabelTransformerTests.cs +++ b/src/React.Tests/Core/BabelTransformerTests.cs @@ -154,7 +154,6 @@ public void ShouldSaveTransformationResult() var resultFilename = _babel.TransformAndSaveFile("foo.jsx"); Assert.AreEqual("foo.generated.js", resultFilename); StringAssert.EndsWith("React.DOM.div('Hello World')", result); - System.IO.File.WriteAllText("c:\\temp\\foo.generated.js", result, System.Text.Encoding.UTF8); } [Test] From 3bb1810413f304803be439effe0f4a25dbf3b816 Mon Sep 17 00:00:00 2001 From: Torben Rahbek Koch Date: Sun, 4 Sep 2016 20:03:07 +0200 Subject: [PATCH 5/5] Fix erroneous comment in babel.cs --- src/React.Core/Babel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/React.Core/Babel.cs b/src/React.Core/Babel.cs index b891b5134..9c816a5ca 100644 --- a/src/React.Core/Babel.cs +++ b/src/React.Core/Babel.cs @@ -371,7 +371,7 @@ string filename /// /// The contents of the input file. /// The output path of the (possibly previously) generated file. - /// Returns true if the file should be transpiled, false otherwise. + /// Returns false if the file should be transpiled, true otherwise. public virtual bool CacheIsValid(string inputFileContents, string outputPath) { if (!_fileSystem.FileExists(outputPath))