コード例 #1
0
    def __str__(self):
        content = [
            get_override_warning_banner(),
            '',
        ]

        if len(self):
            for k, v in self:
                v = textwrap.dedent(str(v)).strip()
                v = v.replace('\n', ' \\\n' + ' ' * (len(k) + 4))
                content.append('{} {} {}'.format(
                    k, self._env_assignment_operators.get(k, '?='), v))
            content.append('')

        if len(self.phony):
            content.append('.PHONY: ' + ' '.join(sorted(self.phony)))
            content.append('')

        for target, details in self.targets:
            deps, rule, doc = details
            content.append('{}: {}  ## {}'.format(
                target, ' '.join(deps),
                doc.replace('\n', ' ') if doc else '').strip())

            script = textwrap.dedent(str(rule)).strip()

            for line in script.split('\n'):
                content.append('\t' + line)

            content.append('')

        return '\n'.join(content)
コード例 #2
0
    def __str__(self):
        content = [get_override_warning_banner(), ""] + self.header + [""]

        if len(self):
            for k, v in self:
                v = textwrap.dedent(str(v)).strip()
                v = v.replace("\n", " \\\n" + " " * (len(k) + 4))
                content.append("{} {} {}".format(k, self._env_assignment_operators.get(k, "?="), v))
            content.append("")

        if len(self.phony):
            content.append(".PHONY: " + " ".join(sorted(self.phony)))
            content.append("")

        for target, details in self.targets:
            deps, rule, doc = details

            if hasattr(rule, "render"):
                content += list(rule.render(target, deps, doc))
            else:
                content.append(
                    "{}: {}  {} {}".format(
                        target,
                        " ".join(deps),
                        "#" if target in self.hidden else "##",
                        doc.replace("\n", " ") if doc else "",
                    ).strip()
                )

                script = textwrap.dedent(str(rule)).strip()

                for line in script.split("\n"):
                    content.append("\t" + line)

            content.append("")

        return "\n".join(content)
コード例 #3
0
    def on_start(self, event):
        """
        **Events**

        - ``medikit.feature.python.on_generate`` (with the same ``ProjectEvent`` we got, todo: why not deprecate
          it in favor of higher priority medikit.on_start?)

        **Files**

        - ``<yourpackage>/__init__.py``
        - ``MANIFEST.in``
        - ``README.rst``
        - ``classifiers.txt``
        - ``requirements-dev.txt``
        - ``requirements.txt``
        - ``setup.cfg``
        - ``setup.py`` (overwritten)

        :param ProjectEvent event:
        """
        self.dispatcher.dispatch(__name__ + ".on_generate", event)

        # Our config object
        python_config = event.config["python"]

        # Some metadata that will prove useful.
        self.render_empty_files("classifiers.txt", "README.rst")
        self.render_file_inline("MANIFEST.in", "include *.txt")
        with event.config.define_resource(ConfigParserResource,
                                          "setup.cfg") as setup_cfg:
            setup_cfg.set_initial_values({
                "bdist_wheel": {
                    "universal": "1"
                },
                "metadata": {
                    "description-file": "README.rst"
                }
            })

        # XXX there is an important side effect in get_init_files that defines namespace packages for later use in
        # setup.py rendering. Even if we do not want to create the packages here, it is important to make the call
        # anyway.
        for dirname, filename, context in python_config.get_init_files():
            if python_config.create_packages:
                if not os.path.exists(dirname):
                    os.makedirs(dirname)
                self.render_file(filename, "python/package_init.py.j2",
                                 context)

        # render version file, try to import version from version.txt if available.
        try:
            with open("version.txt") as f:
                version = f.read().strip()
        except IOError:
            version = "0.0.0"
        self.render_file_inline(python_config.version_file,
                                "__version__ = '{}'".format(version))

        setup = python_config.get_setup()

        context = {
            "url": setup.pop("url", "http://example.com/"),
            "download_url": setup.pop("download_url", "http://example.com/"),
        }

        for k, v in context.items():
            context[k] = context[k].format(name=setup["name"],
                                           user=getuser(),
                                           version="{version}")

        context.update({
            "entry_points":
            setup.pop("entry_points", {}),
            "extras_require":
            python_config.get("extras_require"),
            "install_requires":
            python_config.get("install_requires"),
            "python":
            python_config,
            "setup":
            setup,
            "banner":
            get_override_warning_banner(),
        })

        # Render (with overwriting) the allmighty setup.py
        self.render_file("setup.py",
                         "python/setup.py.j2",
                         context,
                         override=True)
コード例 #4
0
ファイル: python.py プロジェクト: python-edgy/project
    def on_start(self, event):
        """
        **Events**

        - ``medikit.feature.python.on_generate`` (with the same ``ProjectEvent`` we got, todo: why not deprecate
          it in favor of higher priority medikit.on_start?)

        **Files**

        - ``<yourpackage>/__init__.py``
        - ``MANIFEST.in``
        - ``README.rst``
        - ``classifiers.txt``
        - ``requirements-dev.txt``
        - ``requirements.txt``
        - ``setup.cfg``
        - ``setup.py`` (overwritten)

        :param ProjectEvent event:
        """
        self.dispatcher.dispatch(__name__ + ".on_generate", event)

        # Our config object
        python_config = event.config["python"]

        # Some metadata that will prove useful.
        self.render_empty_files("classifiers.txt", "README.rst")
        self.render_file_inline("MANIFEST.in", "include *.txt")
        self.render_file_inline(
            "setup.cfg",
            """
                    [bdist_wheel]
                    # This flag says that the code is written to work on both Python 2 and Python
                    # 3. If at all possible, it is good practice to do this. If you cannot, you
                    # will need to generate wheels for each Python version that you support.
                    universal=1
                    
                    [metadata]
                    description-file = README.rst
                """,
        )

        # XXX there is an important side effect in get_init_files that defines namespace packages for later use in
        # setup.py rendering. Even if we do not want to create the packages here, it is important to make the call
        # anyway.
        for dirname, filename, context in python_config.get_init_files():
            if python_config.create_packages:
                if not os.path.exists(dirname):
                    os.makedirs(dirname)
                self.render_file(filename, "python/package_init.py.j2", context)

        # render version file, try to import version from version.txt if available.
        try:
            with open("version.txt") as f:
                version = f.read().strip()
        except IOError:
            version = "0.0.0"
        self.render_file_inline(python_config.version_file, "__version__ = '{}'".format(version))

        setup = python_config.get_setup()

        context = {
            "url": setup.pop("url", "http://example.com/"),
            "download_url": setup.pop("download_url", "http://example.com/"),
        }

        for k, v in context.items():
            context[k] = context[k].format(name=setup["name"], user=getuser(), version="{version}")

        context.update(
            {
                "entry_points": setup.pop("entry_points", {}),
                "extras_require": python_config.get("extras_require"),
                "install_requires": python_config.get("install_requires"),
                "python": python_config,
                "setup": setup,
                "banner": get_override_warning_banner(),
            }
        )

        # Render (with overwriting) the allmighty setup.py
        self.render_file("setup.py", "python/setup.py.j2", context, override=True)
コード例 #5
0
    def on_end(self, event):

        # Our config object
        python_config = event.config["python"]

        # Pip / PyPI
        repository = PyPIRepository([], cache_dir=CACHE_DIR)

        # We just need to construct this structure if use_uniform_requirements == True
        requirements_by_name = {}

        if python_config.use_uniform_requirements:
            tmpfile = tempfile.NamedTemporaryFile(mode="wt", delete=False)
            for extra in itertools.chain((None,), python_config.get_extras()):
                tmpfile.write("\n".join(python_config.get_requirements(extra=extra)) + "\n")
                tmpfile.flush()

            constraints = list(
                parse_requirements(
                    tmpfile.name, finder=repository.finder, session=repository.session, options=repository.options
                )
            )

            # This resolver is able to evaluate ALL the dependencies along the extras
            resolver = Resolver(
                constraints,
                repository,
                cache=DependencyCache(CACHE_DIR),
                # cache=DependencyCache(tempfile.tempdir),
                prereleases=False,
                clear_caches=False,
                allow_unsafe=False,
            )

            for req in resolver.resolve(max_rounds=10):
                requirements_by_name[parse_requirement(str(req.req)).name] = SimpleNamespace(
                    requirement=format_requirement(req).strip().replace(" ", ""),
                    url=req.link
                )

            python_config.check_duplicate_dependencies_uniform(requirements_by_name)

        # Now it iterates along the versions in extras and looks for the requirements and its dependencies, using the
        # structure created above to select the unified versions (unless the flag indicates otherwise).
        for extra in itertools.chain((None,), python_config.get_extras()):
            requirements_file = "requirements{}.txt".format("-" + extra if extra else "")

            if python_config.override_requirements or not os.path.exists(requirements_file):
                tmpfile = tempfile.NamedTemporaryFile(mode="wt", delete=False)
                tmpfile.write("\n".join(python_config.get_requirements(extra=extra)) + "\n")
                tmpfile.flush()

                constraints = list(
                    parse_requirements(
                        tmpfile.name, finder=repository.finder, session=repository.session, options=repository.options
                    )
                )
                resolver = Resolver(
                    constraints,
                    repository,
                    cache=DependencyCache(CACHE_DIR),
                    prereleases=False,
                    clear_caches=False,
                    allow_unsafe=False,
                )

                if not python_config.use_uniform_requirements:
                    python_config.check_duplicate_dependencies_nonuniform(extra, resolver)

                requirements_list = []
                for req in resolver.resolve(max_rounds=10):
                    if req.name != python_config.get("name"):
                        requirement = python_config.get_requirement_info_by_name(req, requirements_by_name)
                        if requirement:
                            requirements_list.append(requirement)

                self.render_file_inline(
                    requirements_file,
                    "\n".join(
                        (
                            "-e .{}".format("[" + extra + "]" if extra else ""),
                            *(("-r requirements.txt",) if extra else ()),
                            *python_config.get_vendors(extra=extra),
                            *sorted(requirements_list),
                        )
                    ),
                    override=python_config.override_requirements,
                )

        # Updates setup file
        setup = python_config.get_setup()

        context = {
            "url": setup.pop("url", ""),
            "download_url": setup.pop("download_url", ""),
        }

        for k, v in context.items():
            context[k] = context[k].format(name=setup["name"], user=getuser(), version="{version}")

        context.update(
            {
                "entry_points": setup.pop("entry_points", {}),
                "extras_require": python_config.get("extras_require"),
                "install_requires": python_config.get("install_requires"),
                "python": python_config,
                "setup": setup,
                "banner": get_override_warning_banner(),
            }
        )

        # Render (with overwriting) the allmighty setup.py
        self.render_file("setup.py", "python/setup.py.j2", context, override=True)
コード例 #6
0
    def on_start(self, event):
        """
        **Events**

        - ``medikit.feature.python.on_generate`` (with the same ``ProjectEvent`` we got, todo: why not deprecate
          it in favor of higher priority medikit.on_start?)

        **Files**

        - ``<yourpackage>/__init__.py``
        - ``MANIFEST.in``
        - ``README.rst``
        - ``classifiers.txt``
        - ``requirements-dev.txt``
        - ``requirements.txt``
        - ``setup.cfg``
        - ``setup.py`` (overwritten)

        :param ProjectEvent event:
        """
        self.dispatcher.dispatch(__name__ + '.on_generate', event)

        # Our config object
        python_config = event.config['python']

        # Some metadata that will prove useful.
        self.render_empty_files('classifiers.txt', 'README.rst')
        self.render_file_inline('MANIFEST.in', 'include *.txt')
        self.render_file_inline(
            'setup.cfg', '''
                    [bdist_wheel]
                    # This flag says that the code is written to work on both Python 2 and Python
                    # 3. If at all possible, it is good practice to do this. If you cannot, you
                    # will need to generate wheels for each Python version that you support.
                    universal=1
                    
                    [metadata]
                    description-file = README.rst
                '''
        )

        # XXX there is an important side effect in get_init_files that defines namespace packages for later use in
        # setup.py rendering. Even if we do not want to create the packages here, it is important to make the call
        # anyway.
        for dirname, filename, context in python_config.get_init_files():
            if python_config.create_packages:
                if not os.path.exists(dirname):
                    os.makedirs(dirname)
                self.render_file(filename, 'python/package_init.py.j2', context)

        # render version file, try to import version from version.txt if available.
        try:
            with open('version.txt') as f:
                version = f.read().strip()
        except IOError:
            version = '0.0.0'
        self.render_file_inline(python_config.version_file, "__version__ = '{}'".format(version))

        setup = python_config.get_setup()

        context = {
            'url': setup.pop('url', 'http://example.com/'),
            'download_url': setup.pop('download_url', 'http://example.com/'),
        }

        for k, v in context.items():
            context[k] = context[k].format(
                name=setup['name'],
                user=getuser(),
                version='{version}',
            )

        context.update(
            {
                'entry_points': setup.pop('entry_points', {}),
                'extras_require': python_config.get('extras_require'),
                'install_requires': python_config.get('install_requires'),
                'python': python_config,
                'setup': setup,
                'banner': get_override_warning_banner(),
            }
        )

        # Render (with overwriting) the allmighty setup.py
        self.render_file('setup.py', 'python/setup.py.j2', context, override=True)