From ae60bd0167483bad342bcaae9fa2638ee5df91d9 Mon Sep 17 00:00:00 2001
From: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com>
Date: Fri, 16 Jul 2021 14:33:39 -0700
Subject: [PATCH 01/12] [installer/2106-font] revert back to default install
bootstrapper font
Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com>
---
.../Windows/Packaging/BootstrapperTheme.xml.in | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in b/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in
index 8d8416539e..c670ef3d9a 100644
--- a/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in
+++ b/cmake/Platform/Windows/Packaging/BootstrapperTheme.xml.in
@@ -4,15 +4,15 @@
#(loc.WindowTitle)
- Open Sans
+ Segoe UI
- Open Sans
+ Segoe UI
- Open Sans
+ Segoe UI
- Open Sans
+ Segoe UI
- Open Sans
+ Segoe UI
From 679ecf480197d234cc86fd123c5535a33c25d474 Mon Sep 17 00:00:00 2001
From: lumberyard-employee-dm
<56135373+lumberyard-employee-dm@users.noreply.github.com>
Date: Fri, 16 Jul 2021 17:40:27 -0500
Subject: [PATCH 02/12] External Gem and Projects now appear in Editor
AssetBrowser (#2227)
* External Gem and Projects now appear in Editor AssetBrowser
Optimized logic populating the FolderAssetBrowserEntries in the Editor AssetBrowser.
Added an "[External]" tag to scan folders which reside outside of the Engine Root
Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
* Fixed conversion of fixed_string to string when normalizing an added AssetBrowser file path.
Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
* RootAssetBrowserEntry.cpp Linux conditional expression fix
Because an AZ::IO::PathView is convertible to an AZ::IO::FixedMaxPath and vice-versa, the conversion of the second part of the ternary expression absolutePathView needs to explicitly convert to an AZ::IO::FixedMaxPath
Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
---
.../Entries/AssetBrowserEntry.cpp | 4 +-
.../AssetBrowser/Entries/AssetBrowserEntry.h | 5 +-
.../Entries/FolderAssetBrowserEntry.cpp | 4 +-
.../Entries/RootAssetBrowserEntry.cpp | 201 ++++++++----------
.../Entries/RootAssetBrowserEntry.h | 12 +-
.../Entries/SourceAssetBrowserEntry.cpp | 4 +-
6 files changed, 105 insertions(+), 125 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.cpp
index 17a20a9d19..7eae7621d2 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.cpp
@@ -206,12 +206,12 @@ namespace AzToolsFramework
const AZStd::string& AssetBrowserEntry::GetRelativePath() const
{
- return m_relativePath;
+ return m_relativePath.Native();
}
const AZStd::string& AssetBrowserEntry::GetFullPath() const
{
- return m_fullPath;
+ return m_fullPath.Native();
}
const AssetBrowserEntry* AssetBrowserEntry::GetChild(int index) const
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h
index e4a7b6b4cb..24f037a623 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h
@@ -9,6 +9,7 @@
#if !defined(Q_MOC_RUN)
#include
#include
+#include
#include
#include
@@ -130,8 +131,8 @@ namespace AzToolsFramework
protected:
AZStd::string m_name;
QString m_displayName;
- AZStd::string m_relativePath;
- AZStd::string m_fullPath;
+ AZ::IO::Path m_relativePath;
+ AZ::IO::Path m_fullPath;
AZStd::vector m_children;
AssetBrowserEntry* m_parentAssetEntry = nullptr;
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/FolderAssetBrowserEntry.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/FolderAssetBrowserEntry.cpp
index 3c5afab0d0..febd406f23 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/FolderAssetBrowserEntry.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/FolderAssetBrowserEntry.cpp
@@ -37,8 +37,8 @@ namespace AzToolsFramework
void FolderAssetBrowserEntry::UpdateChildPaths(AssetBrowserEntry* child) const
{
- child->m_relativePath = m_relativePath + AZ_CORRECT_DATABASE_SEPARATOR + child->m_name;
- child->m_fullPath = m_fullPath + AZ_CORRECT_DATABASE_SEPARATOR + child->m_name;
+ child->m_relativePath = m_relativePath / child->m_name;
+ child->m_fullPath = m_fullPath / child->m_name;
AssetBrowserEntry::UpdateChildPaths(child);
}
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
index 090ad0d6ca..0e132d2581 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
@@ -10,6 +10,7 @@
#include
#include
+#include
#include
#include
@@ -24,8 +25,6 @@ namespace AzToolsFramework
{
namespace AssetBrowser
{
- const char* GEMS_FOLDER_NAME = "Gems";
-
RootAssetBrowserEntry::RootAssetBrowserEntry()
: AssetBrowserEntry()
{
@@ -53,13 +52,7 @@ namespace AzToolsFramework
EntryCache::GetInstance()->Clear();
m_enginePath = enginePath;
-
- // there is no "Gems" scan folder registered in db, create one manually
- auto gemFolder = aznew FolderAssetBrowserEntry();
- gemFolder->m_name = m_enginePath + AZ_CORRECT_DATABASE_SEPARATOR + GEMS_FOLDER_NAME;
- gemFolder->m_displayName = GEMS_FOLDER_NAME;
- gemFolder->m_isGemsFolder = true;
- AddChild(gemFolder);
+ m_fullPath = enginePath;
}
bool RootAssetBrowserEntry::IsInitialUpdate() const
@@ -80,8 +73,17 @@ namespace AzToolsFramework
if (AZ::IO::FileIOBase::GetInstance()->IsDirectory(scanFolderDatabaseEntry.m_scanFolder.c_str()))
{
- const auto scanFolder = CreateFolders(scanFolderDatabaseEntry.m_scanFolder.c_str(), this);
- scanFolder->m_displayName = QString::fromUtf8(scanFolderDatabaseEntry.m_displayName.c_str());
+ const auto scanFolder = CreateFolders(scanFolderDatabaseEntry.m_scanFolder, this);
+ // Append an "[External]" to the display if the Scan Folder is NOT relative to the Engine Root path
+ if (!AZ::IO::PathView(scanFolderDatabaseEntry.m_scanFolder).IsRelativeTo(m_enginePath))
+ {
+ scanFolder->m_displayName += " [External]";
+ }
+ else
+ {
+ scanFolder->m_displayName = QString::fromUtf8(scanFolderDatabaseEntry.m_displayName.c_str());
+ }
+
EntryCache::GetInstance()->m_scanFolderIdMap[scanFolderDatabaseEntry.m_scanFolderID] = scanFolder;
}
}
@@ -121,38 +123,34 @@ namespace AzToolsFramework
return;
}
- const char* filePath = fileDatabaseEntry.m_fileName.c_str();
+ AZ::IO::FixedMaxPath absoluteFilePath = AZ::IO::FixedMaxPath(AZStd::string_view{ scanFolder->GetFullPath() })
+ / fileDatabaseEntry.m_fileName.c_str();
AssetBrowserEntry* file;
// file can be either folder or actual file
if (fileDatabaseEntry.m_isFolder)
{
- file = CreateFolders(filePath, scanFolder);
+ file = CreateFolders(absoluteFilePath.Native(), scanFolder);
}
else
{
- AZStd::string sourcePath;
- AZStd::string sourceName;
- AZStd::string sourceExtension;
- StringFunc::Path::Split(filePath, nullptr, &sourcePath, &sourceName, &sourceExtension);
// if missing create folders leading to file's location and get immediate parent
// (we don't need to have fileIds for any folders created yet, they will be added later)
- auto parent = CreateFolders(sourcePath.c_str(), scanFolder);
+ auto parent = CreateFolders(absoluteFilePath.ParentPath().Native(), scanFolder);
// for simplicity in AB, files are represented as sources, but they are missing SourceDatabaseEntry-specific information such as SourceUuid
auto source = aznew SourceAssetBrowserEntry();
- source->m_name = (sourceName + sourceExtension).c_str();
+ source->m_name = absoluteFilePath.Filename().Native();
source->m_fileId = fileDatabaseEntry.m_fileID;
source->m_displayName = QString::fromUtf8(source->m_name.c_str());
source->m_scanFolderId = fileDatabaseEntry.m_scanFolderPK;
- source->m_extension = sourceExtension.c_str();
+ source->m_extension = absoluteFilePath.Extension().Native();
parent->AddChild(source);
file = source;
}
EntryCache::GetInstance()->m_fileIdMap[fileDatabaseEntry.m_fileID] = file;
- AZStd::string fullPath = file->m_fullPath;
- AzFramework::StringFunc::Path::Normalize(fullPath);
- EntryCache::GetInstance()->m_absolutePathToFileId[fullPath] = fileDatabaseEntry.m_fileID;
+ AZStd::string filePath = AZ::IO::PathView(file->m_fullPath).LexicallyNormal().String();
+ EntryCache::GetInstance()->m_absolutePathToFileId[filePath] = fileDatabaseEntry.m_fileID;
}
bool RootAssetBrowserEntry::RemoveFile(const AZ::s64& fileId) const
@@ -305,116 +303,95 @@ namespace AzToolsFramework
}
}
- FolderAssetBrowserEntry* RootAssetBrowserEntry::CreateFolder(const char* folderName, AssetBrowserEntry* parent)
+ AssetBrowserEntry* RootAssetBrowserEntry::GetNearestAncestor(AZ::IO::PathView absolutePathView, AssetBrowserEntry* parent,
+ AZStd::unordered_set& visitedSet)
+ {
+ auto IsPathRelativeToEntry = [absolutePathView](AssetBrowserEntry* assetBrowserEntry)
+ {
+ auto& childPath = assetBrowserEntry->m_fullPath;
+ return absolutePathView.IsRelativeTo(AZ::IO::PathView(childPath));
+ };
+
+ if (visitedSet.contains(parent))
+ {
+ return {};
+ }
+
+ visitedSet.insert(parent);
+
+ AssetBrowserEntry* nearestAncestor{};
+ for (AssetBrowserEntry* childBrowserEntry : parent->m_children)
+ {
+ if (IsPathRelativeToEntry(childBrowserEntry))
+ {
+ // Walk the AssetBrowserEntry Tree looking for a nearer ancestor to the absolute path
+ // If one is not found in the recursive call to GetNearestAncestor, then the childBrowserEntry
+ // is the current best candidate
+ AssetBrowserEntry* candidateAncestor = GetNearestAncestor(absolutePathView, childBrowserEntry, visitedSet);
+ candidateAncestor = candidateAncestor != nullptr ? candidateAncestor : childBrowserEntry;
+ AZ::IO::PathView candidatePathView(candidateAncestor->m_fullPath);
+ // If the candidate is relative to the current nearest ancestor, then it is even nearer to the path
+ if (!nearestAncestor || candidatePathView.IsRelativeTo(nearestAncestor->m_fullPath))
+ {
+ nearestAncestor = candidateAncestor;
+ // If the full path compares equal to the AssetBrowserEntry path, then no need to proceed any further
+ if (AZ::IO::PathView(nearestAncestor->m_fullPath) == absolutePathView)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return nearestAncestor;
+ }
+
+ FolderAssetBrowserEntry* RootAssetBrowserEntry::CreateFolder(AZStd::string_view folderName, AssetBrowserEntry* parent)
{
auto it = AZStd::find_if(parent->m_children.begin(), parent->m_children.end(), [folderName](AssetBrowserEntry* entry)
- {
- if (!azrtti_istypeof(entry))
- {
- return false;
- }
- return AzFramework::StringFunc::Equal(entry->m_name.c_str(), folderName);
- });
+ {
+ if (!azrtti_istypeof(entry))
+ {
+ return false;
+ }
+ return AZ::IO::PathView(entry->m_name) == AZ::IO::PathView(folderName);
+ });
if (it != parent->m_children.end())
{
return azrtti_cast(*it);
}
const auto folder = aznew FolderAssetBrowserEntry();
folder->m_name = folderName;
- folder->m_displayName = folderName;
+ folder->m_displayName = QString::fromUtf8(folderName.data(), aznumeric_caster(folderName.size()));
parent->AddChild(folder);
return folder;
}
- AssetBrowserEntry* RootAssetBrowserEntry::CreateFolders(const char* relativePath, AssetBrowserEntry* parent)
+ AssetBrowserEntry* RootAssetBrowserEntry::CreateFolders(AZStd::string_view absolutePath, AssetBrowserEntry* parent)
{
- auto children(parent->m_children);
- int n = 0;
+ AZ::IO::PathView absolutePathView(absolutePath);
+ // Find the nearest ancestor path to the absolutePath
+ AZStd::unordered_set visitedSet;
- // check if folder with the same name already exists
- // step through every character in relativePath and compare to each child's relative path of suggested parent
- // if a character @n in child's rel path mismatches character at n in relativePath, remove that child from further search
- while (!children.empty() && relativePath[n])
+ if (AssetBrowserEntry* nearestAncestor = GetNearestAncestor(absolutePathView, parent, visitedSet);
+ nearestAncestor != nullptr)
{
- AZStd::vector toRemove;
- for (auto child : children)
- {
- auto& childPath = azrtti_istypeof(parent) ? child->m_fullPath : child->m_relativePath;
-
- // child's path mismatched, remove it from search candidates
- if (childPath.length() == n || childPath[n] != relativePath[n])
- {
- toRemove.push_back(child);
-
- // it is possible that child may be a closer parent, substitute it as new potential parent
- // e.g. child->m_relativePath = 'Gems', relativePath = 'Gems/Assets', old parent = root, new parent = Gems
- if (childPath.length() == n && relativePath[n] == AZ_CORRECT_DATABASE_SEPARATOR)
- {
- parent = child;
- relativePath += n; // advance relative path n characters since the parent has changed
- n = 0; // Once the relative path pointer is advanced, reset n
- }
- }
- }
- for (auto entry : toRemove)
- {
- children.erase(AZStd::remove(children.begin(), children.end(), entry), children.end());
- }
- n++;
+ parent = nearestAncestor;
}
- // filter out the remaining children that don't end with '/' or '\0'
- // for example if folderName = "foo", while children may still remain with names like "foo123",
- // which is not the same folder
- AZStd::vector toRemove;
- for (auto child : children)
+ // If the nearest ancestor is the absolutePath, then it is already crated
+ if (absolutePathView == AZ::IO::PathView(parent->GetFullPath()))
{
- auto& childPath = azrtti_istypeof(parent) ? child->m_fullPath : child->m_relativePath;
- // check if there are non-null characters remaining @n
- if (childPath.length() > n)
- {
- toRemove.push_back(child);
- }
- }
- for (auto entry : toRemove)
- {
- children.erase(AZStd::remove(children.begin(), children.end(), entry), children.end());
+ return parent;
}
- // at least one child remains, this means the folder with this name already exists, return it
- if (!children.empty())
+ // create all missing folders
+ auto proximateToPath = absolutePathView.IsRelativeTo(parent->m_fullPath)
+ ? absolutePathView.LexicallyProximate(parent->m_fullPath)
+ : AZ::IO::FixedMaxPath(absolutePathView);
+ for (AZ::IO::FixedMaxPath scanFolderSegment : proximateToPath)
{
- parent = children.front();
- }
- // if it's a scanfolder, then do not create folders leading to it
- // e.g. instead of 'C:\dev\SampleProject' just create 'SampleProject'
- else if (parent->GetEntryType() == AssetEntryType::Root)
- {
- AZStd::string folderName;
- AzFramework::StringFunc::Path::Split(relativePath, nullptr, nullptr, &folderName);
- parent = CreateFolder(folderName.c_str(), parent);
- parent->m_fullPath = relativePath;
- }
- // otherwise create all missing folders
- else
- {
- n = 0;
- AZStd::string folderName(strlen(relativePath) + 1, '\0');
- // iterate through relativePath until the first '/'
- while (relativePath[n] && relativePath[n] != AZ_CORRECT_DATABASE_SEPARATOR)
- {
- folderName[n] = relativePath[n];
- n++;
- }
- if (n > 0)
- {
- parent = CreateFolder(folderName.c_str(), parent);
- }
- // n+1 also skips the '/' character
- if (relativePath[n] && relativePath[n + 1])
- {
- parent = CreateFolders(relativePath + n + 1, parent);
- }
+ parent = CreateFolder(scanFolderSegment.c_str(), parent);
}
return parent;
}
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.h b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.h
index 883f9dec01..62fbc7a39d 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.h
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
@@ -77,12 +78,15 @@ namespace AzToolsFramework
private:
AZ_DISABLE_COPY_MOVE(RootAssetBrowserEntry);
- AZStd::string m_enginePath;
+ AZ::IO::Path m_enginePath;
//! Create folder entry child
- FolderAssetBrowserEntry* CreateFolder(const char* folderName, AssetBrowserEntry* parent);
- //! Recursively create folder structure leading to relative path from parent
- AssetBrowserEntry* CreateFolders(const char* relativePath, AssetBrowserEntry* parent);
+ FolderAssetBrowserEntry* CreateFolder(AZStd::string_view folderName, AssetBrowserEntry* parent);
+ //! Recursively create folder structure leading to path from parent
+ AssetBrowserEntry* CreateFolders(AZStd::string_view absolutePath, AssetBrowserEntry* parent);
+ // Retrieves the nearest ancestor AssetBrowserEntry from the absolutePath
+ static AssetBrowserEntry* GetNearestAncestor(AZ::IO::PathView absolutePath, AssetBrowserEntry* parent,
+ AZStd::unordered_set& visitedSet);
bool m_isInitialUpdate = false;
};
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.cpp
index e45c234c92..1eea909f7c 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/SourceAssetBrowserEntry.cpp
@@ -26,9 +26,7 @@ namespace AzToolsFramework
if (EntryCache* cache = EntryCache::GetInstance())
{
cache->m_fileIdMap.erase(m_fileId);
- AZStd::string fullPath = m_fullPath;
- AzFramework::StringFunc::Path::Normalize(fullPath);
- cache->m_absolutePathToFileId.erase(fullPath);
+ cache->m_absolutePathToFileId.erase(m_fullPath.LexicallyNormal().Native());
if (m_sourceId != -1)
{
From 173126f5a5f1b3a1efc65e5a902c48d63b2a5ad9 Mon Sep 17 00:00:00 2001
From: Brian Herrera
Date: Mon, 19 Jul 2021 16:09:47 -0700
Subject: [PATCH 03/12] Add script for license scanner (#2267)
* Add script for license scanner
This script will scan the source tree for license files and generate a file with the contents of all the licenses.
Signed-off-by: brianherrera
---
scripts/license_scanner/license_scanner.py | 129 ++++++++++++++++++++
scripts/license_scanner/scanner_config.json | 12 ++
2 files changed, 141 insertions(+)
create mode 100644 scripts/license_scanner/license_scanner.py
create mode 100644 scripts/license_scanner/scanner_config.json
diff --git a/scripts/license_scanner/license_scanner.py b/scripts/license_scanner/license_scanner.py
new file mode 100644
index 0000000000..c0e3c1f1ba
--- /dev/null
+++ b/scripts/license_scanner/license_scanner.py
@@ -0,0 +1,129 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+import argparse
+import fnmatch
+import json
+import os
+import pathlib
+import re
+import sys
+
+
+class LicenseScanner:
+ """Class to contain license scanner.
+
+ Scans source tree for license files using provided filename patterns and generates a file
+ with the contents of all the licenses.
+
+ :param config_file: Config file with license patterns and scanner settings
+ """
+
+ DEFAULT_CONFIG_FILE = 'scanner_config.json'
+
+ def __init__(self, config_file=None):
+ self.config_file = config_file
+ self.config_data = self._load_config()
+ self.license_regex = self._load_license_regex()
+
+ def _load_config(self):
+ """Load config from the provided file. Sets default file if one is not provided."""
+ if self.config_file is None:
+ script_directory = os.path.dirname(os.path.abspath(__file__)) # Default file expected in same dir as script
+ self.config_file = os.path.join(script_directory, self.DEFAULT_CONFIG_FILE)
+
+ try:
+ with open(self.config_file) as f:
+ return json.load(f)
+ except FileNotFoundError:
+ print('Config file cannot be found')
+ raise
+
+ def _load_license_regex(self):
+ """Returns regex object with case-insensitive matching from the list of filename patterns."""
+ regex_patterns = []
+ for pattern in self.config_data['license_patterns']:
+ regex_patterns.append(fnmatch.translate(pattern))
+ return re.compile('|'.join(regex_patterns), re.IGNORECASE)
+
+ def scan(self, path=os.curdir):
+ """Scan directory tree for filenames matching license_regex.
+
+ :param path: Path of the directory to run scanner
+ :return: Package paths and their corresponding license file contents
+ :rtype: dict
+ """
+ licenses = 0
+ license_files = {}
+
+ for dirpath, dirnames, filenames in os.walk(path):
+ for file in filenames:
+ if self.license_regex.match(file):
+ license_file_content = self._get_license_file_contents(os.path.join(dirpath, file))
+ rel_dirpath = os.path.relpath(dirpath, path) # Limit path inside scanned directory
+ license_files[rel_dirpath] = license_file_content
+ licenses += 1
+ print(f'License file: {os.path.join(dirpath, file)}')
+
+ # Remove directories that should not be scanned
+ for dir in self.config_data['excluded_directories']:
+ if dir in dirnames:
+ dirnames.remove(dir)
+ print(f'{licenses} license files found.')
+ return license_files
+
+ def _get_license_file_contents(self, filepath):
+ try:
+ with open(filepath, encoding='utf8') as f:
+ return f.read()
+ except UnicodeDecodeError:
+ print(f'Unable to read license file: {filepath}')
+ pass
+
+ def create_license_file(self, licenses, filepath='NOTICES.txt'):
+ """Creates file with all the provided license file contents.
+
+ :param licenses: Dict with package paths and their corresponding license file contents
+ :param filepath: Path to write the file
+ """
+ package_separator = '------------------------------------'
+ with open(filepath, 'w', encoding='utf8') as f:
+ for directory, license in licenses.items():
+ license_output = '\n\n'.join([
+ f'{package_separator}',
+ f'Package path: {directory}',
+ 'License:',
+ f'{license}\n'
+ ])
+ f.write(license_output)
+ return None
+
+
+def parse_args():
+ parser = argparse.ArgumentParser(
+ description='Script to run LicenseScanner and generate license file')
+ parser.add_argument('--config-file', '-c', type=pathlib.Path, help='Config file for LicenseScanner')
+ parser.add_argument('--license-file-path', '-l', type=pathlib.Path, help='Create license file in the provided path')
+ parser.add_argument('--scan-path', '-s', default=os.curdir, type=pathlib.Path, help='Path to scan')
+ return parser.parse_args()
+
+
+def main():
+ try:
+ args = parse_args()
+ ls = LicenseScanner(args.config_file)
+ licenses = ls.scan(args.scan_path)
+
+ if args.license_file_path:
+ ls.create_license_file(licenses, args.license_file_path)
+ except FileNotFoundError as e:
+ print(f'Type: {type(e).__name__}, Error: {e}')
+ return 1
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/scripts/license_scanner/scanner_config.json b/scripts/license_scanner/scanner_config.json
new file mode 100644
index 0000000000..b5863a7d31
--- /dev/null
+++ b/scripts/license_scanner/scanner_config.json
@@ -0,0 +1,12 @@
+{
+ "excluded_directories": [
+ ".git",
+ ".venv",
+ "build",
+ "license_scanner"
+ ],
+ "license_patterns": [
+ "LICENSE*",
+ "COPYING*"
+ ]
+}
From afb57c9cf679592a209dbccdd5f38126e03d6b59 Mon Sep 17 00:00:00 2001
From: Scott Romero <24445312+AMZN-ScottR@users.noreply.github.com>
Date: Mon, 19 Jul 2021 18:17:55 -0700
Subject: [PATCH 04/12] [stabliziation/2106] update 3rd party license file name
to be pulled into the installer package (#2281)
License file name was changed in #2267
Signed-off-by: AMZN-ScottR 24445312+AMZN-ScottR@users.noreply.github.com
---
cmake/Packaging.cmake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cmake/Packaging.cmake b/cmake/Packaging.cmake
index a07e1ec1d3..2240ff472c 100644
--- a/cmake/Packaging.cmake
+++ b/cmake/Packaging.cmake
@@ -128,7 +128,7 @@ install(FILES ${_cmake_package_dest}
# the version string and git tags are intended to be synchronized so it should be safe to use that instead
# of directly calling into git which could get messy in certain scenarios
if(${CPACK_PACKAGE_VERSION} VERSION_GREATER "0.0.0.0")
- set(_3rd_party_license_filename SPDX-Licenses.txt)
+ set(_3rd_party_license_filename NOTICES.txt)
set(_3rd_party_license_url "https://raw.githubusercontent.com/o3de/3p-package-source/${CPACK_PACKAGE_VERSION}/${_3rd_party_license_filename}")
set(_3rd_party_license_dest ${CPACK_BINARY_DIR}/${_3rd_party_license_filename})
From abce54b3cd0a574fff1a8612be838779ab597a73 Mon Sep 17 00:00:00 2001
From: Axel Nana
Date: Tue, 20 Jul 2021 01:05:09 +0100
Subject: [PATCH 05/12] Add missing `*.hxx` pattern
Signed-off-by: Axel Nana
---
cmake/Platform/Common/Install_common.cmake | 1 +
1 file changed, 1 insertion(+)
diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake
index 5b476667e2..0a84d3ceb2 100644
--- a/cmake/Platform/Common/Install_common.cmake
+++ b/cmake/Platform/Common/Install_common.cmake
@@ -64,6 +64,7 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar
PATTERN *.h
PATTERN *.hpp
PATTERN *.inl
+ PATTERN *.hxx
)
endif()
endforeach()
From b58286d9b1022c3e3051c3225b7000935066fd4c Mon Sep 17 00:00:00 2001
From: lumberyard-employee-dm
<56135373+lumberyard-employee-dm@users.noreply.github.com>
Date: Tue, 20 Jul 2021 20:40:04 -0500
Subject: [PATCH 06/12] Fixed RootAssetBrowserEntry setting of child
AssetBrowserEntries
The issue is due to RootAssetBrowserEntry::UpdateChildPaths not taking
the RootAssetBrowserEntry fullpath into account when appending the child
path entry
Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
---
.../AssetBrowser/Entries/RootAssetBrowserEntry.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
index 0e132d2581..eec9970ca3 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBrowser/Entries/RootAssetBrowserEntry.cpp
@@ -399,7 +399,7 @@ namespace AzToolsFramework
void RootAssetBrowserEntry::UpdateChildPaths(AssetBrowserEntry* child) const
{
child->m_relativePath = child->m_name;
- child->m_fullPath = child->m_name;
+ child->m_fullPath = m_fullPath / child->m_name;
AssetBrowserEntry::UpdateChildPaths(child);
}
From 3050a4db479fb2dacf59942f7b0b42d7d82fcdcd Mon Sep 17 00:00:00 2001
From: jckand-amzn
Date: Wed, 21 Jul 2021 10:18:18 -0500
Subject: [PATCH 07/12] Removing obsolete Vegetation Debugger test
Signed-off-by: jckand-amzn
---
.../EditorScripts/Debugger_DebugCVarsWorks.py | 55 ------------------
.../largeworlds/dyn_veg/test_Debugger.py | 56 -------------------
2 files changed, 111 deletions(-)
delete mode 100755 AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/Debugger_DebugCVarsWorks.py
delete mode 100755 AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_Debugger.py
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/Debugger_DebugCVarsWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/Debugger_DebugCVarsWorks.py
deleted file mode 100755
index 40fd67d957..0000000000
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/Debugger_DebugCVarsWorks.py
+++ /dev/null
@@ -1,55 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-"""
-
-import os
-import sys
-
-import azlmbr.legacy.general as general
-import azlmbr.paths
-
-sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
-import editor_python_test_tools.hydra_editor_utils as hydra
-from editor_python_test_tools.editor_test_helper import EditorTestHelper
-
-
-class TestDebuggerDebugCVarsWorks(EditorTestHelper):
- def __init__(self):
- EditorTestHelper.__init__(self, log_prefix="Debugger_DebugCVarsWorks", args=["level"])
-
- def run_test(self):
- """
- Summary:
- C2789148 Vegetation Debug CVars are enabled when the Debugger component is present
-
- Expected Result:
- The following commands are available in the Editor only when the Vegetation Debugger Level component is present:
- veg_debugDumpReport (Command)
- veg_debugRefreshAllAreas (Command)
-
- :return: None
- """
-
- # Create empty level
- self.test_success = self.create_level(
- self.args["level"],
- heightmap_resolution=1024,
- heightmap_meters_per_pixel=1,
- terrain_texture_resolution=4096,
- use_terrain=False,
- )
-
- # Initially run the command in console without Debugger component
- general.run_console("veg_debugDumpReport")
-
- # Add the Vegetation Debugger component to the Level Inspector
- hydra.add_level_component("Vegetation Debugger")
-
- # Run a command again after adding the Vegetation debugger
- general.run_console("veg_debugRefreshAllAreas")
-
-
-test = TestDebuggerDebugCVarsWorks()
-test.run()
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_Debugger.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_Debugger.py
deleted file mode 100755
index ed979136e0..0000000000
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_Debugger.py
+++ /dev/null
@@ -1,56 +0,0 @@
-"""
-Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
-
-SPDX-License-Identifier: Apache-2.0 OR MIT
-"""
-
-import os
-import pytest
-import logging
-
-# Bail on the test if ly_test_tools doesn't exist.
-pytest.importorskip("ly_test_tools")
-import ly_test_tools.environment.file_system as file_system
-import editor_python_test_tools.hydra_test_utils as hydra
-
-logger = logging.getLogger(__name__)
-test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts")
-
-
-@pytest.mark.parametrize("project", ["AutomatedTesting"])
-@pytest.mark.parametrize("level", ["tmp_level"])
-@pytest.mark.usefixtures("automatic_process_killer")
-@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
-class TestDebugger(object):
- @pytest.fixture(autouse=True)
- def setup_teardown(self, request, workspace, project, level):
- # Cleanup our temp level
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
- def teardown():
- # Cleanup our temp level
- file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True)
-
- request.addfinalizer(teardown)
-
- @pytest.mark.test_case_id("C2789148")
- @pytest.mark.SUITE_periodic
- @pytest.mark.dynveg_misc
- def test_Debugger_DebugCVarsWork(self, request, editor, level, workspace, launcher_platform):
- cfg_args = [level]
-
- expected_lines = [
- "Debugger_DebugCVarsWorks: test started",
- "[Warning] Unknown command: veg_debugDumpReport",
- "[CONSOLE] Executing console command 'veg_debugRefreshAllAreas'",
- "Debugger_DebugCVarsWorks: result=SUCCESS",
- ]
-
- hydra.launch_and_validate_results(
- request,
- test_directory,
- editor,
- "Debugger_DebugCVarsWorks.py",
- expected_lines=expected_lines,
- cfg_args=cfg_args
- )
From 7ebdde0be01477ba036bad7f5a1e36ae50e2d879 Mon Sep 17 00:00:00 2001
From: jckand-amzn
Date: Wed, 21 Jul 2021 10:25:48 -0500
Subject: [PATCH 08/12] Adding xfail mark to
test_LandscapeCanvas_GraphClosed_OnEntityDelete
Signed-off-by: jckand-amzn
---
.../landscape_canvas/test_GeneralGraphFunctionality.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GeneralGraphFunctionality.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GeneralGraphFunctionality.py
index bbca71461c..e2aa222c3f 100755
--- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GeneralGraphFunctionality.py
+++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GeneralGraphFunctionality.py
@@ -104,6 +104,7 @@ class TestGeneralGraphFunctionality(object):
@pytest.mark.test_case_id("C17488412")
@pytest.mark.SUITE_periodic
+ @pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, editor, level, launcher_platform):
cfg_args = [level]
From fc1ccb9e8574a1d997bbc791fb46a6a1325ee3a2 Mon Sep 17 00:00:00 2001
From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
Date: Wed, 21 Jul 2021 17:17:09 -0700
Subject: [PATCH 09/12] Issues/2126 PhysX Gem can't be used as build dependency
in engine SDK Part (#2337)
* Applying GENEX_EVAL to 2 cases where the genex can produce another genex
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
* Missing case when the folder is an external one to the engine/project (e.g. external gems)
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
---
Code/LauncherUnified/launcher_generator.cmake | 4 ++--
cmake/LYWrappers.cmake | 15 ++++++++++-----
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/Code/LauncherUnified/launcher_generator.cmake b/Code/LauncherUnified/launcher_generator.cmake
index 628b5fffac..28fddad1eb 100644
--- a/Code/LauncherUnified/launcher_generator.cmake
+++ b/Code/LauncherUnified/launcher_generator.cmake
@@ -40,9 +40,9 @@ foreach(project_name project_path IN ZIP_LISTS LY_PROJECTS_TARGET_NAME LY_PROJEC
add_custom_target(${project_name}.Assets
COMMENT "Processing ${project_name} assets..."
COMMAND "${CMAKE_COMMAND}"
- -DLY_LOCK_FILE=$/project_assets.lock
+ -DLY_LOCK_FILE=$>/project_assets.lock
-P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake
- EXEC_COMMAND $
+ EXEC_COMMAND $>
--zeroAnalysisMode
--project-path=${project_real_path}
--platforms=${LY_ASSET_DEPLOY_ASSET_TYPE}
diff --git a/cmake/LYWrappers.cmake b/cmake/LYWrappers.cmake
index 40bf6ef541..cfe6df5c81 100644
--- a/cmake/LYWrappers.cmake
+++ b/cmake/LYWrappers.cmake
@@ -391,10 +391,10 @@ function(ly_delayed_target_link_libraries)
endif()
if(item_type STREQUAL MODULE_LIBRARY)
- target_include_directories(${target} ${visibility} $)
- target_link_libraries(${target} ${visibility} $)
- target_compile_definitions(${target} ${visibility} $)
- target_compile_options(${target} ${visibility} $)
+ target_include_directories(${target} ${visibility} $>)
+ target_link_libraries(${target} ${visibility} $>)
+ target_compile_definitions(${target} ${visibility} $>)
+ target_compile_options(${target} ${visibility} $>)
else()
ly_parse_third_party_dependencies(${item})
target_link_libraries(${target} ${visibility} ${item})
@@ -659,7 +659,12 @@ function(ly_get_vs_folder_directory absolute_target_source_dir output_source_dir
if(is_target_prefix_of_engine_root)
cmake_path(RELATIVE_PATH absolute_target_source_dir BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE relative_target_source_dir)
else()
- cmake_path(GET absolute_target_source_dir RELATIVE_PART relative_target_source_dir)
+ cmake_path(IS_PREFIX CMAKE_SOURCE_DIR ${absolute_target_source_dir} is_target_prefix_of_source_dir)
+ if(is_target_prefix_of_source_dir)
+ cmake_path(RELATIVE_PATH absolute_target_source_dir BASE_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE relative_target_source_dir)
+ else()
+ cmake_path(GET absolute_target_source_dir RELATIVE_PART relative_target_source_dir)
+ endif()
endif()
set(${output_source_dir} ${relative_target_source_dir} PARENT_SCOPE)
From 26c9853ff9916b7216a5e01eef6b9f7be8bb4df1 Mon Sep 17 00:00:00 2001
From: moraaar
Date: Tue, 27 Jul 2021 09:11:28 +0100
Subject: [PATCH 10/12] Fixed cloth tangent generation (#2440)
- The output vectors were not properly filled with zeros when they already had the expected size.
- The tolerance was too large and was causing patches while computing tangents and bitangents.
- The handedness was inverted to what is expected in the shader (which always inverts tangent's w).
Signed-off-by: moraaar
---
.../ClothComponentMesh/ClothComponentMesh.cpp | 2 +-
.../Code/Source/System/TangentSpaceHelper.cpp | 20 ++++++++++++-------
.../ClothConstraintsTest.cpp | 12 ++++++++---
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp
index b791e8a543..7e0ac2f230 100644
--- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp
+++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp
@@ -577,7 +577,7 @@ namespace NvCloth
const AZ::Vector3& renderTangent = renderTangents[renderVertexIndex];
destTangentsBuffer[index].Set(
renderTangent,
- 1.0f);
+ -1.0f); // Shader function ConstructTBN inverts w to change bitangent sign, but the bitangents passed are already corrected, so passing -1.0 to counteract.
}
if (destBitangentsBuffer)
diff --git a/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp b/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp
index b43ad1923b..e388643c00 100644
--- a/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp
+++ b/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp
@@ -11,7 +11,7 @@ namespace NvCloth
{
namespace
{
- const float Tolerance = 0.0001f;
+ const float Tolerance = 1e-7f;
}
bool TangentSpaceHelper::CalculateNormals(
@@ -33,7 +33,8 @@ namespace NvCloth
const size_t vertexCount = vertices.size();
// Reset results
- outNormals.resize(vertexCount, AZ::Vector3::CreateZero());
+ outNormals.resize(vertexCount);
+ AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero());
// calculate the normals per triangle
for (size_t i = 0; i < triangleCount; ++i)
@@ -114,8 +115,10 @@ namespace NvCloth
const size_t vertexCount = vertices.size();
// Reset results
- outTangents.resize(vertexCount, AZ::Vector3::CreateZero());
- outBitangents.resize(vertexCount, AZ::Vector3::CreateZero());
+ outTangents.resize(vertexCount);
+ outBitangents.resize(vertexCount);
+ AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero());
+ AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero());
// calculate the base vectors per triangle
for (size_t i = 0; i < triangleCount; ++i)
@@ -192,9 +195,12 @@ namespace NvCloth
const size_t vertexCount = vertices.size();
// Reset results
- outTangents.resize(vertexCount, AZ::Vector3::CreateZero());
- outBitangents.resize(vertexCount, AZ::Vector3::CreateZero());
- outNormals.resize(vertexCount, AZ::Vector3::CreateZero());
+ outTangents.resize(vertexCount);
+ outBitangents.resize(vertexCount);
+ outNormals.resize(vertexCount);
+ AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero());
+ AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero());
+ AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero());
// calculate the base vectors per triangle
for (size_t i = 0; i < triangleCount; ++i)
diff --git a/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp b/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp
index 5f390ed45d..50ca5c17cd 100644
--- a/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp
+++ b/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp
@@ -124,6 +124,9 @@ namespace UnitTest
const AZStd::vector& motionConstraints = clothConstraints->GetMotionConstraints();
EXPECT_TRUE(motionConstraints.size() == SimulationParticles.size());
+ EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(SimulationParticles[0].GetAsVector3(), Tolerance));
+ EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(SimulationParticles[1].GetAsVector3(), Tolerance));
+ EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(SimulationParticles[2].GetAsVector3(), Tolerance));
EXPECT_NEAR(motionConstraints[0].GetW(), 6.0f, Tolerance);
EXPECT_NEAR(motionConstraints[1].GetW(), 0.0f, Tolerance);
EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance);
@@ -277,6 +280,9 @@ namespace UnitTest
const AZStd::vector& separationConstraints = clothConstraints->GetSeparationConstraints();
EXPECT_TRUE(motionConstraints.size() == newParticles.size());
+ EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(newParticles[0].GetAsVector3(), Tolerance));
+ EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(newParticles[1].GetAsVector3(), Tolerance));
+ EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(newParticles[2].GetAsVector3(), Tolerance));
EXPECT_NEAR(motionConstraints[0].GetW(), 3.0f, Tolerance);
EXPECT_NEAR(motionConstraints[1].GetW(), 1.5f, Tolerance);
EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance);
@@ -285,8 +291,8 @@ namespace UnitTest
EXPECT_NEAR(separationConstraints[0].GetW(), 3.0f, Tolerance);
EXPECT_NEAR(separationConstraints[1].GetW(), 1.5f, Tolerance);
EXPECT_NEAR(separationConstraints[2].GetW(), 0.3f, Tolerance);
- EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-3.03902f, 2.80752f, 3.80752f), Tolerance));
- EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-1.41659f, 0.651243f, -0.348757f), Tolerance));
- EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(6.15313f, -0.876132f, 0.123868f), Tolerance));
+ EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 3.53553f, 4.53553f), Tolerance));
+ EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 2.06066f, 1.06066f), Tolerance));
+ EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(1.0f, -3.74767f, -2.74767f), Tolerance));
}
} // namespace UnitTest
From 902bdeb6d6092d0b88066fbb873eaa043c3b788a Mon Sep 17 00:00:00 2001
From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
Date: Thu, 29 Jul 2021 16:50:50 -0700
Subject: [PATCH 11/12] Create RUN target as helpers for the project-centric
workflow (#2520) (#2635)
* Create RUN target as helpers for the project-centric workflow
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
* typo fix
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
* rename target as ".Imported" and create "" as the metatarget that is used for debugging and building in o3de
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
---
Code/Editor/CMakeLists.txt | 2 +
cmake/Platform/Common/Install_common.cmake | 43 ++++++++++++++++++----
cmake/SettingsRegistry.cmake | 7 +---
cmake/install/InstalledTarget.in | 2 +
4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt
index 5a846a267a..db6b8e958e 100644
--- a/Code/Editor/CMakeLists.txt
+++ b/Code/Editor/CMakeLists.txt
@@ -163,6 +163,8 @@ ly_add_target(
editor_files.cmake
PLATFORM_INCLUDE_FILES
Platform/${PAL_PLATFORM_NAME}/editor_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
+ TARGET_PROPERTIES
+ LY_INSTALL_GENERATE_RUN_TARGET TRUE
BUILD_DEPENDENCIES
PRIVATE
3rdParty::Qt::Core
diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake
index 1ac59ee83f..8058fb5908 100644
--- a/cmake/Platform/Common/Install_common.cmake
+++ b/cmake/Platform/Common/Install_common.cmake
@@ -9,6 +9,15 @@ include(cmake/FileUtil.cmake)
set(CMAKE_INSTALL_MESSAGE NEVER) # Simplify messages to reduce output noise
+define_property(TARGET PROPERTY LY_INSTALL_GENERATE_RUN_TARGET
+ BRIEF_DOCS "Defines if a \"RUN\" targets should be created when installing this target Gem"
+ FULL_DOCS [[
+ Property which is set on targets that should generate a "RUN"
+ target when installed. This \"RUN\" target helps to run the
+ binary from the installed location directly from the IDE.
+ ]]
+)
+
ly_set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Core)
cmake_path(RELATIVE_PATH CMAKE_RUNTIME_OUTPUT_DIRECTORY BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE runtime_output_directory)
@@ -105,15 +114,19 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar
set(NAMESPACE_PLACEHOLDER "")
set(NAME_PLACEHOLDER ${TARGET_NAME})
endif()
+ get_target_property(should_create_helper ${TARGET_NAME} LY_INSTALL_GENERATE_RUN_TARGET)
+ if(should_create_helper)
+ set(NAME_PLACEHOLDER ${NAME_PLACEHOLDER}.Imported)
+ endif()
set(TARGET_TYPE_PLACEHOLDER "")
- get_target_property(target_type ${NAME_PLACEHOLDER} TYPE)
+ get_target_property(target_type ${TARGET_NAME} TYPE)
# Remove the _LIBRARY since we dont need to pass that to ly_add_targets
string(REPLACE "_LIBRARY" "" TARGET_TYPE_PLACEHOLDER ${target_type})
# For HEADER_ONLY libs we end up generating "INTERFACE" libraries, need to specify HEADERONLY instead
string(REPLACE "INTERFACE" "HEADERONLY" TARGET_TYPE_PLACEHOLDER ${TARGET_TYPE_PLACEHOLDER})
if(TARGET_TYPE_PLACEHOLDER STREQUAL "MODULE")
- get_target_property(gem_module ${NAME_PLACEHOLDER} GEM_MODULE)
+ get_target_property(gem_module ${TARGET_NAME} GEM_MODULE)
if(gem_module)
set(TARGET_TYPE_PLACEHOLDER "GEM_MODULE")
endif()
@@ -146,7 +159,6 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar
unset(RUNTIME_DEPENDENCIES_PLACEHOLDER)
endif()
-
get_target_property(inteface_build_dependencies_props ${TARGET_NAME} INTERFACE_LINK_LIBRARIES)
unset(INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER)
if(inteface_build_dependencies_props)
@@ -170,6 +182,23 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar
list(REMOVE_DUPLICATES INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER)
string(REPLACE ";" "\n" INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER "${INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER}")
+ # If the target is an executable/application, add a custom target so we can debug the target in project-centric workflow
+ if(should_create_helper)
+ string(REPLACE ".Imported" "" RUN_TARGET_NAME ${NAME_PLACEHOLDER})
+ set(target_types_with_debugging_helper EXECUTABLE APPLICATION)
+ if(NOT target_type IN_LIST target_types_with_debugging_helper)
+ message(FATAL_ERROR "Cannot generate a RUN target for ${TARGET_NAME}, type is ${target_type}")
+ endif()
+ set(TARGET_RUN_HELPER
+"add_custom_target(${RUN_TARGET_NAME})
+set_target_properties(${RUN_TARGET_NAME} PROPERTIES
+ FOLDER \"CMakePredefinedTargets/SDK\"
+ VS_DEBUGGER_COMMAND \$>
+ VS_DEBUGGER_COMMAND_ARGUMENTS \"--project-path=\${LY_DEFAULT_PROJECT_PATH}\"
+)"
+)
+ endif()
+
# Config file
set(target_file_contents "# Generated by O3DE install\n\n")
if(NOT target_type STREQUAL INTERFACE_LIBRARY)
@@ -182,13 +211,13 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar
set(target_location "\${LY_ROOT_FOLDER}/${library_output_directory}/${PAL_PLATFORM_NAME}/$/${target_library_output_subdirectory}/$")
elseif(target_type STREQUAL SHARED_LIBRARY)
string(APPEND target_file_contents
-"set_property(TARGET ${TARGET_NAME}
+"set_property(TARGET ${NAME_PLACEHOLDER}
APPEND_STRING PROPERTY IMPORTED_IMPLIB
$<$$:\"\${LY_ROOT_FOLDER}/${archive_output_directory}/${PAL_PLATFORM_NAME}/$/$\"$
)
")
string(APPEND target_file_contents
-"set_property(TARGET ${TARGET_NAME}
+"set_property(TARGET ${NAME_PLACEHOLDER}
PROPERTY IMPORTED_IMPLIB_$>
\"\${LY_ROOT_FOLDER}/${archive_output_directory}/${PAL_PLATFORM_NAME}/$/$\"
)
@@ -200,11 +229,11 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar
if(target_location)
string(APPEND target_file_contents
-"set_property(TARGET ${TARGET_NAME}
+"set_property(TARGET ${NAME_PLACEHOLDER}
APPEND_STRING PROPERTY IMPORTED_LOCATION
$<$$:${target_location}$
)
-set_property(TARGET ${TARGET_NAME}
+set_property(TARGET ${NAME_PLACEHOLDER}
PROPERTY IMPORTED_LOCATION_$>
${target_location}
)
diff --git a/cmake/SettingsRegistry.cmake b/cmake/SettingsRegistry.cmake
index 934bae4e30..a1e6de73f8 100644
--- a/cmake/SettingsRegistry.cmake
+++ b/cmake/SettingsRegistry.cmake
@@ -158,10 +158,6 @@ function(ly_delayed_generate_settings_registry)
message(FATAL_ERROR "Dependency ${gem_target} from ${target} does not exist")
endif()
- get_property(has_manually_added_dependencies TARGET ${gem_target} PROPERTY MANUALLY_ADDED_DEPENDENCIES SET)
- get_target_property(target_type ${gem_target} TYPE)
-
-
ly_get_gem_module_root(gem_module_root ${gem_target})
file(RELATIVE_PATH gem_module_root_relative_to_engine_root ${LY_ROOT_FOLDER} ${gem_module_root})
@@ -179,7 +175,8 @@ function(ly_delayed_generate_settings_registry)
list(JOIN target_gem_dependencies_names ",\n" target_gem_dependencies_names)
string(CONFIGURE ${gems_json_template} gem_json @ONLY)
get_target_property(is_imported ${target} IMPORTED)
- if(is_imported)
+ get_target_property(target_type ${target} TYPE)
+ if(is_imported OR target_type STREQUAL UTILITY)
unset(target_dir)
foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES)
string(TOUPPER ${conf} UCONF)
diff --git a/cmake/install/InstalledTarget.in b/cmake/install/InstalledTarget.in
index 0503fd5f2b..a4f4fa4763 100644
--- a/cmake/install/InstalledTarget.in
+++ b/cmake/install/InstalledTarget.in
@@ -17,6 +17,8 @@ ly_add_target(
@RUNTIME_DEPENDENCIES_PLACEHOLDER@
)
+@TARGET_RUN_HELPER@
+
set(configs @CMAKE_CONFIGURATION_TYPES@)
foreach(config ${configs})
include("@NAME_PLACEHOLDER@_${config}.cmake" OPTIONAL)
From 4b817a6483560691a5f95a34355c87c8972b05ab Mon Sep 17 00:00:00 2001
From: Shirang Jia
Date: Wed, 4 Aug 2021 17:57:47 -0700
Subject: [PATCH 12/12] Include build failure root cause in email notification
(#2491)
Signed-off-by: shiranj
---
scripts/build/Jenkins/Jenkinsfile | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile
index 70618fea78..e693168af0 100644
--- a/scripts/build/Jenkins/Jenkinsfile
+++ b/scripts/build/Jenkins/Jenkinsfile
@@ -577,13 +577,19 @@ finally {
)
}
node('controller') {
- step([
- $class: 'Mailer',
- notifyEveryUnstableBuild: true,
- recipients: emailextrecipients([
+ if("${currentBuild.currentResult}" == "SUCCESS") {
+ emailBody = "${BUILD_URL}\nSuccess!"
+ } else {
+ buildFailure = tm('${BUILD_FAILURE_ANALYZER}')
+ emailBody = "${BUILD_URL}\n${buildFailure}!"
+ }
+ emailext (
+ body: "${emailBody}",
+ subject: "${currentBuild.currentResult}: ${JOB_NAME} - Build # ${BUILD_NUMBER}",
+ recipientProviders: [
[$class: 'RequesterRecipientProvider']
- ])
- ])
+ ]
+ )
}
} catch(Exception e) {
}