From b36631de947fbea590702e4f2e45d2d877741558 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com> Date: Wed, 12 Oct 2016 08:36:11 -0400 Subject: [PATCH 1/5] STYLE: UseSlicer: Simplify how list of optional extension variable is obtained --- CMake/UseSlicer.cmake.in | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CMake/UseSlicer.cmake.in b/CMake/UseSlicer.cmake.in index a214b81986..30c39c5f36 100644 --- a/CMake/UseSlicer.cmake.in +++ b/CMake/UseSlicer.cmake.in @@ -393,10 +393,9 @@ if(NOT Slicer_DONT_USE_EXTENSION) slicer_setting_variable_message("MIDAS_PACKAGE_EMAIL" OBFUSCATE) slicer_setting_variable_message("MIDAS_PACKAGE_API_KEY" OBFUSCATE) - set(optional_vars HOMEPAGE CATEGORY ICONURL CONTRIBUTORS DESCRIPTION - SCREENSHOTURLS DEPENDS LICENSE_FILE README_FILE - ) - foreach(var ${optional_vars}) + include(SlicerExtensionDescriptionSpec) + + foreach(var IN LISTS Slicer_EXT_OPTIONAL_METADATA_NAMES) slicer_setting_variable_message(EXTENSION_${var}) endforeach() -- GitLab From 1447fa7f8129dee2a1622ad4336bcaf70e836637 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com> Date: Wed, 12 Oct 2016 10:03:27 -0400 Subject: [PATCH 2/5] STYLE: UseSlicerMacros: Use CMakeParseArguments with setting_variable_message This is done anticipating a other change. --- CMake/UseSlicerMacros.cmake | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/CMake/UseSlicerMacros.cmake b/CMake/UseSlicerMacros.cmake index 19bd9ab870..ccb11d5959 100644 --- a/CMake/UseSlicerMacros.cmake +++ b/CMake/UseSlicerMacros.cmake @@ -66,16 +66,22 @@ endfunction() # -- Setting SHORTNAME ........: This is short variable name # -- Setting LONGLONGNAME .....: This is a longer variable name # +include(CMakeParseArguments) function(slicer_setting_variable_message varname) + set(options OBFUSCATE SKIP_TRUNCATE) + set(oneValueArgs ) + set(multiValueArgs ) + CMAKE_PARSE_ARGUMENTS(LOCAL + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) set(truncate TRUE) - set(obfuscate FALSE) - foreach(arg ${ARGN}) - if(arg STREQUAL "SKIP_TRUNCATE") - set(truncate FALSE) - elseif(arg STREQUAL "OBFUSCATE") - set(obfuscate TRUE) + if(LOCAL_SKIP_TRUNCATE) + set(truncate FALSE) endif() - endforeach() + set(obfuscate ${LOCAL_OBFUSCATE}) set(pretext_right_jusitfy_length 45) set(fill_char ".") set(truncated_text_length 120) -- GitLab From 7eab9f4f5e85382a1c039c30625390fc5f47ad33 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com> Date: Wed, 12 Oct 2016 09:53:51 -0400 Subject: [PATCH 3/5] STYLE: UseSlicerMacros: setting_variable_message function learn PRETEXT arg It is now possible to override the default pretext, specifying PRETEXT argument. --- CMake/UseSlicerMacros.cmake | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/CMake/UseSlicerMacros.cmake b/CMake/UseSlicerMacros.cmake index ccb11d5959..15f026b141 100644 --- a/CMake/UseSlicerMacros.cmake +++ b/CMake/UseSlicerMacros.cmake @@ -47,12 +47,15 @@ endfunction() # If the variable is not defined, it will display: # "-- Setting <varname> ........: <NOT DEFINED>" # -# If the optional argument 'SKIP_TRUNCATE' is provided, the +# If the option 'SKIP_TRUNCATE' is provided, the # text will NOT be truncated it too long. # -# If the optional argument 'OBFUSCATE' is provided, 'OBFUSCATED' will +# If the option 'OBFUSCATE' is provided, 'OBFUSCATED' will # be displayed instead of the variable value. # +# If the optional argument `PRETEXT <pretext>` is provided, +# `<pretext` will be displaying instead of `Setting <varname>`. +# # In the current implementation, the padding is hardcoded to a length of 40 # and the total text will be truncated if longer than 120 characters. # @@ -69,7 +72,7 @@ endfunction() include(CMakeParseArguments) function(slicer_setting_variable_message varname) set(options OBFUSCATE SKIP_TRUNCATE) - set(oneValueArgs ) + set(oneValueArgs PRETEXT) set(multiValueArgs ) CMAKE_PARSE_ARGUMENTS(LOCAL "${options}" @@ -82,6 +85,12 @@ function(slicer_setting_variable_message varname) set(truncate FALSE) endif() set(obfuscate ${LOCAL_OBFUSCATE}) + + set(pretext "Setting ${varname}") + if(DEFINED LOCAL_PRETEXT) + set(pretext ${LOCAL_PRETEXT}) + endif() + set(pretext_right_jusitfy_length 45) set(fill_char ".") set(truncated_text_length 120) @@ -96,7 +105,6 @@ function(slicer_setting_variable_message varname) set(_value "OBFUSCATED") endif() - set(pretext "Setting ${varname}") string(LENGTH ${pretext} pretext_length) math(EXPR pad_length "${pretext_right_jusitfy_length} - ${pretext_length} - 1") if(pad_length GREATER 0) @@ -145,6 +153,11 @@ function(slicer_setting_variable_message_test) set(YOU_SHOULD_NOT_SEE_THE_VALUE "You should not see this") slicer_setting_variable_message("YOU_SHOULD_NOT_SEE_THE_VALUE" OBFUSCATE) + set(YOU_SHOULD_SEE_DIFFERENT_PRETEXT "good") + slicer_setting_variable_message( + "YOU_SHOULD_SEE_DIFFERENT_PRETEXT" + PRETEXT "This is different pretext") + message("SUCCESS") endfunction() if(TEST_slicer_setting_variable_message_test) -- GitLab From 866bdfe788ea7a0fb124cc54e19c5643bab761a4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com> Date: Wed, 12 Oct 2016 11:30:50 -0400 Subject: [PATCH 4/5] BUG: Extension upload: Ensure missing optional metatdata do not cause failure This commit improves the Extension build system tests to check that: (1) optional extension metatdata NOT specified in the CMakeLists do NOT prevent the configure/build/test/upload from happening (2) metadata submitted to the extension server during the upload are the expected ones. Fixes #4276 --- CMake/UseSlicer.cmake.in | 13 ++ .../CMake/MIDASAPIUploadExtension.cmake | 6 +- .../Testing/SlicerExtensionBuildSystemTest.py | 114 +++++++++++++++++- 3 files changed, 129 insertions(+), 4 deletions(-) diff --git a/CMake/UseSlicer.cmake.in b/CMake/UseSlicer.cmake.in index 30c39c5f36..06d14f6082 100644 --- a/CMake/UseSlicer.cmake.in +++ b/CMake/UseSlicer.cmake.in @@ -399,6 +399,19 @@ if(NOT Slicer_DONT_USE_EXTENSION) slicer_setting_variable_message(EXTENSION_${var}) endforeach() + # + # If not defined, initialize optional variables with their default values. + # + foreach(var IN LISTS Slicer_EXT_OPTIONAL_METADATA_NAMES) + if(NOT DEFINED EXTENSION_${var} AND + NOT ${var} STREQUAL "SVNUSERNAME" AND + NOT ${var} STREQUAL "SVNPASSWORD") + set(EXTENSION_${var} "${Slicer_EXT_METADATA_${var}_DEFAULT}") + slicer_setting_variable_message(EXTENSION_${var} + PRETEXT "Setting default for EXTENSION_${var}") + endif() + endforeach() + #----------------------------------------------------------------------------- if(NOT DEFINED Slicer_SKIP_SlicerEnableExtensionTesting) set(Slicer_SKIP_SlicerEnableExtensionTesting FALSE) diff --git a/Extensions/CMake/MIDASAPIUploadExtension.cmake b/Extensions/CMake/MIDASAPIUploadExtension.cmake index 2e0dd33781..643afb090b 100644 --- a/Extensions/CMake/MIDASAPIUploadExtension.cmake +++ b/Extensions/CMake/MIDASAPIUploadExtension.cmake @@ -31,9 +31,6 @@ function(midas_api_upload_extension) set(expected_nonempty_args ARCHITECTURE - EXTENSION_CATEGORY - EXTENSION_ENABLED - EXTENSION_HOMEPAGE EXTENSION_NAME EXTENSION_REPOSITORY_TYPE EXTENSION_REPOSITORY_URL @@ -48,8 +45,11 @@ function(midas_api_upload_extension) SUBMISSION_TYPE ) set(optional_args + EXTENSION_CATEGORY EXTENSION_CONTRIBUTORS EXTENSION_DESCRIPTION + EXTENSION_ENABLED + EXTENSION_HOMEPAGE EXTENSION_ICONURL EXTENSION_SCREENSHOTURLS ) diff --git a/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py b/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py index 1bf7919121..97271a8f74 100644 --- a/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py +++ b/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py @@ -21,6 +21,10 @@ _server = None _midas_token = 'TestTokenWithExpectedLengthxxxxxxxxxxxxx' _requests = [] +_midas_upload_query_data = {} +"""Keep track of Midas upload query parameters for each submitted Extension. +""" + def get_cmakecache_values(file_path, variables): result = dict.fromkeys(variables) with open(file_path) as cmakecache: @@ -131,6 +135,13 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): response_type = "application/json" query_data = parse_qs(urlparse(self.path).query) if query_data['method'][0] == 'midas.slicerpackages.extension.upload': + + extension_name = query_data['productname'][0] + + # Keep track of method parameters + global _midas_upload_query_data + _midas_upload_query_data[extension_name] = query_data + # Send back extension data response_data = { 'stat': 'ok', @@ -138,7 +149,7 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): 'message': '', 'data': { 'extension': { - 'productname': query_data['productname'][0] + 'productname': extension_name # XXX Real server sends back all properties of extension DAO } } @@ -223,6 +234,20 @@ class SlicerExtensionBuildSystemTest(unittest.TestCase): if _server: _server.stop() + def _remove_matching_lines(self, filepath, patterns=[]): + """Given an input ``filepath`` and a list of ``patterns``, this function + will update the file in place removing all lines matching any of the + listed ``patterns``. + """ + updated_content = [] + with open(filepath) as content: + for line in content: + if any([pattern in line for pattern in patterns]): + continue + updated_content.append(line) + with open(filepath, 'w') as output: + output.write("".join(updated_content)) + def _prepare_test_binary_dir(self, test_binary_dir): # Remove binary directory @@ -274,6 +299,29 @@ class SlicerExtensionBuildSystemTest(unittest.TestCase): with open(extension_description_dir + '/TestExt%s.s4ext' % suffix, 'w') as description_file: description_file.write(description) + if suffix == 'A': + # + # Strip all optional metadata from Extension A. This allows to check + # that the full process can effectively succeed without them. + # See issue #4276 + # + # Extension A is chosen because it has no dependency. This mean we + # can even strip the DEPENDS option. + # + # Finally, note this is done after generating the description file + # because the ExtensionWizard currently expects them to be set. + # + # The list of optional metadata has been copied from + # SlicerExtensionDescriptionSpec.cmake CMake module. + # + patterns = ['EXTENSION_' + pattern for pattern in [ + 'SVNUSERNAME', 'SVNPASSWORD', 'DEPENDS', 'BUILD_SUBDIRECTORY', + 'HOMEPAGE', 'CONTRIBUTORS', 'CATEGORY', 'ICONURL', + 'DESCRIPTION', 'SCREENSHOTURLS', 'ENABLED', 'STATUS' + ]] + extension_dir = test_binary_dir + '/TestExt%s' % suffix + self._remove_matching_lines(extension_dir + '/CMakeLists.txt', patterns) + def test_index_build_with_upload(self): self._test_index_build('build_with_upload', True) @@ -394,6 +442,7 @@ include({slicer_source_dir}/Extensions/CMake/SlicerExtensionsDashboardDriverScri # Check self._check_caches(test_binary_dir + '/S-E') self._check_queries(test_upload, with_ctest=True) + self._check_midas_upload_query_parameters(test_upload, with_ctest=True) def _test_index_build(self, test_name, test_upload): @@ -450,6 +499,7 @@ include({slicer_source_dir}/Extensions/CMake/SlicerExtensionsDashboardDriverScri # Check self._check_caches(test_binary_dir) self._check_queries(test_upload, with_ctest=False) + self._check_midas_upload_query_parameters(test_upload, with_ctest=False) def _check_caches(self, test_binary_dir): @@ -553,3 +603,65 @@ include({slicer_source_dir}/Extensions/CMake/SlicerExtensionsDashboardDriverScri # Upload top-level build results and notes to CDash check_cdash_request(parse_request(requests.next()), 'PUT', r'.+Build\.xml') check_cdash_request(parse_request(requests.next()), 'PUT', r'.+Notes\.xml') + + def _check_midas_upload_query_parameters(self, test_upload, with_ctest=False): + if not test_upload: + for extensionName in ['TestExtA', 'TestExtB', 'TestExtC']: + self.assertTrue(extensionName not in _midas_upload_query_data) + + else: + + def _expected_parameters(extensionName): + expected = { + 'arch': ['amd64'], + 'codebase': ['Slicer4'], + 'method': ['midas.slicerpackages.extension.upload'], + 'name': None, # ['25430-linux-amd64-TestExtB-local0-0000-00-00.tar.gz'], + 'os': None, # ['linux'], + 'packagetype': ['archive'], + 'productname': [extensionName], + 'repository_type': ['local'], + 'repository_url': ['NA'], + 'revision': ['0'], + 'slicer_revision': None, #['25430'], + 'submissiontype': ['nightly'], + 'token': ['TestTokenWithExpectedLengthxxxxxxxxxxxxx'] + } + if extensionName != 'TestExtA': + expected.update({ + 'category': ['Examples'], + 'contributors': ['John Doe (AnyWare Corp.)'], + 'description': ['This is an example of a simple extension'], + 'enabled': ['1'], + 'homepage': ['http://slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/%s' % extensionName], + 'icon_url': ['http://www.example.com/Slicer/Extensions/%s.png' % extensionName], + 'screenshots': ['http://www.example.com/Slicer/Extensions/%s/Screenshots/1.png' % extensionName], + }) + else: + # XXX We should have a way to get the default value from + # SlicerExtensionDescriptionSpec.cmake + # XXX Empty parameter are not sent to the server + expected.update({ + #'category': [''], + #'contributors': [''], + #'description': [''], + 'enabled': ['1'], + #'homepage': [''], + #'icon_url': [''], + #'screenshots': [''], + }) + return expected + + for extensionName in ['TestExtA', 'TestExtB', 'TestExtC']: + query_data = _midas_upload_query_data[extensionName] + expected_query_data = _expected_parameters(extensionName) + + self.assertEqual(sorted(query_data.keys()), sorted(expected_query_data.keys())) + + for key, expected_value in expected_query_data.items(): + current_value = query_data[key] + if expected_value is None: + # XXX For now only consider values that do not change with platform + # and Slicer revision. + continue + self.assertEqual(current_value, expected_value) -- GitLab From f0eb21f82bbea391a92864e3a9e448dd53018bc1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin <jchris.fillionr@kitware.com> Date: Wed, 12 Oct 2016 13:30:52 -0400 Subject: [PATCH 5/5] BUG: Ensure ExtensionBuildSystem tests propagate CMAKE_OSX_* vars This commit fixes error like this one: ``` 7: -- Setting OSX_ARCHITECTURES to 'x86_64' as none was specified. 7: -- Setting OSX_SYSROOT to latest '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk' as none was specified. 7: CMake Error at /Users/inorton/git/slcr/r4/CMake/SlicerBlockSetCMakeOSXVariables.cmake:102 (message): 7: The OSX_SYSROOT is set to version 10.12 (>10.8) and OSX_DEPLOYMENT_TARGET 7: is not explicitly set! 7: 7: Since: 7: 7: (1) the default runtime associated with >=10.9 deployment target is 'libc++'.[1] 7: (2) the default runtime associated with <=10.8 deployment target is 'libstdc++'. 7: (3) Qt support for 'macx-clang-libc++' is listed as 'unsupported' mkspecs. 7: (4) Qt binaries may be build against 'libstdc++' or 'libc++'. 7: (5) Mixing the two different runtime in binaries is unstable. 7: [1]http://stackoverflow.com/questions/19637164/c-linking-error-after-upgrading-to-mac-os-x-10-9-xcode-5-0-1/19637199#19637199 7: 7: -------------------------------- 7: 7: Run '$otool -L $(which qmake) |grep lib.\*c++' to check what library Qt is 7: built against: 7: 7: (1) if it is libstdc++ then add '-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.8' (or older) to the cmake command line. 7: (2) if it is libc++ then add '-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.9' (or newer) to the cmake command line. 7: 7: Call Stack (most recent call first): 7: CMakeLists.txt:14 (include) 7: ``` Reported-by: Isaiah Norton <isaiah.norton@gmail.com> Tested-by: Isaiah Norton <isaiah.norton@gmail.com> --- .../CMake/Testing/SlicerExtensionBuildSystemTest.py | 11 ++++++++++- .../SlicerExtensionBuildSystemTestConfig.py.in | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py b/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py index 97271a8f74..564aa0b3e4 100644 --- a/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py +++ b/Extensions/CMake/Testing/SlicerExtensionBuildSystemTest.py @@ -376,6 +376,9 @@ Slicer_EXTENSION_DESCRIPTION_DIR:PATH={extension_description_dir} Slicer_LOCAL_EXTENSIONS_DIR:PATH={local_extensions_dir} CMAKE_C_COMPILER:PATH={cmake_c_compiler} CMAKE_CXX_COMPILER:PATH={cmake_cxx_compiler} +CMAKE_OSX_DEPLOYMENT_TARGET={cmake_osx_deployment_target} +CMAKE_OSX_ARCHITECTURES= {cmake_osx_architectures} +CMAKE_OSX_SYSROOT={cmake_osx_sysroot} ") set(CTEST_GIT_COMMAND "{git_executable}") @@ -411,6 +414,9 @@ include({slicer_source_dir}/Extensions/CMake/SlicerExtensionsDashboardDriverScri cmake_generator=config.CMAKE_GENERATOR, cmake_generator_platform=config.CMAKE_GENERATOR_PLATFORM, cmake_generator_toolset=config.CMAKE_GENERATOR_TOOLSET, + cmake_osx_deployment_target=config.CMAKE_OSX_DEPLOYMENT_TARGET, + cmake_osx_architectures=config.CMAKE_OSX_ARCHITECTURES, + cmake_osx_sysroot=config.CMAKE_OSX_SYSROOT, compiler_name=compiler_name, ctest_drop_site=self.ctest_drop_site, ctest_build_configuration=build_config, @@ -461,7 +467,10 @@ include({slicer_source_dir}/Extensions/CMake/SlicerExtensionsDashboardDriverScri '-DCMAKE_C_COMPILER:PATH=' + config.CMAKE_C_COMPILER, '-DCMAKE_CXX_COMPILER:PATH=' + config.CMAKE_CXX_COMPILER, '-DGIT_EXECUTABLE:PATH=' + config.GIT_EXECUTABLE, - '-DSubversion_SVN_EXECUTABLE:PATH=' + config.Subversion_SVN_EXECUTABLE + '-DSubversion_SVN_EXECUTABLE:PATH=' + config.Subversion_SVN_EXECUTABLE, + '-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=' + config.CMAKE_OSX_DEPLOYMENT_TARGET, + '-DCMAKE_OSX_ARCHITECTURES:STRING=' + config.CMAKE_OSX_ARCHITECTURES, + '-DCMAKE_OSX_SYSROOT:PATH=' + config.CMAKE_OSX_SYSROOT ] if not config.CMAKE_CONFIGURATION_TYPES: diff --git a/Extensions/CMake/Testing/SlicerExtensionBuildSystemTestConfig.py.in b/Extensions/CMake/Testing/SlicerExtensionBuildSystemTestConfig.py.in index 11aa31c3c4..a71373723c 100644 --- a/Extensions/CMake/Testing/SlicerExtensionBuildSystemTestConfig.py.in +++ b/Extensions/CMake/Testing/SlicerExtensionBuildSystemTestConfig.py.in @@ -13,6 +13,10 @@ CMAKE_GENERATOR = '@CMAKE_GENERATOR@' CMAKE_GENERATOR_PLATFORM = '@CMAKE_GENERATOR_PLATFORM@' CMAKE_GENERATOR_TOOLSET = '@CMAKE_GENERATOR_TOOLSET@' +CMAKE_OSX_DEPLOYMENT_TARGET = '@CMAKE_OSX_DEPLOYMENT_TARGET@' +CMAKE_OSX_ARCHITECTURES = '@CMAKE_OSX_ARCHITECTURES@' +CMAKE_OSX_SYSROOT = '@CMAKE_OSX_SYSROOT@' + MIDAS_PACKAGE_API_KEY = 'ThisIsATestApiKeyOfExpectedLengthxxxxxxx' MIDAS_PACKAGE_EMAIL = 'test@slicer.org' -- GitLab