Example #1
0
    def test_setup_centralized_project(self, mocked=None):
        """
        Test setting up a Project.
        """
        def mocked_resolve_core_path(core_path):
            return {
                "linux2": core_path,
                "darwin": core_path,
                "win32": core_path
            }

        mocked.side_effect = mocked_resolve_core_path

        # create new project
        new_project = {
            "type": "Project",
            "id": 1234,
            "name": "new_project_1234"
        }
        self.add_to_sg_mock_db(new_project)
        # location where the config will be installed
        new_config_root = os.path.join(self.tank_temp,
                                       "new_project_1234_config")
        # location where the data will be installed
        os.makedirs(os.path.join(self.tank_temp, "new_project_1234"))

        command = self.tk.get_command("setup_project")
        command.set_logger(logging.getLogger("/dev/null"))
        # Test we can setup a new project and it does not fail.
        command.execute({
            "project_id":
            new_project["id"],
            "project_folder_name":
            "new_project_1234",
            "config_uri":
            self.project_config,
            "config_path_mac":
            new_config_root if is_macos() else None,
            "config_path_win":
            new_config_root if is_windows() else None,
            "config_path_linux":
            new_config_root if is_linux() else None,
        })

        # Check we get back our custom primary root name
        new_pc = tank.pipelineconfig_factory.from_path(new_config_root)
        self.assertEqual(list(new_pc.get_data_roots().keys()),
                         ["setup_project_root"])

        # make sure the fake core didn't get copied across, e.g. that
        # we didn't localize the setup
        self.assertFalse(
            os.path.exists(
                os.path.join(new_config_root, "install", "core", "bad_path")))

        # make sure we have the core location files for this unlocalized setup
        self.assertTrue(
            os.path.exists(
                os.path.join(new_config_root, "install", "core",
                             "core_Darwin.cfg")))
Example #2
0
    def _jump_to_fs(self):
        """
        Jump from context to FS
        """
        # launch one window for each location on disk
        paths = self._engine.context.filesystem_locations
        for disk_location in paths:

            # get the setting
            system = sys.platform

            # run the app
            if is_linux():
                args = ["xdg-open", disk_location]
            elif is_macos():
                args = ['open "%s"', disk_location]
            elif is_windows():
                args = [
                    "cmd.exe", "/C", "start",
                    '"Folder %s"' % disk_location
                ]
            else:
                raise Exception("Platform '%s' is not supported." % system)

            exit_code = subprocess.check_output(args, shell=False)
            if exit_code != 0:
                self._engine.logger.error("Failed to launch '%s'!", args)
Example #3
0
    def test_legacy_global(self):
        """
        tests the global root, 0.17 style
        """
        cache_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.CACHE, LocalFileStorageManager.CORE_V17
        )
        persistent_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.PERSISTENT, LocalFileStorageManager.CORE_V17
        )
        log_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.LOGGING, LocalFileStorageManager.CORE_V17
        )

        if is_macos():
            self.assertEqual(cache_path, os.path.expanduser("~/Library/Caches/Shotgun"))
            self.assertEqual(
                persistent_path,
                os.path.expanduser("~/Library/Application Support/Shotgun"),
            )
            self.assertEqual(log_path, os.path.expanduser("~/Library/Logs/Shotgun"))

        elif is_windows():
            app_data = os.environ.get("APPDATA", "APPDATA_NOT_SET")
            self.assertEqual(cache_path, os.path.join(app_data, "Shotgun"))
            self.assertEqual(persistent_path, os.path.join(app_data, "Shotgun"))
            self.assertEqual(log_path, os.path.join(app_data, "Shotgun"))

        else:
            # linux
            self.assertEqual(cache_path, os.path.expanduser("~/.shotgun"))
            self.assertEqual(persistent_path, os.path.expanduser("~/.shotgun"))
            self.assertEqual(log_path, os.path.expanduser("~/.shotgun"))
    def _test_config_locations(self, pc, autogen_files_root, config_files_root):
        """
        Test locations that are reported by the configuration.
        """
        # Pipeline configuration location tests.
        self.assertEqual(pc.get_path(), autogen_files_root)
        self.assertEqual(
            pc.get_yaml_cache_location(),
            os.path.join(autogen_files_root, "yaml_cache.pickle"),
        )
        self.assertEqual(
            pc._get_pipeline_config_file_location(),
            os.path.join(
                autogen_files_root, "config", "core", "pipeline_configuration.yml"
            ),
        )
        self.assertEqual(
            pc._storage_roots.roots_file,
            os.path.join(autogen_files_root, "config", "core", "roots.yml"),
        )
        self.assertEqual(
            pc.get_all_os_paths(),
            tank.util.ShotgunPath(
                autogen_files_root if is_windows() else None,
                autogen_files_root if is_linux() else None,
                autogen_files_root if is_macos() else None,
            ),
        )

        # Config folder location test.
        self.assertEqual(pc.get_config_location(), os.path.join(config_files_root))
        self.assertEqual(
            pc.get_core_hooks_location(),
            os.path.join(config_files_root, "core", "hooks"),
        )
        self.assertEqual(
            pc.get_schema_config_location(),
            os.path.join(config_files_root, "core", "schema"),
        )
        self.assertEqual(
            pc.get_hooks_location(), os.path.join(config_files_root, "hooks")
        )
        self.assertEqual(
            pc.get_shotgun_menu_cache_location(),
            os.path.join(autogen_files_root, "cache"),
        )
        self.assertEqual(
            pc.get_environment_path("test"),
            os.path.join(config_files_root, "env", "test.yml"),
        )
        self.assertEqual(
            pc._get_templates_config_location(),
            os.path.join(config_files_root, "core", "templates.yml"),
        )
Example #5
0
    def test_folder(self, subprocess_mock):
        """
        Tests opening a folder
        """
        fs.open_file_browser(self.test_folder)
        args, kwargs = subprocess_mock.call_args

        if is_linux():
            self.assertEqual(args[0], ["xdg-open", self.test_folder])

        elif is_macos():
            self.assertEqual(args[0], ["open", self.test_folder])

        elif is_windows():
            self.assertEqual(args[0], ["cmd.exe", "/C", "start", self.test_folder])
Example #6
0
    def test_file(self, subprocess_mock):
        """
        Tests opening a file
        """
        fs.open_file_browser(self.test_file)
        args, kwargs = subprocess_mock.call_args

        if is_linux():
            self.assertEqual(args[0], ["xdg-open", os.path.dirname(self.test_file)])

        elif is_macos():
            self.assertEqual(args[0], ["open", "-R", self.test_file])

        elif is_windows():
            self.assertEqual(args[0], ["explorer", "/select,", self.test_file])
Example #7
0
 def test_get_shotgun_storage_key(self):
     """
     Tests get_shotgun_storage_key
     """
     gssk = ShotgunPath.get_shotgun_storage_key
     self.assertEqual(gssk("win32"), "windows_path")
     self.assertEqual(gssk("linux2"), "linux_path")
     self.assertEqual(gssk("linux"), "linux_path")
     self.assertEqual(gssk("linux3"), "linux_path")
     self.assertEqual(gssk("darwin"), "mac_path")
     if is_windows():
         self.assertEqual(gssk(), "windows_path")
     if is_macos():
         self.assertEqual(gssk(), "mac_path")
     if is_linux():
         self.assertEqual(gssk(), "linux_path")
Example #8
0
    def test_global(self):
        """
        tests the global root
        """
        pref_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.PREFERENCES
        )
        cache_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.CACHE
        )
        persistent_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.PERSISTENT
        )
        log_path = LocalFileStorageManager.get_global_root(
            LocalFileStorageManager.LOGGING
        )

        if is_macos():
            self.assertEqual(cache_path, os.path.expanduser("~/Library/Caches/Shotgun"))
            self.assertEqual(
                pref_path, os.path.expanduser("~/Library/Preferences/Shotgun")
            )
            self.assertEqual(
                persistent_path,
                os.path.expanduser("~/Library/Application Support/Shotgun"),
            )
            self.assertEqual(log_path, os.path.expanduser("~/Library/Logs/Shotgun"))

        elif is_windows():
            app_data = os.environ.get("APPDATA", "APPDATA_NOT_SET")
            self.assertEqual(cache_path, os.path.join(app_data, "Shotgun"))
            self.assertEqual(
                pref_path, os.path.join(app_data, "Shotgun", "Preferences")
            )
            self.assertEqual(persistent_path, os.path.join(app_data, "Shotgun", "Data"))
            self.assertEqual(log_path, os.path.join(app_data, "Shotgun", "Logs"))

        else:
            # linux
            self.assertEqual(cache_path, os.path.expanduser("~/.shotgun"))
            self.assertEqual(pref_path, os.path.expanduser("~/.shotgun/preferences"))
            self.assertEqual(persistent_path, os.path.expanduser("~/.shotgun/data"))
            self.assertEqual(log_path, os.path.expanduser("~/.shotgun/logs"))
Example #9
0
    def test_paths(self):
        """Test paths match those in roots for current os."""
        root_file = open(self.root_file_path, "w")
        root_file.write(yaml.dump(self.roots))
        root_file.close()

        pc = tank.pipelineconfig_factory.from_path(self.project_root)
        result = pc.get_data_roots()

        # Determine platform
        if is_macos():
            platform = "mac_path"
        elif is_linux():
            platform = "linux_path"
        elif is_windows():
            platform = "windows_path"

        project_name = os.path.basename(self.project_root)
        for root_name, root_path in result.items():
            expected_path = os.path.join(self.roots[root_name][platform],
                                         project_name)
            self.assertEqual(expected_path, root_path)
    def test_desktop_interpreter(self):
        """
        Checks that if we're running in the Shotgun Desktop we're writing the correct interpreter.
        """
        expected_interpreters = self._get_default_intepreters()
        if is_windows():
            sys_prefix = r"C:\Program Files\Shotgun.v1.4.3\Python"
            sys_executable = r"C:\Program Files\Shotgun_v1.4.3\Shotgun.exe"
            python_exe = os.path.join(sys_prefix, "python.exe")
        elif is_macos():
            sys_prefix = "/Applications/Shotgun.v1.4.3.app/Contents/Resources/Python"
            sys_executable = "/Applications/Shotgun.v1.4.3.app/Contents/MacOS/Shotgun"
            python_exe = os.path.join(sys_prefix, "bin", "python")
        else:
            sys_prefix = "/opt/Shotgun.v.1.4.3/Python"
            sys_executable = "/opt/Shotgun.v.1.4.3/Shotgun"
            python_exe = os.path.join(sys_prefix, "bin", "python")

        expected_interpreters.current_os = python_exe

        interpreters = self._write_interpreter_file(sys_executable, sys_prefix)

        self.assertEqual(interpreters, expected_interpreters)
Example #11
0
    def test_env_var(self):
        """
        Tests that if the current os is not defined
        in the shotgun local storage defs, we can override
        it by setting an env var.
        """
        # add a storage and omit current os
        self.storage = {
            "type": "LocalStorage",
            "id": 2,
            "code": "home",
            "mac_path": "/local",
            "windows_path": "x:\\",
            "linux_path": "/local",
        }

        current_path_field = {
            "win32": "windows_path",
            "linux2": "linux_path",
            "darwin": "mac_path",
        }[sgsix.platform]

        self.storage[current_path_field] = None
        self.add_to_sg_mock_db([self.storage])

        # add a publish record
        sg_dict = {
            "id": 123,
            "type": "PublishedFile",
            "code": "foo",
            "path": {
                "content_type": "image/png",
                "id": 25826,
                "link_type": "local",
                "local_path": None,
                "local_path_linux": "/local/path/to/file.ext",
                "local_path_mac": "/local/path/to/file.ext",
                "local_path_windows": r"X:\path\to\file.ext",
                "local_storage": {
                    "id": 2,
                    "name": "home",
                    "type": "LocalStorage"
                },
                "name": "foo.png",
                "type": "Attachment",
                "url": "file:///local/path/to/file.ext",
            },
        }

        if is_windows():
            os.environ["SHOTGUN_PATH_WINDOWS_HOME"] = "Y:\\"
            local_path = r"Y:\path\to\file.ext"
            sg_dict["path"]["local_path_windows"] = None
        elif is_macos():
            os.environ["SHOTGUN_PATH_MAC_HOME"] = "/local_override"
            local_path = "/local_override/path/to/file.ext"
            sg_dict["path"]["local_path_mac"] = None
        elif is_linux():
            os.environ["SHOTGUN_PATH_LINUX_HOME"] = "/local_override"
            local_path = "/local_override/path/to/file.ext"
            sg_dict["path"]["local_path_linux"] = None

        evaluated_path = sgtk.util.resolve_publish_path(self.tk, sg_dict)
        self.assertEqual(evaluated_path, local_path)
Example #12
0
    def test_construction(self):
        """
        Tests get_cache_root
        """
        self.assertEqual(ShotgunPath.SHOTGUN_PATH_FIELDS,
                         ["windows_path", "linux_path", "mac_path"])

        sg = ShotgunPath.from_shotgun_dict({
            "windows_path": "C:\\temp",
            "mac_path": "/tmp",
            "linux_path": "/tmp2",
            "foo": "bar",
        })

        self.assertEqual(sg.windows, "C:\\temp")
        self.assertEqual(sg.macosx, "/tmp")
        self.assertEqual(sg.linux, "/tmp2")

        sg = ShotgunPath.from_shotgun_dict({
            "windows_path": "C:\\temp",
            "mac_path": None,
            "foo": "bar"
        })

        self.assertEqual(sg.windows, "C:\\temp")
        self.assertEqual(sg.macosx, None)
        self.assertEqual(sg.linux, None)

        sys_paths = ShotgunPath.from_system_dict({
            "win32": "C:\\temp",
            "darwin": "/tmp",
            "linux2": "/tmp2",
            "foo": "bar"
        })

        self.assertEqual(sys_paths.windows, "C:\\temp")
        self.assertEqual(sys_paths.macosx, "/tmp")
        self.assertEqual(sys_paths.linux, "/tmp2")

        sys_paths = ShotgunPath.from_system_dict({
            "win32": "C:\\temp",
            "darwin": None,
            "foo": "bar"
        })

        self.assertEqual(sys_paths.windows, "C:\\temp")
        self.assertEqual(sys_paths.macosx, None)
        self.assertEqual(sys_paths.linux, None)

        if is_windows():
            curr = ShotgunPath.from_current_os_path("\\\\server\\mount\\path")
            self.assertEqual(curr.windows, "\\\\server\\mount\\path")
            self.assertEqual(curr.macosx, None)
            self.assertEqual(curr.linux, None)
            self.assertEqual(curr.current_os, curr.windows)

        if is_linux():
            curr = ShotgunPath.from_current_os_path("/tmp/foo/bar")
            self.assertEqual(curr.windows, None)
            self.assertEqual(curr.macosx, None)
            self.assertEqual(curr.linux, "/tmp/foo/bar")
            self.assertEqual(curr.current_os, curr.linux)

        if is_macos():
            curr = ShotgunPath.from_current_os_path("/tmp/foo/bar")
            self.assertEqual(curr.windows, None)
            self.assertEqual(curr.macosx, "/tmp/foo/bar")
            self.assertEqual(curr.linux, None)
            self.assertEqual(curr.current_os, curr.macosx)

        std_constructor = ShotgunPath("C:\\temp", "/tmp", "/tmp2")
        self.assertEqual(std_constructor.windows, "C:\\temp")
        self.assertEqual(std_constructor.macosx, "/tmp2")
        self.assertEqual(std_constructor.linux, "/tmp")
    def _setup_project(self, is_localized):
        """
        Setups a Toolkit centralized pipeline configuration with a localized or not core.
        """

        # Create the project's destination folder.
        locality = "localized" if is_localized else "studio"
        project_folder_name = "config_with_%s_core" % locality
        config_root = os.path.join(
            self.tank_temp, project_folder_name, "pipeline_configuration"
        )

        os.makedirs(os.path.join(self.tank_temp, project_folder_name))

        # Mock a core that will setup the project.
        core_root = os.path.join(self.tank_temp, "%s_core" % locality)
        core_install_folder = os.path.join(core_root, "install", "core")
        os.makedirs(core_install_folder)

        # Copy the core info.yml, since the config expects a certain version of
        # core and the setup project needs to be able to compare versions.
        shutil.copy(
            os.path.join(os.path.dirname(__file__), "..", "..", "info.yml"),
            os.path.join(core_install_folder, "info.yml"),
        )

        # Mock a localized core if required.
        if is_localized:
            self.create_file(
                os.path.join(core_root, "config", "core", "interpreter_Darwin.cfg")
            )
            self.create_file(
                os.path.join(core_root, "config", "core", "interpreter_Windows.cfg")
            )
            self.create_file(
                os.path.join(core_root, "config", "core", "interpreter_Linux.cfg")
            )
            self.create_file(os.path.join(core_root, "config", "core", "shotgun.yml"))
            self.create_file(os.path.join(core_root, "config", "core", "roots.yml"))
            self.create_file(os.path.join(core_install_folder, "_core_upgrader.py"))
            self.assertEqual(tank.pipelineconfig_utils.is_localized(core_root), True)

        # We have to patch these methods because the core doesn't actually exist on disk for the tests.
        with patch(
            "sgtk.pipelineconfig_utils.get_path_to_current_core", return_value=core_root
        ):
            with patch(
                "sgtk.pipelineconfig_utils.resolve_all_os_paths_to_core",
                return_value={
                    "linux2": core_root if is_linux() else None,
                    "win32": core_root if is_windows() else None,
                    "darwin": core_root if is_macos() else None,
                },
            ):
                command = get_command("setup_project", self.tk)
                command.set_logger(logging.getLogger("test"))
                command.execute(
                    dict(
                        config_uri=os.path.join(self.fixtures_root, "config"),
                        project_id=self._project["id"],
                        project_folder_name=project_folder_name,
                        config_path_mac=config_root if is_macos() else None,
                        config_path_win=config_root if is_windows() else None,
                        config_path_linux=config_root if is_linux() else None,
                        check_storage_path_exists=False,
                    )
                )

        tk = tank.sgtk_from_path(config_root)
        pc = tk.pipeline_configuration

        return pc, config_root, core_root
Example #14
0
    def init_engine(self):
        """
        Initializes the Rumba engine.
        """
        self.logger.debug("%s: Initializing...", self)

        # check that we are running a supported OS
        if not any([is_windows(), is_linux(), is_macos()]):
            raise tank.TankError(
                "The current platform is not supported!"
                " Supported platforms "
                "are Mac, Linux 64 and Windows 64."
            )

        # check that we are running an ok version of Rumba
        rumba_build_version = rversion.rumba_version
        rumba_build_version = rumba_build_version.replace("-beta", "")
        rumba_ver = float(".".join(rumba_build_version.split(".")[:2]))

        if rumba_ver < MIN_COMPATIBILITY_VERSION:
            msg = (
                "Shotgun integration is not compatible with %s versions older than %s"
                % (
                    APPLICATION_NAME,
                    MIN_COMPATIBILITY_VERSION,
                )
            )
            show_error(msg)
            raise tank.TankError(msg)

        if rumba_ver > MIN_COMPATIBILITY_VERSION + 1:
            # show a warning that this version of Rumba isn't yet fully tested
            # with Shotgun:
            msg = (
                "The Shotgun Pipeline Toolkit has not yet been fully "
                "tested with %s %s.  "
                "You can continue to use Toolkit but you may experience "
                "bugs or instability."
                "\n\n" % (APPLICATION_NAME, rumba_ver)
            )

            # determine if we should show the compatibility warning dialog:
            show_warning_dlg = self.has_ui and SHOW_COMP_DLG not in os.environ

            if show_warning_dlg:
                # make sure we only show it once per session
                os.environ[SHOW_COMP_DLG] = "1"

                # split off the major version number - accommodate complex
                # version strings and decimals:
                major_version_number_str = rumba_build_version.split(".")[0]
                if major_version_number_str and major_version_number_str.isdigit():
                    # check against the compatibility_dialog_min_version
                    # setting
                    min_ver = self.get_setting("compatibility_dialog_min_version")
                    if int(major_version_number_str) < min_ver:
                        show_warning_dlg = False

            if show_warning_dlg:
                # Note, title is padded to try to ensure dialog isn't insanely
                # narrow!
                show_info(msg)

            # always log the warning to the script editor:
            self.logger.warning(msg)

            # In the case of Windows, we have the possibility of locking up if
            # we allow the PySide shim to import QtWebEngineWidgets.
            # We can stop that happening here by setting the following
            # environment variable.

            # Note that prior PyQt5 v5.12 this module existed, after that it has
            # been separated and would not cause any issues. Since it is no
            # harm if the module is not there, we leave it just in case older
            # versions of Rumba were using previous versions of PyQt
            # https://www.riverbankcomputing.com/software/pyqtwebengine/intro
            if is_windows():
                self.logger.debug(
                    "This application on Windows can deadlock if QtWebEngineWidgets "
                    "is imported. Setting "
                    "SHOTGUN_SKIP_QTWEBENGINEWIDGETS_IMPORT=1..."
                )
                os.environ["SHOTGUN_SKIP_QTWEBENGINEWIDGETS_IMPORT"] = "1"

        # check that we can load the GUI libraries
        self.logger.info("before init pyside")
        self._init_pyside()
        self.logger.info("after init pyside")
        # default menu name is Shotgun but this can be overriden
        # in the configuration to be Sgtk in case of conflicts
        self._menu_name = "Shotgun"
        if self.get_setting("use_sgtk_as_menu_name", False):
            self._menu_name = "Sgtk"
Example #15
0
    def _apply_fields(self,
                      fields,
                      ignore_types=None,
                      platform=None,
                      skip_defaults=False):
        """
        Creates path using fields.

        :param fields: Mapping of keys to fields. Keys must match those in template
                       definition.
        :param ignore_types: Keys for whom the defined type is ignored as list of strings.
                            This allows setting a Key whose type is int with a string value.
        :param platform: Optional operating system platform. If you leave it at the
                         default value of None, paths will be created to match the
                         current operating system. If you pass in a sys.platform-style string
                         (e.g. 'win32', 'linux2' or 'darwin'), paths will be generated to
                         match that platform.
        :param skip_defaults: Optional. If set to True, if a key has a default value and no
                              corresponding value in the fields argument, its default value
                              will be used. If set to False, keys that are not specified in
                              the fields argument are skipped whether they have a default
                              value or not. Defaults to False

        :returns: Full path, matching the template with the given fields inserted.
        """
        relative_path = super(TemplatePath,
                              self)._apply_fields(fields,
                                                  ignore_types,
                                                  platform,
                                                  skip_defaults=skip_defaults)

        if platform is None:
            # return the current OS platform's path
            return (os.path.join(self.root_path, relative_path)
                    if relative_path else self.root_path)

        else:
            platform = sgsix.normalize_platform(platform)
            # caller has requested a path for another OS
            if self._per_platform_roots is None:
                # it's possible that the additional os paths are not set for a template
                # object (mainly because of backwards compatibility reasons) and in this case
                # we cannot compute the path.
                raise TankError(
                    "Template %s cannot resolve path for operating system '%s' - "
                    "it was instantiated in a mode which only supports the resolving "
                    "of current operating system paths." % (self, platform))

            platform_root_path = self._per_platform_roots.get(platform)

            if platform_root_path is None:
                # either the platform is undefined or unknown
                raise TankError(
                    "Cannot resolve path for operating system '%s'! Please ensure "
                    "that you have a valid storage set up for this platform." %
                    platform)

            elif is_windows(platform):
                # use backslashes for windows
                if relative_path:
                    return "%s\\%s" % (
                        platform_root_path,
                        relative_path.replace(os.sep, "\\"),
                    )
                else:
                    # not path generated - just return the root path
                    return platform_root_path

            elif is_macos(platform) or is_linux(platform):
                # unix-like plaforms - use slashes
                if relative_path:
                    return "%s/%s" % (
                        platform_root_path,
                        relative_path.replace(os.sep, "/"),
                    )
                else:
                    # not path generated - just return the root path
                    return platform_root_path

            else:
                raise TankError(
                    "Cannot evaluate path. Unsupported platform '%s'." %
                    platform)
Example #16
0
    def test_setup_project_with_external_core(
            self, resolve_all_os_paths_to_core_mock,
            get_install_location_mock):
        """
        Test setting up a Project config that has a core/core_api.yml file included.
        """
        def mocked_resolve_core_path(core_path):
            return {
                "linux2": core_path,
                "darwin": core_path,
                "win32": core_path
            }

        resolve_all_os_paths_to_core_mock.side_effect = mocked_resolve_core_path

        def mocked_get_install_location():
            return self._fake_core_install

        get_install_location_mock.side_effect = mocked_get_install_location

        # add a core_api.yml to our config that we are installing from, telling the
        # setup project command to use this when running the localize portion of the setup.
        core_api_path = os.path.join(self.project_config, "core",
                                     "core_api.yml")
        with open(core_api_path, "wt") as fp:
            fp.write("location:\n")
            fp.write("   type: dev\n")
            fp.write("   path: %s\n" % self.tank_source_path)

        try:
            # create new project
            new_project = {
                "type": "Project",
                "id": 1235,
                "name": "new_project_1235"
            }
            self.add_to_sg_mock_db(new_project)
            new_config_root = os.path.join(self.tank_temp,
                                           "new_project_1235_config")
            # location where the data will be installed
            os.makedirs(os.path.join(self.tank_temp, "new_project_1235"))

            command = self.tk.get_command("setup_project")
            command.set_logger(logging.getLogger("/dev/null"))
            # Test we can setup a new project and it does not fail.
            command.execute({
                "project_id":
                new_project["id"],
                "project_folder_name":
                "new_project_1235",
                "config_uri":
                self.project_config,
                "config_path_mac":
                new_config_root if is_macos() else None,
                "config_path_win":
                new_config_root if is_windows() else None,
                "config_path_linux":
                new_config_root if is_linux() else None,
            })

            # Check we get back our custom primary root name
            new_pc = tank.pipelineconfig_factory.from_path(new_config_root)
            self.assertEqual(list(new_pc.get_data_roots().keys()),
                             ["setup_project_root"])

            # the 'fake' core that we mocked earlier has a 'bad_path' folder
            self.assertFalse(
                os.path.exists(
                    os.path.join(new_config_root, "install", "core",
                                 "bad_path")))

            # instead we expect a full installl
            self.assertTrue(
                os.path.exists(
                    os.path.join(
                        new_config_root,
                        "install",
                        "core",
                        "python",
                        "tank",
                        "errors.py",
                    )))

        finally:
            os.remove(core_api_path)
Example #17
0
    def init_engine(self):
        """
        Initializes the Blender engine.
        """
        self.logger.debug("%s: Initializing...", self)

        # check that we are running a supported OS
        if not any([is_windows(), is_linux(), is_macos()]):
            raise tank.TankError("The current platform is not supported!"
                                 " Supported platforms "
                                 "are Mac, Linux 64 and Windows 64.")

        # check that we are running an ok version of Blender
        build_version = bpy.app.version
        app_ver = float(".".join(map(str, build_version[:2])))

        if app_ver < MIN_COMPATIBILITY_VERSION:
            msg = (
                "Shotgun integration is not compatible with %s versions older than %s"
                % (
                    APPLICATION_NAME,
                    MIN_COMPATIBILITY_VERSION,
                ))
            self.show_error(msg)
            raise tank.TankError(msg)

        if app_ver > MIN_COMPATIBILITY_VERSION:
            # show a warning that this version of Blender isn't yet fully tested
            # with Shotgun:
            msg = ("The Shotgun Pipeline Toolkit has not yet been fully "
                   "tested with %s %s.  "
                   "You can continue to use Toolkit but you may experience "
                   "bugs or instability."
                   "\n\n" % (APPLICATION_NAME, app_ver))

            # determine if we should show the compatibility warning dialog:
            show_warning_dlg = self.has_ui and SHOW_COMP_DLG not in os.environ

            if show_warning_dlg:
                # make sure we only show it once per session
                os.environ[SHOW_COMP_DLG] = "1"

                min_ver = self.get_setting("compatibility_dialog_min_version")
                if build_version[0] < min_ver:
                    show_warning_dlg = False

            if show_warning_dlg:
                # Note, title is padded to try to ensure dialog isn't insanely
                # narrow!
                self.show_info(msg)

            # always log the warning to the script editor:
            self.logger.warning(msg)

            # In the case of Windows, we have the possibility of locking up if
            # we allow the PySide shim to import QtWebEngineWidgets.
            # We can stop that happening here by setting the following
            # environment variable.

            # Note that prior PyQt5 v5.12 this module existed, after that it has
            # been separated and would not cause any issues.
            # https://www.riverbankcomputing.com/software/pyqtwebengine/intro
            if is_windows():
                self.logger.debug(
                    "This application on Windows can deadlock if QtWebEngineWidgets "
                    "is imported. Setting "
                    "SHOTGUN_SKIP_QTWEBENGINEWIDGETS_IMPORT=1...")
                os.environ["SHOTGUN_SKIP_QTWEBENGINEWIDGETS_IMPORT"] = "1"

        # default menu name is Shotgun but this can be overriden
        # in the configuration to be Sgtk in case of conflicts
        self._menu_name = "Shotgun"
        if self.get_setting("use_sgtk_as_menu_name", False):
            self._menu_name = "Sgtk"

        if self.get_setting("automatic_context_switch", True):
            # need to watch some scene events in case the engine needs rebuilding:
            setup_app_handlers()
            self.logger.debug("Registered open and save callbacks.")
Example #18
0
    def test_01_setup_legacy_bootstrap_core(self):
        """
        Sets up a site-wide configuration like Shotgun Desktop 1.3.6 used to do so we
        can make sure it doesn't get broken by more recent versions of tk-core.
        """
        self.remove_files(self.legacy_bootstrap_core,
                          self.site_config_location)

        if is_macos():
            path_param = "config_path_mac"
        elif is_windows():
            path_param = "config_path_win"
        elif is_linux():
            path_param = "config_path_linux"

        cw = sgtk.bootstrap.configuration_writer.ConfigurationWriter(
            sgtk.util.ShotgunPath.from_current_os_path(
                self.legacy_bootstrap_core),
            self.sg,
        )

        # Activate the core.
        cw.ensure_project_scaffold()

        install_core_folder = os.path.join(self.legacy_bootstrap_core,
                                           "install", "core")
        os.makedirs(install_core_folder)

        cw.write_shotgun_file(Mock(get_path=lambda: "does_not_exist"))
        cw.write_install_location_file()

        sgtk.util.filesystem.copy_folder(
            self.tk_core_repo_root,
            install_core_folder,
            skip_list=[".git", "docs", "tests"],
        )
        cw.create_tank_command()

        # Setup the site config in the legacy auto_path mode that the Desktop used.
        params = {
            "auto_path":
            True,
            "config_uri":
            os.path.join(os.path.dirname(__file__), "data", "site_config"),
            "project_folder_name":
            "site",
            "project_id":
            None,
            path_param:
            self.site_config_location,
        }
        setup_project = sgtk.get_command("setup_project")
        setup_project.set_logger(logger)

        sgtk.set_authenticated_user(self.user)

        with patch(
                "tank.pipelineconfig_utils.resolve_all_os_paths_to_core",
                return_value=sgtk.util.ShotgunPath.from_current_os_path(
                    self.legacy_bootstrap_core).as_system_dict(),
        ):
            setup_project.execute(params)