public function zip($sourceDirectory, $zipFile, array $options = [])
    {
        $fs = $this->getFilesystem();
        $normalized = @realpath($sourceDirectory);
        if ($normalized === false || !$fs->isDirectory($normalized)) {
            throw new Exception(t('Unable to find the directory %s', $sourceDirectory));
        }
        $sourceDirectory = $normalized;
        $zipFile = str_replace('/', DIRECTORY_SEPARATOR, $zipFile);
        if ($fs->exists($zipFile)) {
            if ($fs->isDirectory($zipFile)) {
                throw new Exception(t('The specified path of the ZIP archive (%s) is a directory, not a file', $zipFile));
            }
            $options['append'] = isset($options['append']) ? (bool) $options['append'] : false;
            if (!$options['append']) {
                if (@$fs->delete([$zipFile]) === false) {
                    throw new Exception(t('Failed to delete file %s', $zipFile));
                }
            }
        } else {
            $options['append'] = false;
        }
        $options += [
            'includeDotFiles' => false,
            'skipCheck' => false,
            'level' => 9,
        ];
        if ($this->mayUseNativeCommand('zip')) {
            $this->zipNative($sourceDirectory, $zipFile, $options);
        } else {
            $this->zipPHP($sourceDirectory, $zipFile, $options);
        }
    }