A working skeleton processor built into EDI, no scripts needed

This commit is contained in:
Andy Williams 2015-02-02 22:07:02 +00:00
parent 02bb3db148
commit 4edcc6ba16
16 changed files with 259 additions and 64 deletions

View File

@ -9,5 +9,4 @@ install-data-hook:
uninstall-local: uninstall-local:
rm -rf $(skeletondir)/skeleton rm -rf $(skeletondir)/skeleton
EXTRA_DIST = $(skeleton_DATA) EXTRA_DIST = $(skeleton_DATA)

View File

@ -1,2 +1 @@
${EDI_USER} <${EDI_EMAIL}> ${Edi_User} <${Edi_Email}>

View File

@ -5,7 +5,7 @@ Type=Application
Name=@PACKAGE_NAME@ Name=@PACKAGE_NAME@
Name[fr]=@PACKAGE_NAME@ Name[fr]=@PACKAGE_NAME@
GenericName=Efl Application Skeletion GenericName=Efl Application Skeletion
Comment=Efl Application ${EDI_NAME} Comment=Efl Application ${Edi_Name}
Icon=@PACKAGE_NAME@ Icon=@PACKAGE_NAME@
TryExec=@PACKAGE_NAME@ TryExec=@PACKAGE_NAME@
Exec=@PACKAGE_NAME@ Exec=@PACKAGE_NAME@

View File

@ -9,7 +9,7 @@ ${edi_name} \- a demo application
.SH DESCRIPTION .SH DESCRIPTION
${EDI_NAME} is a demo application to show how to integrate EFL and autotools into a ${Edi_Name} is a demo application to show how to integrate EFL and autotools into a
cross platform build. You should be able to generate an executable easily for all cross platform build. You should be able to generate an executable easily for all
target supported by EFL with this ${edi_name}. target supported by EFL with this ${edi_name}.
@ -47,4 +47,4 @@ http://enlightenment.org
.SH AUTHORS .SH AUTHORS
${EDI_USER} <${EDI_EMAIL}> and various contributors. ${Edi_User} <${Edi_Email}> and various contributors.

View File

@ -4,7 +4,7 @@ pkgver=1.8.99.8967.a1cfce6
pkgrel=1 pkgrel=1
pkgdesc="Enlightenment toolkit ${edi_name} - GIT development snapshot" pkgdesc="Enlightenment toolkit ${edi_name} - GIT development snapshot"
arch=('i686' 'x86_64' 'arm') arch=('i686' 'x86_64' 'arm')
url="http://${EDI_WWW}" url="http://${Edi_Url}"
license=('WTFPL') license=('WTFPL')
makedepends=('doxygen' 'imagemagick' 'git') makedepends=('doxygen' 'imagemagick' 'git')
depends=('elementary-git') depends=('elementary-git')
@ -49,7 +49,7 @@ package_${edi_name}-git() {
} }
package_${edi_name}_doc-git() { package_${edi_name}_doc-git() {
pkgdesc="Documentation for ${EDI_NAME}" pkgdesc="Documentation for ${Edi_Name}"
arch=('any') arch=('any')
unset depends optdepends unset depends optdepends

View File

@ -8,12 +8,12 @@
|-----handy-ruler------------------------------------------------------| |-----handy-ruler------------------------------------------------------|
${edi_name}: ${edi_name} ${edi_name}: ${edi_name}
${edi_name}: ${edi_name}:
${edi_name}: ${EDI_NAME} is an example of application written using the Enlightenment ${edi_name}: ${Edi_Name} is an example of application written using the Enlightenment
${edi_name}: Foundation Libraries. ${edi_name}: Foundation Libraries.
${edi_name}: ${edi_name}:
${edi_name}: It requires elementary. ${edi_name}: It requires elementary.
${edi_name}: ${edi_name}:
${edi_name}: ${edi_name} was written by ${EDI_USER} <${EDI_EMAIL}> ${edi_name}: ${edi_name} was written by ${Edi_User} <${Edi_Email}>
${edi_name}: website: <http://${EDI_WWW}/> ${edi_name}: website: <http://${Edi_Url}/>
${edi_name}: ${edi_name}:
${edi_name}: ${edi_name}:

View File

@ -11,11 +11,11 @@
#include "gettext.h" #include "gettext.h"
#include "${EDI_NAME}.h" #include "${Edi_Name}.h"
#include "${edi_name}_private.h" #include "${edi_name}_private.h"
#define COPYRIGHT "Copyright © ${EDI_YEAR} ${EDI_USER} <${EDI_EMAIL}> and various contributors (see AUTHORS)." #define COPYRIGHT "Copyright © ${Edi_Year} ${Edi_User} <${Edi_Email}> and various contributors (see AUTHORS)."
static void static void
_${edi_name}_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) _${edi_name}_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
@ -29,7 +29,7 @@ ${edi_name}_win_setup(void)
Evas_Object *win; Evas_Object *win;
Evas_Object *label; Evas_Object *label;
win = elm_win_util_standard_add("main", "${EDI_NAME}"); win = elm_win_util_standard_add("main", "${Edi_Name}");
if (!win) return NULL; if (!win) return NULL;
elm_win_focus_highlight_enabled_set(win, EINA_TRUE); elm_win_focus_highlight_enabled_set(win, EINA_TRUE);

View File

@ -35,7 +35,7 @@ extern "C" {
/** /**
* @file * @file
* @brief These routines are used for ${EDI_NAME} library interaction. * @brief These routines are used for ${Edi_Name} library interaction.
*/ */
/** /**
@ -47,20 +47,20 @@ extern "C" {
* Functions of obligatory usage, handling proper initialization * Functions of obligatory usage, handling proper initialization
* and shutdown routines. * and shutdown routines.
* *
* Before the usage of any other function, ${EDI_NAME} should be properly * Before the usage of any other function, ${Edi_Name} should be properly
* initialized with @ref ${edi_name}_init() and the last call to ${EDI_NAME}'s * initialized with @ref ${edi_name}_init() and the last call to ${Edi_Name}'s
* functions should be @ref ${edi_name}_shutdown(), so everything will * functions should be @ref ${edi_name}_shutdown(), so everything will
* be correctly freed. * be correctly freed.
* *
* ${EDI_NAME} logs everything with Eina Log, using the "${edi_name}" log domain. * ${Edi_Name} logs everything with Eina Log, using the "${edi_name}" log domain.
* *
*/ */
/** /**
* Initialize ${EDI_NAME}. * Initialize ${Edi_Name}.
* *
* Initializes ${EDI_NAME}, its dependencies and modules. Should be the first * Initializes ${Edi_Name}, its dependencies and modules. Should be the first
* function of ${EDI_NAME} to be called. * function of ${Edi_Name} to be called.
* *
* @return The init counter value. * @return The init counter value.
* *
@ -71,12 +71,12 @@ extern "C" {
EAPI int ${edi_name}_init(void); EAPI int ${edi_name}_init(void);
/** /**
* Shutdown ${EDI_NAME} * Shutdown ${Edi_Name}
* *
* Shutdown ${EDI_NAME}. If init count reaches 0, all the internal structures will * Shutdown ${Edi_Name}. If init count reaches 0, all the internal structures will
* be freed. Any ${EDI_NAME} library call after this point will leads to an error. * be freed. Any ${Edi_Name} library call after this point will leads to an error.
* *
* @return ${EDI_NAME}'s init counter value. * @return ${Edi_Name}'s init counter value.
* *
* @see ${edi_name}_init(). * @see ${edi_name}_init().
* *

View File

@ -2,7 +2,7 @@
# include "config.h" # include "config.h"
#endif #endif
#include "${EDI_NAME}.h" #include "${Edi_Name}.h"
#include "${edi_name}_private.h" #include "${edi_name}_private.h"
@ -20,7 +20,7 @@ ${edi_name}_init(void)
_${edi_name}_lib_log_dom = eina_log_domain_register("${edi_name}", EINA_COLOR_CYAN); _${edi_name}_lib_log_dom = eina_log_domain_register("${edi_name}", EINA_COLOR_CYAN);
if (_${edi_name}_lib_log_dom < 0) if (_${edi_name}_lib_log_dom < 0)
{ {
EINA_LOG_ERR("${EDI_NAME} can not create its log domain."); EINA_LOG_ERR("${Edi_Name} can not create its log domain.");
goto shutdown_eina; goto shutdown_eina;
} }

View File

@ -6,13 +6,13 @@ AM_CPPFLAGS = \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \ -DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ -DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EFL_CFLAGS@ \ @EFL_CFLAGS@ \
-DEFL_EFL_BUILD -DEFL_${EDI_NAME}_BUILD
lib_LTLIBRARIES = lib${edi_name}.la lib_LTLIBRARIES = lib${edi_name}.la
includes_HEADERS = ${EDI_NAME}.h includes_HEADERS = ${Edi_Name}.h
includesdir = $(includedir)/${edi_name}-@VMAJ@ includesdir = $(includedir)/${edi_name}-@VMAJ@
lib${edi_name}_la_SOURCES = ${edi_name}.c lib${edi_name}_la_SOURCES = ${edi_name}.c
lib${edi_name}_la_LIBADD = @EFL_LIBS@ -lm lib${edi_name}_la_LIBADD = @EFL_LIBS@ -lm
lib${edi_name}_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@ lib${edi_name}_la_LDFLAGS = -no-undefined @EFL_LTLIBRARY_FLAGS@

View File

@ -5,9 +5,9 @@
#include <Ecore_Getopt.h> #include <Ecore_Getopt.h>
#include <check.h> #include <check.h>
#include "${EDI_NAME}.h" #include "${Edi_Name}.h"
#define COPYRIGHT "Copyright © ${EDI_YEAR} ${EDI_USER} <${EDI_EMAIL}> and various contributors (see AUTHORS)." #define COPYRIGHT "Copyright © ${Edi_Year} ${Edi_User} <${Edi_Email}> and various contributors (see AUTHORS)."
static void ${edi_name}_test_basic(TCase *tc); static void ${edi_name}_test_basic(TCase *tc);
@ -96,7 +96,7 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
goto end; goto end;
} }
s = suite_create("${EDI_NAME}"); s = suite_create("${Edi_Name}");
for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
{ {

View File

@ -40,7 +40,7 @@ _exe_del(void *d EINA_UNUSED, int t EINA_UNUSED, void *event_info EINA_UNUSED)
static const Ecore_Getopt optdesc = { static const Ecore_Getopt optdesc = {
"edi_build", "edi_build",
"%prog [options] [build-type]", "%prog [options] [build|clean|create|test]",
PACKAGE_VERSION, PACKAGE_VERSION,
COPYRIGHT, COPYRIGHT,
"BSD with advertisement clause", "BSD with advertisement clause",
@ -117,9 +117,12 @@ main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
edi_builder_test(); edi_builder_test();
else if (!strncmp("build", build_type, 5)) else if (!strncmp("build", build_type, 5))
edi_builder_build(); edi_builder_build();
else if (!strncmp("create", build_type, 6))
fprintf(stderr, "cannot yet make projects on command line");
// edi_create_efl_project(...);
else else
{ {
fprintf(stderr, "Unrecognised build type - try build, test or clean.\n"); fprintf(stderr, "Unrecognised build type - try build, clean, create or test.\n");
goto end; goto end;
} }
ecore_main_loop_begin(); ecore_main_loop_begin();

View File

@ -2,6 +2,9 @@
# include "config.h" # include "config.h"
#endif #endif
#include <sys/types.h>
#include <pwd.h>
#include <Elementary.h> #include <Elementary.h>
#include "edi_welcome.h" #include "edi_welcome.h"
@ -218,7 +221,30 @@ _edi_welcome_project_new_create_cb(void *data EINA_UNUSED, Evas_Object *obj EINA
user = elm_object_text_get(_create_inputs[3]); user = elm_object_text_get(_create_inputs[3]);
email = elm_object_text_get(_create_inputs[4]); email = elm_object_text_get(_create_inputs[4]);
edi_create_project(path, name, url, user, email, _edi_welcome_project_new_create_done_cb); edi_create_efl_project(path, name, url, user, email, _edi_welcome_project_new_create_done_cb);
}
static int
_edi_welcome_user_fullname_get(const char *username, char *fullname, size_t max)
{
struct passwd *p;
size_t n;
errno = 0;
p = getpwnam(username);
if (p == NULL && errno == 0)
return 0;
if (p == NULL)
return -1;
n = strcspn(p->pw_gecos, ",");
if (max == 0 || n <= 0)
return 0;
if (n > max - 1)
n = max - 1;
memcpy(fullname, p->pw_gecos, n);
fullname[n] = '\0';
return 1;
} }
static void static void
@ -227,17 +253,23 @@ _edi_welcome_project_new_cb(void *data, Evas_Object *obj EINA_UNUSED, void *even
Evas_Object *content, *button, *naviframe = data; Evas_Object *content, *button, *naviframe = data;
Elm_Object_Item *item; Elm_Object_Item *item;
int row = 0; int row = 0;
char fullname[1024];
char *username;
content = elm_table_add(naviframe); content = elm_table_add(naviframe);
elm_table_homogeneous_set(content, EINA_TRUE); elm_table_homogeneous_set(content, EINA_TRUE);
evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_weight_set(content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(content); evas_object_show(content);
username = getenv("USER");
_edi_welcome_project_new_directory_row_add("Parent Path", NULL, row++, content); _edi_welcome_project_new_directory_row_add("Parent Path", NULL, row++, content);
_edi_welcome_project_new_input_row_add("Project Name", NULL, row++, content); _edi_welcome_project_new_input_row_add("Project Name", NULL, row++, content);
_edi_welcome_project_new_input_row_add("Project URL", NULL, row++, content); _edi_welcome_project_new_input_row_add("Project URL", NULL, row++, content);
_edi_welcome_project_new_input_row_add("Username", getenv("USER"), row++, content); if (_edi_welcome_user_fullname_get(username, fullname, 1024) > 0)
_edi_welcome_project_new_input_row_add("Email", NULL, row++, content); _edi_welcome_project_new_input_row_add("Creator Name", fullname, row++, content);
else
_edi_welcome_project_new_input_row_add("Creator Name", username, row++, content);
_edi_welcome_project_new_input_row_add("Creator Email", NULL, row++, content);
button = elm_button_add(content); button = elm_button_add(content);
elm_object_text_set(button, "Create"); elm_object_text_set(button, "Create");

View File

@ -3,6 +3,7 @@
#include <Elementary.h> #include <Elementary.h>
#include <Eina.h> #include <Eina.h>
#include <Eio.h>
#ifdef EAPI #ifdef EAPI
# undef EAPI # undef EAPI

View File

@ -6,6 +6,102 @@
#include "edi_private.h" #include "edi_private.h"
static Edi_Create *_edi_create_data;
static const char *
_edi_create_filter_variable(const char *text, const char *variable, const char *value)
{
char *pos, *ret;
int copylen;
pos = strstr(text, variable);
if (!pos)
return strdup(text);
copylen = pos - text;
ret = malloc(sizeof(char) * (strlen(text) + strlen(value) - strlen(variable) + 1));
snprintf(ret, copylen + 1, text);
snprintf(ret + copylen, strlen(value) + 1, value);
snprintf(ret + copylen + strlen(value), strlen(text) - copylen - strlen(variable) + 1, text + copylen + strlen(variable));
return ret;
}
static const char *
_edi_create_filter_name(const char *text, const char *name)
{
char *lowername;
const char *filtered, *ret;
filtered = _edi_create_filter_variable(text, "${Edi_Name}", name);
lowername = strdup(name);
eina_str_tolower(&lowername);
ret = _edi_create_filter_variable(filtered, "${edi_name}", lowername);
free(lowername);
free((void *) filtered);
return ret;
}
static int
_edi_create_year_get()
{
time_t timeval;
struct tm *tp;
time (&timeval);
tp = gmtime(&timeval);
return tp->tm_year + 1900;
}
static void
_edi_create_filter_file(Edi_Create *create, const char *path)
{
char *cmd, *lowername, *uppername;
const char *template;
int length;
// TODO speed this up - pre-cache this filter!
template = "sed -i \"s|\\${edi_name}|%s|g;s|\\${Edi_Name}|%s|g;s|\\${EDI_NAME}|%s|g;s|\\${Edi_User}|%s|ig;s|\\${Edi_Email}|%s|g;s|\\${Edi_Url}|$%s|g;s|\\${Edi_Year}|%d|g\" %s";
length = strlen(template) + (strlen(create->name) * 3) + strlen(create->user) + strlen(create->email) + strlen(create->url) + strlen(path) + 4 - 16 + 1;
lowername = strdup(create->name);
eina_str_tolower(&lowername);
uppername = strdup(create->name);
eina_str_toupper(&uppername);
cmd = malloc(sizeof(char) * length);
snprintf(cmd, length, template, lowername, create->name, uppername , create->user, create->email, create->url, _edi_create_year_get(), path);
ecore_exe_run(cmd, NULL);
free(lowername);
free(uppername);
free(cmd);
// This matches the filtered path copy created in the copy callback
free((void *) path);
}
static void _edi_create_free_data()
{
Edi_Create *create;
create = _edi_create_data;
_edi_create_data = NULL;
free(create->url);
free(create->user);
free(create->email);
free(create->name);
free(create->path);
free(create);
}
static Eina_Bool static Eina_Bool
_edi_create_project_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED) _edi_create_project_done(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
{ {
@ -15,40 +111,104 @@ _edi_create_project_done(void *data, int type EINA_UNUSED, void *event EINA_UNUS
ecore_event_handler_del(create->handler); ecore_event_handler_del(create->handler);
create->callback(create->path, EINA_TRUE); create->callback(create->path, EINA_TRUE);
free(create->path);
free(data);
_edi_create_free_data();
return ECORE_CALLBACK_DONE; // or ECORE_CALLBACK_PASS_ON return ECORE_CALLBACK_DONE; // or ECORE_CALLBACK_PASS_ON
} }
EAPI void static void
edi_create_project(const char *path, const char *name, const char *url, _edi_create_move_done_cb(void *data, Eio_File *file EINA_UNUSED)
const char *user, const char *email, Edi_Create_Cb func) {
_edi_create_filter_file(_edi_create_data, (const char *) data);
}
static void
_edi_create_move_error_cb(void *data, Eio_File *handler EINA_UNUSED, int error)
{
fprintf(stderr, "move error for %s: [%s]\n", (char *) data, strerror(error));
// This matches the filtered path copy created in the copy callback
free(data);
}
static void
_edi_create_notify_cb(void *d, Eio_File *handler EINA_UNUSED, const Eio_Progress *info)
{
Edi_Create *data;
const char *filtered;
data = (Edi_Create *) d;
switch (info->op)
{
case EIO_FILE_COPY:
// this will get freed in the filter callback when it's done with
filtered = _edi_create_filter_name(info->dest, data->name);
if (strcmp(info->dest, filtered))
{
eio_file_move(info->dest, filtered, NULL, _edi_create_move_done_cb, _edi_create_move_error_cb, filtered);
}
else
{
_edi_create_filter_file(data, filtered);
}
break;
default:
break;
}
}
static void
_edi_create_done_cb(void *d, Eio_File *file EINA_UNUSED)
{ {
char script[PATH_MAX], fullpath[PATH_MAX];
char *cmd;
int cmdlen;
Edi_Create *data; Edi_Create *data;
Ecore_Event_Handler *handler; Ecore_Event_Handler *handler;
data = calloc(1, sizeof(Edi_Create)); data = (Edi_Create *) d;
handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _edi_create_project_done, data);
snprintf(script, sizeof(script), "%s/skeleton/eflprj", elm_app_data_dir_get()
);
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, name);
data->path = strdup(fullpath); handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _edi_create_project_done, data);
data->callback = func;
data->handler = handler; data->handler = handler;
cmdlen = strlen(script) + 19 + strlen(path) + strlen(name) + strlen(url) + strlen(user) + strlen(email); chdir(data->path);
cmd = malloc(sizeof(char) * cmdlen); ecore_exe_run("git init && git add .", data);
snprintf(cmd, cmdlen, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", }
script, fullpath, name, user, email, url);
INF("Creating project \"%s\" at path %s for %s<%s>\n", name, fullpath, user, email); static void
ecore_exe_run(cmd, data); _edi_create_error_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, int error)
free(cmd);
{
fprintf(stderr, "copy error: [%s]\n", strerror(error));
_edi_create_free_data();
}
EAPI void
edi_create_efl_project(const char *parentdir, const char *name, const char *url,
const char *user, const char *email, Edi_Create_Cb func)
{
char source[PATH_MAX], dest[PATH_MAX];
Edi_Create *data;
snprintf(source, sizeof(source), "%s/skeleton/eflproject", elm_app_data_dir_get());
snprintf(dest, sizeof(dest), "%s/%s", parentdir, name);
INF("Creating project \"%s\" at path %s for %s<%s>\n", name, dest, user, email);
data = calloc(1, sizeof(Edi_Create));
data->path = strdup(dest);
data->name = strdup(name);
data->url = strdup(url);
data->user = strdup(user);
data->email = strdup(email);
data->callback = func;
_edi_create_data = data;
eio_dir_copy(source, dest, NULL, _edi_create_notify_cb, _edi_create_done_cb,
_edi_create_error_cb, data);
} }

View File

@ -16,7 +16,8 @@ typedef void (*Edi_Create_Cb)(const char *path, Eina_Bool success);
typedef struct _Edi_Create typedef struct _Edi_Create
{ {
char *path; char *path, *name;
char *url, *user, *email;
Edi_Create_Cb callback; Edi_Create_Cb callback;
Ecore_Event_Handler *handler; Ecore_Event_Handler *handler;
@ -38,8 +39,8 @@ typedef struct _Edi_Create
* @ingroup Creation * @ingroup Creation
*/ */
EAPI void EAPI void
edi_create_project(const char *path, const char *name, const char *url, edi_create_efl_project(const char *parentdir, const char *name, const char *url,
const char *user, const char *email, Edi_Create_Cb func); const char *user, const char *email, Edi_Create_Cb func);
/** /**
* @} * @}