示例#1
0
def install_dependencies(modules):

    for module_name, module_help in modules:
        try:
            import_module(module_name)
        except ImportError:
            if pip_installed:
                decision = ask_user(
                    'It looks like you don\'t have `{name}` package. Install it now?'
                    .format(name=module_name),
                    variants=['y', 'n'],
                )
                if decision == 'y':
                    try:
                        rc = pip.main(['install', module_name])
                        if rc:
                            # Some error occured
                            raise ConfigError('PIP error: {}'.format(rc))
                    except BaseException as e:
                        tell_user(
                            'You should install `{name}` manually. Installation instructions are available at {help}.'
                            .format(name=module_name, help=module_help))
                        raise
                else:
                    tell_user(
                        'You should install `{name}` manually. Installation instructions are available at {help}.'
                        .format(name=module_name, help=module_help))
                    raise ConfigError('Unable to proceed...')
            else:
                tell_user(
                    'It looks like you don\'t have `{name}` package. You should install it manually. Installation instructions are available at {help}.'
                    .format(name=module_name, help=module_help))
                raise ConfigError('Unable to proceed...')
示例#2
0
    def check_recent_modifications(self):

        # Если есть файлы в статусе RECENTLY_MODIFIED, предупреждаем пользователя.
        recently_modified_files = self._select_files(FILE_RECENTLY_MODIFIED)

        if recently_modified_files:
            tell_user(
                '\nSome files on the server were modified by another user(s) not long ago:'
            )

            for file in recently_modified_files:
                tell_user('  {file} by {user} at {time}'.format(
                    file=file.get_path(PATH_ABSOLUTE),
                    user=file._changed['who'],
                    time=file._changed['when']))

            answer = ask_user(
                'Do you still want to continue?',
                variants=['n', 'y'],
            )
            if answer == 'n':
                raise BuildError('Operation cancelled')
示例#3
0
    config['roots']['include'] = {}
    config['roots']['include']['path'] = 'include/conduit'
    config['roots']['include']['ignore'] = [
        'Credentials.inc.php',
        'Settings.inc.php',
        'KhinkoReminder.php',
    ]

    # Определяем, где находится проект. По идее он должен быть в родительском каталоге текущего.
    parent_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
    if not find_missing_roots(parent_dir, config['roots']):
        project_dir = parent_dir
    else:
        while True:
            project_dir = ask_user(
                'Where is your project located (enter empty string for abort)?',
                case_sensitive=True,
            )

            if project_dir == '':
                raise ConfigError('Abort requested')

            project_dir = os.path.abspath(project_dir)
            missing_dirs = find_missing_roots(project_dir, config['roots'])

            if not missing_dirs:
                break

            for dir in missing_dirs:
                tell_user('Directory {} not found'.format(dir))

    config['local'] = {}
示例#4
0
    def synchronize_all(self):

        # Директории
        dirs_to_create = self._select_dirs(FILE_NEW)
        dirs_to_delete = self._select_dirs(FILE_REMOTE_ONLY)

        # Файлы
        files_to_update = self._select_files(FILE_MODIFIED,
                                             FILE_RECENTLY_MODIFIED, FILE_NEW)
        files_to_delete = self._select_files(FILE_REMOTE_ONLY)

        if not any((files_to_update, files_to_delete, dirs_to_create,
                    dirs_to_delete)):
            raise BuildError('Everything is up to date. No actions required.')

        # Покажем пользователю, какие изменения мы планируем произвести на сервере.
        if dirs_to_create:
            tell_user('\nFollowing directories will be created on the server:')
            for dir in dirs_to_create:
                tell_user('  ' + dir.get_path(PATH_ABSOLUTE | PATH_REMOTE))

        if dirs_to_delete:
            tell_user(
                '\nFollowing directories will be deleted from the server:')
            for dir in dirs_to_delete:
                tell_user('  ' + dir.get_path(PATH_ABSOLUTE | PATH_REMOTE))

        if files_to_update:
            tell_user('\nFollowing files will be uploaded to the server:')
            for file in files_to_update:
                tell_user('  ' + file.get_path(PATH_ABSOLUTE))

        if files_to_delete:
            tell_user('\nFollowing files will be deleted from the server:')
            for file in files_to_delete:
                tell_user('  ' + file.get_path(PATH_ABSOLUTE | PATH_REMOTE))

        answer = ask_user(
            'Do you wish to start?',
            variants=['y', 'n'],
        )
        if answer == 'n':
            raise BuildError('Operation cancelled')

        # Apply changes
        self.connect_to_ftp()

        try:
            for dir in dirs_to_create:
                dir.upload_to_server(self._ftp)
                tell_user('{} created'.format(dir))

            for file in files_to_update:
                # minify and upload file
                file.upload_to_server(self._ftp, self._remote_file_list)
                tell_user('{} updated'.format(file))

            for file in files_to_delete:
                file.delete_from_server(self._ftp, self._remote_file_list)
                tell_user('{} deleted'.format(file))

            for dir in dirs_to_delete:
                dir.delete_from_server(self._ftp)
                tell_user('{} deleted'.format(file))

        finally:
            self.write_remote_file_list()

            self.unlock_mutex()

            self.disconnect_from_ftp()

        tell_user('Mission accomplished')
示例#5
0
    def process_minified_files(self):
        # Если на локальной машине обнаружены минифицированные файлы, предлагаем их удалить на фиг.
        minified_files = self._select_files(FILE_MINIFIED)
        if minified_files:
            tell_user('There are minified files in the local repository:')
            for file in minified_files:
                tell_user('  ' + file.get_path(PATH_ABSOLUTE))

            tell_user(
                'Generally files are minified on the fly and stored only server-side.'
            )
            answer = ask_user(
                'What do you want to do with listed files?',
                variants=['d', 'i', 'g', '?'],
                descriptions=[
                    'delete', 'ignore', 'add to ignore-list',
                    'decide individually'
                ],
            )

            if answer == '?':
                # Ask again for every file
                decisions = []
                tell_user(
                    '\nWARNING. Changes are not applied interactively. So you can cancel everything by selecting `abort`.'
                )
                for file in minified_files:
                    answer = ask_user(
                        'What do you want to do with {file}?'.format(
                            file=file.get_path(PATH_ABSOLUTE)),
                        variants=['d', 'i', 'g', 'a'],
                        descriptions=[
                            'delete', 'ignore', 'add to ignore-list', 'abort'
                        ],
                    )
                    if answer == 'a':
                        raise BuildError('Operation cancelled')
                    else:
                        decisions.append(answer)
            else:
                decisions = [answer for file in minified_files]

            update_config = False

            for file, decision in zip(minified_files, decisions):
                if decision == 'd':
                    # Delete file
                    file_name = file.get_path(PATH_ABSOLUTE)
                    os.unlink(file_name)
                    tell_user('File deleted: {}'.format(file_name))

                elif decision == 'g':
                    # Add file to ignore-list
                    try:
                        local_config['roots'][file.get_path(
                            PATH_ROOT_NAME)]['ignore'].append(
                                file.get_path(PATH_POSIX))
                    except KeyError:
                        local_config['roots'][file.get_path(
                            PATH_ROOT_NAME)]['ignore'] = [
                                file.get_path(PATH_POSIX)
                            ]

                    update_config = True
                    tell_user('File added to ignore-list: {}'.format(
                        file.get_path(PATH_ABSOLUTE)))

            if update_config:
                local_config.write()
示例#6
0
        return self

    def __exit__(self, type, value, traceback):
        try:
            self.disconnect_from_ftp()
        except:
            pass


#-------------------------------------------------------------------------------

# Определяем сервер
try:
    server = sys.argv[1]
except IndexError:
    server = ask_user('Enter FTP alias')

# TODO: Добавить режим force --- игнорируем оглавление

with Builder(server) as builder:
    try:
        builder.analyze_local_repository()
        builder.analyze_remote_repository()
        builder.synchronize_all()
    except MutexError as e:
        user, time = str(e).split('\t')
        tell_user(
            'User {user} works on the site right now ({time}). Unable to proceed...'
            .format(
                user=user,
                time=time,