fantasy/cli.py
def requirements(work_dir, hive_root, with_requirements,
                 with_dockerfile, active_module, active_module_file):
    """编译全新依赖文件"""
    import sys
    sys.path.insert(0, hive_root)

    hive_root = os.path.abspath(os.path.expanduser(hive_root))

    work_dir = work_dir or os.path.join(
        os.environ.get('FANTASY_APP_PATH',
                       os.getcwd()))

    work_dir = os.path.expanduser(work_dir)

    requirements_root = os.path.join(work_dir, 'requirements')
    migrate_root = os.path.join(work_dir, 'migrations')

    # active_modules 严格按照顺序
    active_module_paths = []
    active_module_list = []

    if active_module_file:
        with open(active_module_file, 'r') as fp:
            for l in fp:
                pkg = l.split('#')[0].strip()
                if pkg:
                    active_module_list.append(l.strip("\n"))
            pass

    active_module_list += active_module

    for m in active_module_list:
        try:
            mod = importlib.import_module(m)
            active_module_paths.append(os.path.dirname(mod.__file__))
        except ImportError:
            click.echo('module "%s" not found.' % m, color="yellow")
            pass
        pass

    def build_requirements():
        """构造requirements文件

        requirements文件共分为两份：

        - hive.txt  从hive项目中直接复制
        - hive-modules.txt 从指定的模块中装载依赖项

        .. note::
            requirements要求必须是顺序无关的
            因为我们会使用set来去重，并按照value排序

        """
        if not os.path.exists(requirements_root):
            os.makedirs(requirements_root)
            pass

        click.echo(click.style("Generate hive requirements...", fg="yellow"))

        shutil.copy(
            os.path.join(hive_root, 'requirements.txt'),
            os.path.join(requirements_root, 'hive.txt')
        )

        click.echo(click.style("Generate hive-module requirements...",
                               fg="yellow"))

        requirements_files = []

        for m in active_module_paths:
            t = os.path.join(m, 'requirements.txt')
            if os.path.exists(t):
                requirements_files.append(t)
            pass

        module_packages = set()
        with fileinput.input(requirements_files) as fp:
            for line in fp:
                pkg = line.split('#')[0].strip()
                if pkg:
                    module_packages.add(pkg)
            pass

        with click.open_file(
                os.path.join(requirements_root, 'hive-modules.txt'),
                'w') as fp:
            for p in module_packages:
                fp.write("%s\n" % p)
            pass
        pass

    def build_dockerfile():
        """构造Dockerfile"""

        modules_in_hive = map(
            lambda x: x.replace(hive_root, '').lstrip('/'),
            filter(lambda x: x.startswith(hive_root),
                   active_module_paths))

        modules_path = ' '.join(modules_in_hive)

        docker_file = os.path.join(
            os.path.dirname(requirements_root),
            'Dockerfile'
        )

        # update Dockerfile
        if os.path.exists(docker_file):
            click.echo(click.style("Found Dockerfile,try update...",
                                   fg="yellow"))

            with open(docker_file, 'r') as fp:
                buffer = fp.read()
                pass
            import re
            replaced = re.sub('ARG HIVE_PACKAGES=".*"',
                              'ARG HIVE_PACKAGES="%s"' % modules_path,
                              buffer)
            with open(docker_file, 'w') as fp:
                fp.write(replaced)
                pass

            pass
        pass

    def build_migrations():
        models_pairs = filter(
            lambda pair: os.path.exists(pair[0]),
            map(lambda x: (os.path.join(x[0], 'models.py'), x[1]),
                [(v, active_module_list[i]) for i, v in
                 enumerate(active_module_paths)]))

        try:
            _, models = zip(*models_pairs)
        except ValueError:
            click.echo(click.style("No models found,"
                                   "is it include in "
                                   "your PYTHONPATH?\n"
                                   "Modules: %s" %
                                   ','.join(active_module_list),
                                   fg="yellow"))
            return

        click.echo(click.style("Found models.txt,try update...",
                               fg="yellow"))

        with open(os.path.join(migrate_root, 'models.txt'), 'w') as fp:
            for p in models:
                fp.write("%s\n" % p)
            pass
        pass

    def build_tasks():
        tasks_pairs = filter(
            lambda pair: os.path.exists(pair[0]),
            map(lambda x: (os.path.join(x[0], 'tasks.py'), x[1]),
                [(v, active_module_list[i]) for i, v in
                 enumerate(active_module_paths)]))

        try:
            _, tasks = zip(*tasks_pairs)
        except ValueError:
            click.echo(click.style("No tasks found,"
                                   "is it include in "
                                   "your PYTHONPATH?\n"
                                   "Modules: %s" %
                                   ','.join(active_module_list),
                                   fg="yellow"))
            return

        click.echo(click.style("Found tasks.txt,try update...",
                               fg="yellow"))
        with open(os.path.join(migrate_root, 'tasks.txt'), 'w') as fp:
            for p in tasks:
                fp.write("%s\n" % p)
        pass

    if with_requirements:
        build_requirements()

    if with_dockerfile:
        build_dockerfile()

    if os.path.exists(migrate_root):
        build_migrations()

    if os.path.exists(migrate_root):
        build_tasks()

    click.echo(click.style("Generate done...", fg="yellow"))
    pass
def requirements(work_dir, hive_root, with_requirements,
                 with_dockerfile, active_module, active_module_file):
    """编译全新依赖文件"""
    import sys
    sys.path.insert(0, hive_root)

    hive_root = os.path.abspath(os.path.expanduser(hive_root))

    work_dir = work_dir or os.path.join(
        os.environ.get('FANTASY_APP_PATH',
                       os.getcwd()))

    work_dir = os.path.expanduser(work_dir)

    requirements_root = os.path.join(work_dir, 'requirements')
    migrate_root = os.path.join(work_dir, 'migrations')

    # active_modules 严格按照顺序
    active_module_paths = []
    active_module_list = []

    if active_module_file:
        with open(active_module_file, 'r') as fp:
            for l in fp:
                pkg = l.split('#')[0].strip()
                if pkg:
                    active_module_list.append(l.strip("\n"))
            pass

    active_module_list += active_module

    for m in active_module_list:
        try:
            mod = importlib.import_module(m)
            active_module_paths.append(os.path.dirname(mod.__file__))
        except ImportError:
            click.echo('module "%s" not found.' % m, color="yellow")
            pass
        pass

    def build_requirements():
        """构造requirements文件

        requirements文件共分为两份：

        - hive.txt  从hive项目中直接复制
        - hive-modules.txt 从指定的模块中装载依赖项

        .. note::
            requirements要求必须是顺序无关的
            因为我们会使用set来去重，并按照value排序

        """
        if not os.path.exists(requirements_root):
            os.makedirs(requirements_root)
            pass

        click.echo(click.style("Generate hive requirements...", fg="yellow"))

        shutil.copy(
            os.path.join(hive_root, 'requirements.txt'),
            os.path.join(requirements_root, 'hive.txt')
        )

        click.echo(click.style("Generate hive-module requirements...",
                               fg="yellow"))

        requirements_files = []

        for m in active_module_paths:
            t = os.path.join(m, 'requirements.txt')
            if os.path.exists(t):
                requirements_files.append(t)
            pass

        module_packages = set()
        with fileinput.input(requirements_files) as fp:
            for line in fp:
                pkg = line.split('#')[0].strip()
                if pkg:
                    module_packages.add(pkg)
            pass

        with click.open_file(
                os.path.join(requirements_root, 'hive-modules.txt'),
                'w') as fp:
            for p in module_packages:
                fp.write("%s\n" % p)
            pass
        pass

    def build_dockerfile():
        """构造Dockerfile"""

        modules_in_hive = map(
            lambda x: x.replace(hive_root, '').lstrip('/'),
            filter(lambda x: x.startswith(hive_root),
                   active_module_paths))

        modules_path = ' '.join(modules_in_hive)

        docker_file = os.path.join(
            os.path.dirname(requirements_root),
            'Dockerfile'
        )

        # update Dockerfile
        if os.path.exists(docker_file):
            click.echo(click.style("Found Dockerfile,try update...",
                                   fg="yellow"))

            with open(docker_file, 'r') as fp:
                buffer = fp.read()
                pass
            import re
            replaced = re.sub('ARG HIVE_PACKAGES=".*"',
                              'ARG HIVE_PACKAGES="%s"' % modules_path,
                              buffer)
            with open(docker_file, 'w') as fp:
                fp.write(replaced)
                pass

            pass
        pass

    def build_migrations():
        models_pairs = filter(
            lambda pair: os.path.exists(pair[0]),
            map(lambda x: (os.path.join(x[0], 'models.py'), x[1]),
                [(v, active_module_list[i]) for i, v in
                 enumerate(active_module_paths)]))

        try:
            _, models = zip(*models_pairs)
        except ValueError:
            click.echo(click.style("No models found,"
                                   "is it include in "
                                   "your PYTHONPATH?\n"
                                   "Modules: %s" %
                                   ','.join(active_module_list),
                                   fg="yellow"))
            return

        click.echo(click.style("Found models.txt,try update...",
                               fg="yellow"))

        with open(os.path.join(migrate_root, 'models.txt'), 'w') as fp:
            for p in models:
                fp.write("%s\n" % p)
            pass
        pass

    def build_tasks():
        tasks_pairs = filter(
            lambda pair: os.path.exists(pair[0]),
            map(lambda x: (os.path.join(x[0], 'tasks.py'), x[1]),
                [(v, active_module_list[i]) for i, v in
                 enumerate(active_module_paths)]))

        try:
            _, tasks = zip(*tasks_pairs)
        except ValueError:
            click.echo(click.style("No tasks found,"
                                   "is it include in "
                                   "your PYTHONPATH?\n"
                                   "Modules: %s" %
                                   ','.join(active_module_list),
                                   fg="yellow"))
            return

        click.echo(click.style("Found tasks.txt,try update...",
                               fg="yellow"))
        with open(os.path.join(migrate_root, 'tasks.txt'), 'w') as fp:
            for p in tasks:
                fp.write("%s\n" % p)
        pass

    if with_requirements:
        build_requirements()

    if with_dockerfile:
        build_dockerfile()

    if os.path.exists(migrate_root):
        build_migrations()

    if os.path.exists(migrate_root):
        build_tasks()

    click.echo(click.style("Generate done...", fg="yellow"))
    pass
编译全新依赖文件