diff --git a/builder/Makefile.am.inc b/builder/Makefile.am.inc index 85aae5522..72e40bed7 100644 --- a/builder/Makefile.am.inc +++ b/builder/Makefile.am.inc @@ -20,6 +20,8 @@ xdg_app_builder_SOURCES = \ builder/builder-source-bzr.h \ builder/builder-source-file.c \ builder/builder-source-file.h \ + builder/builder-source-script.c \ + builder/builder-source-script.h \ builder/builder-source-patch.c \ builder/builder-source-patch.h \ builder/builder-context.c \ diff --git a/builder/builder-source-script.c b/builder/builder-source-script.c new file mode 100644 index 000000000..e2de46f01 --- /dev/null +++ b/builder/builder-source-script.c @@ -0,0 +1,218 @@ +/* builder-source-script.c + * + * Copyright (C) 2015 Red Hat, Inc + * + * This script is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This script is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Authors: + * Alexander Larsson + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "builder-utils.h" +#include "builder-source-script.h" + +struct BuilderSourceScript { + BuilderSource parent; + + char **commands; + char *dest_filename; +}; + +typedef struct { + BuilderSourceClass parent_class; +} BuilderSourceScriptClass; + +G_DEFINE_TYPE (BuilderSourceScript, builder_source_script, BUILDER_TYPE_SOURCE); + +enum { + PROP_0, + PROP_COMMANDS, + PROP_DEST_FILENAME, + LAST_PROP +}; + +static void +builder_source_script_finalize (GObject *object) +{ + BuilderSourceScript *self = (BuilderSourceScript *)object; + + g_strfreev (self->commands); + g_free (self->dest_filename); + + G_OBJECT_CLASS (builder_source_script_parent_class)->finalize (object); +} + +static void +builder_source_script_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + BuilderSourceScript *self = BUILDER_SOURCE_SCRIPT (object); + + switch (prop_id) + { + case PROP_COMMANDS: + g_value_set_boxed (value, self->commands); + break; + + case PROP_DEST_FILENAME: + g_value_set_string (value, self->dest_filename); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +builder_source_script_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + BuilderSourceScript *self = BUILDER_SOURCE_SCRIPT (object); + gchar **tmp; + + switch (prop_id) + { + case PROP_COMMANDS: + tmp = self->commands; + self->commands = g_strdupv (g_value_get_boxed (value)); + g_strfreev (tmp); + break; + + case PROP_DEST_FILENAME: + g_free (self->dest_filename); + self->dest_filename = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static gboolean +builder_source_script_download (BuilderSource *source, + BuilderContext *context, + GError **error) +{ + return TRUE; +} + +static gboolean +builder_source_script_extract (BuilderSource *source, + GFile *dest, + BuilderContext *context, + GError **error) +{ + BuilderSourceScript *self = BUILDER_SOURCE_SCRIPT (source); + g_autoptr(GFile) dest_script = NULL; + const char *dest_filename; + g_autoptr(GString) script = NULL; + int i; + guint32 perms; + + script = g_string_new ("#!/bin/sh\n"); + + if (self->commands) + { + for (i = 0; self->commands[i] != NULL; i++) + { + g_string_append (script, self->commands[i]); + g_string_append_c (script, '\n'); + } + } + + if (self->dest_filename) + dest_filename = self->dest_filename; + else + dest_filename = "autogen.sh"; + + dest_script = g_file_get_child (dest, dest_filename); + + if (!g_file_replace_contents (dest_script, + script->str, + script->len, + NULL, + FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + NULL, NULL,error)) + return FALSE; + + perms = 0755; + if (!g_file_set_attribute (dest_script, + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_ATTRIBUTE_TYPE_UINT32, + &perms, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, error)) + return FALSE; + + return TRUE; +} + +static void +builder_source_script_checksum (BuilderSource *source, + BuilderCache *cache, + BuilderContext *context) +{ + BuilderSourceScript *self = BUILDER_SOURCE_SCRIPT (source); + + builder_cache_checksum_strv (cache, self->commands); + builder_cache_checksum_str (cache, self->dest_filename); +} + +static void +builder_source_script_class_init (BuilderSourceScriptClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + BuilderSourceClass *source_class = BUILDER_SOURCE_CLASS (klass); + + object_class->finalize = builder_source_script_finalize; + object_class->get_property = builder_source_script_get_property; + object_class->set_property = builder_source_script_set_property; + + source_class->download = builder_source_script_download; + source_class->extract = builder_source_script_extract; + source_class->checksum = builder_source_script_checksum; + + g_object_class_install_property (object_class, + PROP_COMMANDS, + g_param_spec_boxed ("commands", + "", + "", + G_TYPE_STRV, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DEST_FILENAME, + g_param_spec_string ("dest-filename", + "", + "", + NULL, + G_PARAM_READWRITE)); +} + +static void +builder_source_script_init (BuilderSourceScript *self) +{ +} diff --git a/builder/builder-source-script.h b/builder/builder-source-script.h new file mode 100644 index 000000000..90df62b7c --- /dev/null +++ b/builder/builder-source-script.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2015 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Alexander Larsson + */ + +#ifndef __BUILDER_SOURCE_SCRIPT_H__ +#define __BUILDER_SOURCE_SCRIPT_H__ + +#include "builder-source.h" + +G_BEGIN_DECLS + +typedef struct BuilderSourceScript BuilderSourceScript; + +#define BUILDER_TYPE_SOURCE_SCRIPT (builder_source_script_get_type()) +#define BUILDER_SOURCE_SCRIPT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUILDER_TYPE_SOURCE_SCRIPT, BuilderSourceScript)) +#define BUILDER_IS_SOURCE_SCRIPT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUILDER_TYPE_SOURCE_SCRIPT)) + +GType builder_source_script_get_type (void); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(BuilderSourceScript, g_object_unref) + +G_END_DECLS + +#endif /* __BUILDER_SOURCE_SCRIPT_H__ */ diff --git a/builder/builder-source.c b/builder/builder-source.c index 5255c7d85..3a564423b 100644 --- a/builder/builder-source.c +++ b/builder/builder-source.c @@ -34,6 +34,7 @@ #include "builder-source-git.h" #include "builder-source-bzr.h" #include "builder-source-file.h" +#include "builder-source-script.h" static void serializable_iface_init (JsonSerializableIface *serializable_iface); @@ -160,6 +161,8 @@ builder_source_from_json (JsonNode *node) return (BuilderSource *)json_gobject_deserialize (BUILDER_TYPE_SOURCE_ARCHIVE, node); if (strcmp (type, "file") == 0) return (BuilderSource *)json_gobject_deserialize (BUILDER_TYPE_SOURCE_FILE, node); + if (strcmp (type, "script") == 0) + return (BuilderSource *)json_gobject_deserialize (BUILDER_TYPE_SOURCE_SCRIPT, node); if (strcmp (type, "patch") == 0) return (BuilderSource *)json_gobject_deserialize (BUILDER_TYPE_SOURCE_PATCH, node); if (strcmp (type, "git") == 0) diff --git a/doc/xdg-app-builder.xml b/doc/xdg-app-builder.xml index 3f8fb722b..12b267d7e 100644 --- a/doc/xdg-app-builder.xml +++ b/doc/xdg-app-builder.xml @@ -347,6 +347,30 @@ + + Script sources + + This is a way to create a shell (/bin/sh) script from an inline set of commands. + + + + + "script" + + + + An array of shell commands that will be put in a shellscript file + + + + Filename to use inside the source dir, default to the basename of path. + + + + Directory inside the source dir where the file will be copied. + + + Patch sources