Esempio n. 1
0
 def run(self):
     with CliReporter(self.env, verbosity=self.verbosity):
         self.build(update_source_info_first=True)
         for ts, eventtype, absolute_filename_w_path in self.watcher:
             DatabaseCache.purge_cache()
             if self.last_build is None or ts > self.last_build:
                 self.build()
Esempio n. 2
0
def build_cmd(ctx, output_path, watch, prune, verbosity, source_info_only,
              buildstate_path, profile, build_flags):
    """Builds the entire project into the final artifacts.

    The default behavior is to build the project into the default build
    output path which can be discovered with the `project-info` command
    but an alternative output folder can be provided with the `--output-path`
    option.

    The default behavior is to perform a build followed by a pruning step
    which removes no longer referenced artifacts from the output folder.
    Lektor will only build the files that require rebuilding if the output
    folder is reused.

    To enforce a clean build you have to issue a `clean` command first.

    If the build fails the exit code will be `1` otherwise `0`.  This can be
    used by external scripts to only deploy on successful build for instance.
    """
    from lektor.builder import Builder
    from lektor.reporter import CliReporter

    if output_path is None:
        output_path = ctx.get_default_output_path()

    ctx.load_plugins()

    env = ctx.get_env()

    def _build():
        builder = Builder(env.new_pad(),
                          output_path,
                          buildstate_path=buildstate_path,
                          build_flags=build_flags)
        if source_info_only:
            builder.update_all_source_infos()
            return True

        if profile:
            from .utils import profile_func
            failures = profile_func(builder.build_all)
        else:
            failures = builder.build_all()
        if prune:
            builder.prune()
        return failures == 0

    reporter = CliReporter(env, verbosity=verbosity)
    with reporter:
        success = _build()
        if not watch:
            return sys.exit(0 if success else 1)

        from lektor.watcher import watch
        click.secho('Watching for file system changes', fg='cyan')
        last_build = time.time()
        for ts, _, _ in watch(env):
            if ts > last_build:
                _build()
                last_build = time.time()
Esempio n. 3
0
File: cli.py Progetto: jab/lektor
def build_cmd(ctx, output_path, watch, prune, verbosity):
    """Builds the entire site out."""
    from lektor.builder import Builder
    from lektor.reporter import CliReporter

    if output_path is None:
        output_path = ctx.get_default_output_path()

    env = ctx.get_env()

    def _build():
        builder = Builder(ctx.new_pad(), output_path)
        builder.build_all()
        if prune:
            builder.prune()

    reporter = CliReporter(env, verbosity=verbosity)
    with reporter:
        _build()
        if not watch:
            return

        from lektor.watcher import watch
        click.secho('Watching for file system changes', fg='cyan')
        last_build = time.time()
        for ts, _, _ in watch(env):
            if ts > last_build:
                _build()
                last_build = time.time()
    def __init__(self, *args, **kwargs):
        Plugin.__init__(self, *args, **kwargs)
        src_dir = self.env.root_path + '/' + (self.get_config().get('src_dir')
                                              or 'assets') + '/'
        target_dir = self.env.root_path + '/' + (
            self.get_config().get('target_dir') or 'templates') + '/'

        self.observer = Observer()
        self.handler = HtmlHandler(target=target_dir)
        self.observer.schedule(self.handler, src_dir, recursive=True)

        cli_reporter = CliReporter(self.env)
        cli_reporter.report_generic(
            f'Starting webpack-html helper: {src_dir} -> {target_dir}')

        self.observer.start()
Esempio n. 5
0
 def run(self):
     with CliReporter(self.env, verbosity=self.verbosity):
         self.build(update_source_info_first=True)
         with Watcher(self.env, self.output_path) as watcher:
             for ts, _, _ in watcher:
                 if self.last_build is None or ts > self.last_build:
                     self.build()
Esempio n. 6
0
    def clean(self):
        from lektor.builder import Builder
        from lektor.reporter import CliReporter

        # self._ctx.load_plugins()
        env = self._ctx.get_env()

        reporter = CliReporter(env)  # (env, verbosity=self._verbosity)
        with reporter:
            builder = Builder(env.new_pad(), self._dst)
            builder.prune(all=True)
Esempio n. 7
0
def remove(ctx, relpath):
    lektor_cli_ctx = Context()
    lektor_cli_ctx.load_plugins()

    env = lektor_cli_ctx.get_env()
    path = os.path.join(OUTPUT_DIR, relpath)
    with CliReporter(env, verbosity=0), reporter.build('prune', None):
        if os.path.exists(path):
            reporter.report_pruned_artifact(relpath)
            if os.path.isdir(path):
                shutil.rmtree(path)
            else:
                os.remove(path)
def build(ctx):
    lektor_cli_ctx = Context()
    lektor_cli_ctx.load_plugins()

    env = lektor_cli_ctx.get_env()
    pad = env.new_pad()

    # This is essentially `lektor build --output-path build`.
    with CliReporter(env, verbosity=0):
        builder = Builder(pad, OUTPUT_DIR)
        failures = builder.build_all()

    if failures:
        raise invoke.Exit('Builder failed.')
Esempio n. 9
0
File: cli.py Progetto: jab/lektor
def clean_cmd(ctx, output_path, verbosity):
    """Cleans the entire build folder."""
    from lektor.builder import Builder
    from lektor.reporter import CliReporter

    if output_path is None:
        output_path = ctx.get_default_output_path()

    env = ctx.get_env()

    reporter = CliReporter(env, verbosity=verbosity)
    with reporter:
        builder = Builder(ctx.new_pad(), output_path)
        builder.prune(all=True)
Esempio n. 10
0
    def resolve_artifact(self, url_path, pad=None, redirect_slash=True):
        """Resolves an artifact and also triggers a build if necessary.
        Returns a tuple in the form ``(artifact_name, filename)`` where
        `artifact_name` can be `None` in case a file was targeted explicitly.
        """
        if pad is None:
            pad = self.get_pad()

        artifact_name = filename = record_path = alt = None

        # We start with trying to resolve a source and then use the
        # primary
        source = pad.resolve_url_path(url_path)
        if source is not None:
            # If the request path does not end with a slash but we
            # requested a URL that actually wants a trailing slash, we
            # append it.  This is consistent with what apache and nginx do
            # and it ensures our relative urls work.
            if (
                not url_path.endswith("/")
                and source.url_path != "/"
                and source.url_path != url_path
            ):
                return abort(append_slash_redirect(request.environ))

            with CliReporter(self.env, verbosity=self.verbosity):
                builder = self.get_builder(pad)
                prog, _ = builder.build(source)

            artifact = prog.primary_artifact
            if artifact is not None:
                artifact_name = artifact.artifact_name
                filename = artifact.dst_filename
            alt = source.alt
            if isinstance(source, Record):
                record_path = source.record.path

        if filename is None:
            path_list = url_path.strip("/").split("/")
            if sys.platform == "win32":
                filename = os.path.join(self.output_path, *path_list)
            else:
                filename = safe_join(self.output_path, *path_list)

        return ResolveResult(artifact_name, filename, record_path, alt)
Esempio n. 11
0
def clean_cmd(ctx, output_path, verbosity):
    """Cleans the entire build folder.

    If not build folder is provided, the default build folder of the project
    in the Lektor cache is used.
    """
    from lektor.builder import Builder
    from lektor.reporter import CliReporter

    if output_path is None:
        output_path = ctx.get_default_output_path()

    env = ctx.get_env()

    reporter = CliReporter(env, verbosity=verbosity)
    with reporter:
        builder = Builder(env.new_pad(), output_path)
        builder.prune(all=True)
Esempio n. 12
0
def build(ctx, bust=False):
    lektor_cli_ctx = Context()

    if bust:
        project = lektor_cli_ctx.get_project()
        shutil.rmtree(project.get_package_cache_path(), ignore_errors=True)
        shutil.rmtree(project.get_output_path(), ignore_errors=True)

    lektor_cli_ctx.load_plugins()
    env = lektor_cli_ctx.get_env()
    pad = env.new_pad()

    # This is essentially `lektor build --output-path build`.
    with CliReporter(env, verbosity=0):
        builder = Builder(pad, OUTPUT_DIR)
        failures = builder.build_all()

    if failures:
        raise invoke.Exit('Builder failed.')

    # Generate redirect file.
    redirect_filename = os.path.join(OUTPUT_DIR, '_redirects')
    with io.open(redirect_filename, mode='w', encoding='utf8') as f:
        static_redirect = get_static_redirect()
        f.write(static_redirect)
        if not static_redirect.endswith('\n'):
            f.write('\n')

        f.write('\n')
        f.write('# Blog posts.\n')
        f.write('\n'.join(generate_blog_post_redirects(pad)))
        f.write('\n')

        f.write('\n')
        f.write('# Download redirects.\n')
        f.write('\n'.join(generate_download_redirects(pad)))
        f.write('\n')

        latest_redirect = get_latest_download_redirect(pad)
        if latest_redirect is not None:
            f.write('\n')
            f.write('# Latests version download links.\n')
            f.write(latest_redirect)
            f.write('\n')
Esempio n. 13
0
def demo_output(site_path, my_plugin_id, my_plugin_cls, tmp_path_factory):
    """ Build the demo site.

    Return path to output directory.

    """
    project = Project.from_path(str(site_path))
    env = Environment(project, load_plugins=False)

    # Load our plugin
    env.plugin_controller.instanciate_plugin(my_plugin_id, my_plugin_cls)
    env.plugin_controller.emit('setup-env')

    pad = Database(env).new_pad()
    output_path = tmp_path_factory.mktemp('demo-site')
    builder = Builder(pad, str(output_path))
    with CliReporter(env):
        failures = builder.build_all()
        assert failures == 0
    return output_path
Esempio n. 14
0
    def build(self, tiny=False):
        from lektor.builder import Builder
        from lektor.reporter import CliReporter

        self._ctx.load_plugins()

        env = self._ctx.get_env()

        def _build():
            builder = Builder(env.new_pad(), str(self._dst),
                              buildstate_path=self._buildstate,
                              extra_flags=self._buildflags if not tiny else [])
            failures = builder.build_all()
            builder.prune()
            return failures == 0

        reporter = CliReporter(env, verbosity=True)
        with reporter:
            success = _build()

        return success
def demo_output(tmp_path_factory):
    """ Build the demo site.

    Return path to output director.

    """
    site_dir = os.path.join(os.path.dirname(__file__), 'test-site')

    project = Project.from_path(site_dir)

    env = project.make_env(load_plugins=False)
    # Load our plugin
    env.plugin_controller.instanciate_plugin('polymorphic-type',
                                             PolymorphicTypePlugin)
    env.plugin_controller.emit('setup-env')

    output_path = tmp_path_factory.mktemp('output')
    builder = Builder(env.new_pad(), str(output_path))
    with CliReporter(env):
        failures = builder.build_all()
        assert failures == 0

    return output_path
Esempio n. 16
0
    def resolve_artifact(self, path, pad=None, redirect_slash=True):
        """Resolves an artifact and also triggers a build if necessary.
        Returns a tuple in the form ``(artifact_name, filename)`` where
        `artifact_name` can be `None` in case a file was targeted explicitly.
        """
        if pad is None:
            pad = self.get_pad()

        artifact_name = filename = None

        # We start with trying to resolve a source and then use the
        # primary
        source = pad.resolve_url_path(path)
        if source is not None:
            # If the request path does not end with a slash but we
            # requested a URL that actually wants a trailing slash, we
            # append it.  This is consistent with what apache and nginx do
            # and it ensures our relative urls work.
            if not path.endswith('/') and \
               source.url_path != '/' and \
               source.url_path != path:
                return abort(append_slash_redirect(request.environ))

            with CliReporter(self.env, verbosity=self.verbosity):
                builder = self.get_builder(pad)
                prog, _ = builder.build(source)

            artifact = prog.primary_artifact
            if artifact is not None:
                artifact_name = artifact.artifact_name
                filename = artifact.dst_filename

        if filename is None:
            filename = safe_join(self.output_path, path.strip('/'))

        return artifact_name, filename
Esempio n. 17
0
    def handle_request(self, request):
        pad = self.get_pad()
        filename = None

        # We start with trying to resolve a source and then use the
        # primary
        source = pad.resolve_url_path(request.path)
        if source is not None:
            with CliReporter(self.env, verbosity=self.verbosity):
                builder = self.get_builder(pad)
                prog = builder.build(source)

            artifact = prog.primary_artifact
            if artifact is not None:
                filename = artifact.dst_filename

        # If there is no primary artifact or the url does not point to a
        # known artifact at all, then we just look directly into the
        # output directory and serve from there.  This will for instance
        # pick up thumbnails.
        if filename is None:
            filename = os.path.join(self.output_path, request.path.strip('/'))

        return send_file(request, filename)
Esempio n. 18
0
 def run(self):
     with CliReporter(self.env, verbosity=self.verbosity):
         self.build(update_source_info_first=True)
         for ts, _, _ in self.watcher:
             if self.last_build is None or ts > self.last_build:
                 self.build()
Esempio n. 19
0
 def run(self):
     with CliReporter(self.env, verbosity=self.verbosity):
         self.build()
         for ts, _, _ in self.watcher:
             if self.last_build is None or ts > self.last_build:
                 self.build()