Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: tools/gn/filesystem_utils.cc

Issue 1704383002: [GN] Don't rewrite files with the same contents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/filesystem_utils.h ('k') | tools/gn/filesystem_utils_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/filesystem_utils.h" 5 #include "tools/gn/filesystem_utils.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 std::string GetOutputSubdirName(const Label& toolchain_label, bool is_default) { 680 std::string GetOutputSubdirName(const Label& toolchain_label, bool is_default) {
681 // The default toolchain has no subdir. 681 // The default toolchain has no subdir.
682 if (is_default) 682 if (is_default)
683 return std::string(); 683 return std::string();
684 684
685 // For now just assume the toolchain name is always a valid dir name. We may 685 // For now just assume the toolchain name is always a valid dir name. We may
686 // want to clean up the in the future. 686 // want to clean up the in the future.
687 return toolchain_label.name() + "/"; 687 return toolchain_label.name() + "/";
688 } 688 }
689 689
690 bool ContentsEqual(const base::FilePath& file_path, const std::string& data) {
691 // Compare file and stream sizes first. Quick and will save us some time if
692 // they are different sizes.
693 int64_t file_size;
694 if (!base::GetFileSize(file_path, &file_size) ||
695 static_cast<size_t>(file_size) != data.size()) {
696 return false;
697 }
698
699 std::string file_data;
700 file_data.resize(file_size);
701 if (!base::ReadFileToString(file_path, &file_data))
702 return false;
703
704 return file_data == data;
705 }
706
707 bool WriteFileIfChanged(const base::FilePath& file_path,
708 const std::string& data,
709 Err* err) {
710 if (ContentsEqual(file_path, data))
711 return true;
712
713 // Create the directory if necessary.
714 if (!base::CreateDirectory(file_path.DirName())) {
715 if (err) {
716 *err =
717 Err(Location(), "Unable to create directory.",
718 "I was using \"" + FilePathToUTF8(file_path.DirName()) + "\".");
719 }
720 return false;
721 }
722
723 int size = static_cast<int>(data.size());
724 bool write_success = false;
725
726 #if defined(OS_WIN)
727 // On Windows, provide a custom implementation of base::WriteFile. Sometimes
728 // the base version fails, especially on the bots. The guess is that Windows
729 // Defender or other antivirus programs still have the file open (after
730 // checking for the read) when the write happens immediately after. This
731 // version opens with FILE_SHARE_READ (normally not what you want when
732 // replacing the entire contents of the file) which lets us continue even if
733 // another program has the file open for reading. See http://crbug.com/468437
734 base::win::ScopedHandle file(::CreateFile(file_path.value().c_str(),
735 GENERIC_WRITE, FILE_SHARE_READ,
736 NULL, CREATE_ALWAYS, 0, NULL));
737 if (file.IsValid()) {
738 DWORD written;
739 BOOL result = ::WriteFile(file.Get(), data.c_str(), size, &written, NULL);
740 if (result) {
741 if (static_cast<int>(written) == size) {
742 write_success = true;
743 } else {
744 // Didn't write all the bytes.
745 LOG(ERROR) << "wrote" << written << " bytes to "
746 << base::UTF16ToUTF8(file_path.value()) << " expected "
747 << size;
748 }
749 } else {
750 // WriteFile failed.
751 PLOG(ERROR) << "writing file " << base::UTF16ToUTF8(file_path.value())
752 << " failed";
753 }
754 } else {
755 PLOG(ERROR) << "CreateFile failed for path "
756 << base::UTF16ToUTF8(file_path.value());
757 }
758 #else
759 write_success = base::WriteFile(file_path, data.c_str(), size) == size;
760 #endif
761
762 if (!write_success && err) {
763 *err = Err(Location(), "Unable to write file.",
764 "I was writing \"" + FilePathToUTF8(file_path) + "\".");
765 }
766
767 return write_success;
768 }
769
690 SourceDir GetToolchainOutputDir(const Settings* settings) { 770 SourceDir GetToolchainOutputDir(const Settings* settings) {
691 return settings->toolchain_output_subdir().AsSourceDir( 771 return settings->toolchain_output_subdir().AsSourceDir(
692 settings->build_settings()); 772 settings->build_settings());
693 } 773 }
694 774
695 SourceDir GetToolchainOutputDir(const BuildSettings* build_settings, 775 SourceDir GetToolchainOutputDir(const BuildSettings* build_settings,
696 const Label& toolchain_label, bool is_default) { 776 const Label& toolchain_label, bool is_default) {
697 std::string result = build_settings->build_dir().value(); 777 std::string result = build_settings->build_dir().value();
698 result.append(GetOutputSubdirName(toolchain_label, is_default)); 778 result.append(GetOutputSubdirName(toolchain_label, is_default));
699 return SourceDir(SourceDir::SWAP_IN, &result); 779 return SourceDir(SourceDir::SWAP_IN, &result);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 915
836 SourceDir GetCurrentOutputDir(const Scope* scope) { 916 SourceDir GetCurrentOutputDir(const Scope* scope) {
837 return GetOutputDirForSourceDirAsOutputFile( 917 return GetOutputDirForSourceDirAsOutputFile(
838 scope->settings(), scope->GetSourceDir()).AsSourceDir( 918 scope->settings(), scope->GetSourceDir()).AsSourceDir(
839 scope->settings()->build_settings()); 919 scope->settings()->build_settings());
840 } 920 }
841 921
842 SourceDir GetCurrentGenDir(const Scope* scope) { 922 SourceDir GetCurrentGenDir(const Scope* scope) {
843 return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir()); 923 return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir());
844 } 924 }
OLDNEW
« no previous file with comments | « tools/gn/filesystem_utils.h ('k') | tools/gn/filesystem_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698