Basic build server configuration working.

This commit is contained in:
Scott Duensing 2022-12-19 20:42:34 -06:00
parent b3fd82bed3
commit b2905df911
7 changed files with 452 additions and 32 deletions

View file

@ -29,8 +29,9 @@
#define JOEYDEV_VERSION "@joeydev_VERSION_MAJOR@.@joeydev_VERSION_MINOR@"
#define PROJECT_VERSION "1.0" // Used for file format versioning.
#define VICTOR_VERSION "1.0" // Used for file format versioning.
#define BUILD_SETTINGS_VERSION "1.0" // Used for file format versioning.
#define PROJECT_VERSION "1.0" // Used for file format versioning.
#define VICTOR_VERSION "1.0" // Used for file format versioning.
#cmakedefine DEBUG_MODE

View file

@ -27,6 +27,16 @@
#include "common.h"
#ifdef _WIN32
#define UTIL_PATH_CHAR '\\'
#else
#define UTIL_PATH_CHAR '/'
#endif
#define UTIL_PATH_MAX 1024
char *utilCreateString(char *format, ...);
char *utilCreateStringVArgs(char *format, va_list args);
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
@ -35,6 +45,7 @@ gboolean utilFileOpen(WindowDataT *self, char *extension, char *what);
gboolean utilFileSaveAs(WindowDataT *self, char *extension, char *what);
WindowDataT *utilGetWindowData(GtkWidget *window);
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
gboolean utilMkDirP(const char *dir, const mode_t mode);
gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question);
void utilSetDirty(WindowDataT *self, gboolean dirty);
void utilWindowRegister(gpointer windowData);

View file

@ -53,9 +53,11 @@ typedef enum ProjectSectionTypeE ProjectSectionTypeT;
typedef struct ProjectDataS {
WindowDataT windowData;
GtkWidget *treeProject;
GtkTreeStore *storeProject;
char *title;
char *filename;
char *configName;
char *buildHost;
int buildPort;
char *buildUser;
char *buildPassword;
} ProjectDataT;
typedef struct SectionDataS {
@ -78,7 +80,11 @@ static SectionDataT _sectionData[] = {
};
#define BUILD_SETTINGS_RESPONSE_TEST 1
static void addToTree(ProjectDataT *self, char *filename);
static void loadConfig(ProjectDataT *self);
static void loadProject(ProjectDataT *self);
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData);
@ -91,6 +97,7 @@ EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userDat
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData);
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData);
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
static void saveConfig(ProjectDataT *self);
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
static void winProjectDelete(gpointer userData);
@ -100,8 +107,9 @@ static void addToTree(ProjectDataT *self, char *filename) {
char temp[4];
GtkTreeIter iterParent;
GtkTreeIter iter;
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject));
int fileLen;
int extLen;
int extLen;
// Is it long enough?
if (strlen(filename) > 2) {
@ -113,9 +121,9 @@ static void addToTree(ProjectDataT *self, char *filename) {
extLen = strlen(_sectionData[section].extension) - 1;
if (filename[fileLen - 1] == _sectionData[section].extension[extLen - 1] && filename[fileLen] == _sectionData[section].extension[extLen]) {
snprintf(temp, 4, "%d", section);
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(self->storeProject), &iterParent, temp);
gtk_tree_store_append(self->storeProject, &iter, &iterParent);
gtk_tree_store_set(self->storeProject, &iter, COL_FILENAME, filename, -1);
gtk_tree_model_get_iter_from_string(model, &iterParent, temp);
gtk_tree_store_append(GTK_TREE_STORE(model), &iter, &iterParent);
gtk_tree_store_set(GTK_TREE_STORE(model), &iter, COL_FILENAME, filename, -1);
//***TODO*** Need to store extra RAW data somewhere.
break;
}
@ -125,6 +133,68 @@ static void addToTree(ProjectDataT *self, char *filename) {
}
static void loadConfig(ProjectDataT *self) {
FILE *in = NULL;
char *line = NULL;
size_t len = 0;
size_t count = 0;
self->configName = utilCreateString("%s%cjoeydev%cbuild.conf", g_get_user_config_dir(), UTIL_PATH_CHAR, UTIL_PATH_CHAR);
if (utilFileExists(self->configName)) {
in = fopen(self->configName, "rt");
if (in != NULL) {
while (getline(&line, &len, in) != -1) {
if (strlen(line) > 0) line[strlen(line) - 1] = 0;
switch (count) {
case 0: // Version Number
case 1: // Separator line
break;
case 2: // Host
DEL(self->buildHost);
self->buildHost = strdup(line);
break;
case 3: // Port
self->buildPort = atoi(line);
break;
case 4: // User
DEL(self->buildUser);
self->buildUser = strdup(line);
break;
case 5: // Password
DEL(self->buildPassword);
self->buildPassword = strdup(line);
break;
default: // Oops
break;
}
count++;
}
fclose(in);
DEL(line);
} else {
//***TODO*** Something bad happened.
}
} else {
// No config file. Set defaults.
DEL(self->buildHost);
DEL(self->buildUser);
DEL(self->buildPassword);
self->buildHost = strdup("build.joeylib.com");
self->buildPort = 816;
self->buildUser = strdup(g_get_user_name());
self->buildPassword = strdup("SuperSecret");
saveConfig(self);
}
}
static void loadProject(ProjectDataT *self) {
FILE *in = NULL;
char *line = NULL;
@ -157,30 +227,45 @@ static void loadProject(ProjectDataT *self) {
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
GtkTreeIter iter;
ProjectSectionTypeT i;
GtkTreeStore *store;
(void)object;
gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), NULL);
store = gtk_tree_store_new(1, G_TYPE_STRING);
for (i=0; i<SECTION_COUNT; i++) {
gtk_tree_store_append(store, &iter, NULL);
gtk_tree_store_set(store, &iter, COL_FILENAME, _sectionData[i].name, -1);
}
gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), GTK_TREE_MODEL(store));
g_object_unref(store);
}
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
(void)object;
if (utilFileOpen((WindowDataT *)userData, "*.joe", "Project")) {
menuProjectFileNew(object, userData);
loadProject(self);
}
}
EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
FILE *out = NULL;
ProjectDataT *self = (ProjectDataT *)userData;
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject));
FILE *out = NULL;
GtkTreeIter iter;
GtkTreeIter child;
char *temp;
(void)object;
// Do we need to save?
if (self->windowData.isDirty == TRUE) {
@ -195,17 +280,17 @@ EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) {
// Save!
fprintf(out, "%s\n", PROJECT_VERSION);
fprintf(out, "------------------------------------------------------------------------------\n");
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(self->storeProject), &iter);
gtk_tree_model_get_iter_first(model, &iter);
do {
if (gtk_tree_model_iter_children(GTK_TREE_MODEL(self->storeProject), &child, &iter)) {
if (gtk_tree_model_iter_children(model, &child, &iter)) {
do {
//***TODO*** For RAW we need to store function name somewhere.
gtk_tree_model_get(GTK_TREE_MODEL(self->storeProject), &child, COL_FILENAME, &temp, -1);
gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1);
fprintf(out, "%s\n", temp);
DEL(temp);
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(self->storeProject), &child));
} while (gtk_tree_model_iter_next(model, &child));
}
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(self->storeProject), &iter));
} while (gtk_tree_model_iter_next(model, &iter));
fclose(out);
// We're clean now.
utilSetDirty((WindowDataT *)self, FALSE);
@ -282,13 +367,13 @@ EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData) {
// Is anything selected?
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
// Are we on a child item?
if (gtk_tree_store_iter_depth(self->storeProject, &iter) > 0) {
if (gtk_tree_store_iter_depth(GTK_TREE_STORE(model), &iter) > 0) {
found = TRUE;
}
}
if (found) {
gtk_tree_store_remove(self->storeProject, &iter);
gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
utilSetDirty((WindowDataT *)self, TRUE);
} else {
// Provide help.
@ -309,7 +394,61 @@ EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData) {
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
GtkWidget *dialogServerSettings;
GtkWidget *txtHost;
GtkWidget *txtPort;
GtkWidget *txtUser;
GtkWidget *txtPassword;
char *widgetNames[] = {
"dialogServerSettings",
"txtHost",
"txtPort",
"txtUser",
"txtPassword",
NULL
};
GtkWidget **widgets[] = {
&dialogServerSettings,
&txtHost,
&txtPort,
&txtUser,
&txtPassword
};
int result = 0;
char temp[6];
(void)object;
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/BuildServer.glade", widgetNames, widgets, self);
while (1) {
snprintf(temp, 6, "%d", self->buildPort);
gtk_entry_set_text(GTK_ENTRY(txtHost), self->buildHost);
gtk_entry_set_text(GTK_ENTRY(txtPort), temp);
gtk_entry_set_text(GTK_ENTRY(txtUser), self->buildUser);
gtk_entry_set_text(GTK_ENTRY(txtPassword), self->buildPassword);
result = gtk_dialog_run(GTK_DIALOG(dialogServerSettings));
if (result == BUILD_SETTINGS_RESPONSE_TEST || result == GTK_RESPONSE_OK) {
// Save settings to disk.
DEL(self->buildHost);
DEL(self->buildUser);
DEL(self->buildPassword);
self->buildHost = strdup(gtk_entry_get_text(GTK_ENTRY(txtHost)));
self->buildPort = atoi(gtk_entry_get_text(GTK_ENTRY(txtPort)));
self->buildUser = strdup(gtk_entry_get_text(GTK_ENTRY(txtUser)));
self->buildPassword = strdup(gtk_entry_get_text(GTK_ENTRY(txtPassword)));
saveConfig(self);
if (result == BUILD_SETTINGS_RESPONSE_TEST) {
// Run server connection test.
}
break;
}
}
gtk_widget_destroy(dialogServerSettings);
}
@ -326,6 +465,31 @@ EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData) {
}
static void saveConfig(ProjectDataT *self) {
char *temp;
FILE *out;
// Make sure we have a config folder.
temp = utilCreateString("%s%cjoeydev", g_get_user_config_dir(), UTIL_PATH_CHAR);
utilMkDirP(temp, 0777);
DEL(temp);
// Save config.
out = fopen(self->configName, "wt");
if (out != NULL) {
fprintf(out, "%s\n", BUILD_SETTINGS_VERSION);
fprintf(out, "------------------------------------------------------------------------------\n");
fprintf(out, "%s\n", self->buildHost);
fprintf(out, "%d\n", self->buildPort);
fprintf(out, "%s\n", self->buildUser);
fprintf(out, "%s\n", self->buildPassword); //***TODO*** This is hardly secure.
fclose(out);
} else {
//***TODO*** Something bad happened.
}
}
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData) {
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
@ -358,8 +522,6 @@ void winProjectCreate(void) {
};
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkTreeIter iter;
ProjectSectionTypeT i;
// Set up instance data.
self = NEW(ProjectDataT);
@ -376,15 +538,12 @@ void winProjectCreate(void) {
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_add_attribute(col, renderer, "text", COL_FILENAME);
self->storeProject = gtk_tree_store_new(1, G_TYPE_STRING);
for (i=0; i<SECTION_COUNT; i++) {
gtk_tree_store_append(self->storeProject, &iter, NULL);
gtk_tree_store_set(self->storeProject, &iter, COL_FILENAME, _sectionData[i].name, -1);
}
// Reset tree.
menuProjectFileNew(self->windowData.window, self);
gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), GTK_TREE_MODEL(self->storeProject));
g_object_unref(self->storeProject);
// Load server settings.
loadConfig(self);
// Register window & show it.
utilWindowRegister(self);
@ -401,6 +560,11 @@ static void winProjectDelete(gpointer userData) {
utilWindowUnRegister(userData);
DEL(self->buildHost);
DEL(self->buildUser);
DEL(self->buildPassword);
DEL(self->configName);
DEL(self);
}

View file

@ -20,9 +20,17 @@
*/
#include <sys/stat.h>
#include "utils.h"
#ifdef _WIN32
#define ourMkdir(p,m) mkdir(p)
#else
#define ourMkdir mkdir
#endif
typedef struct WindowListS {
GtkWidget *key;
WindowDataT *value;
@ -199,6 +207,67 @@ gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widg
}
gboolean utilMkDirP(const char *dir, const mode_t mode) {
char tmp[UTIL_PATH_MAX];
char *p = NULL;
struct stat sb;
size_t len;
// Make copy of dir.
len = strnlen(dir, UTIL_PATH_MAX);
if (len == 0 || len == UTIL_PATH_MAX) {
return -1;
}
memcpy(tmp, dir, len);
tmp[len] = '\0';
// Remove trailing slash.
if (tmp[len - 1] == UTIL_PATH_CHAR) {
tmp[len - 1] = '\0';
}
// Does it already exist?
if (stat(tmp, &sb) == 0) {
if (S_ISDIR(sb.st_mode)) {
return TRUE;
}
}
// Recursive mkdir.
for (p = tmp + 1; *p; p++) {
if (*p == UTIL_PATH_CHAR) {
*p = 0;
if (stat(tmp, &sb) != 0) {
// Does not exist - create it.
if (ourMkdir(tmp, mode) < 0) {
return FALSE;
}
} else {
if (!S_ISDIR(sb.st_mode)) {
// Not a directory
return FALSE;
}
}
*p = UTIL_PATH_CHAR;
}
}
// Check path
if (stat(tmp, &sb) != 0) {
// Does not exist - create it.
if (ourMkdir(tmp, mode) < 0) {
return FALSE;
}
} else {
if (!S_ISDIR(sb.st_mode)) {
// Not a directory
return FALSE;
}
}
return TRUE;
}
gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question) {
GtkWidget *dialog;
int response;

174
ui/BuildServer.glade Normal file
View file

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkDialog" id="dialogServerSettings">
<property name="can-focus">False</property>
<property name="title" translatable="yes">Build Server Settings</property>
<property name="default-width">200</property>
<property name="icon-name">applications-system</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="btnTest">
<property name="label" translatable="yes">Test</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnOkay">
<property name="label" translatable="yes">OK</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<!-- n-columns=2 n-rows=4 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="row-spacing">5</property>
<property name="column-spacing">5</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Host:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Port:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">User:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Password:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="txtHost">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="input-purpose">url</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="txtPort">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="input-purpose">digits</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="txtUser">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="input-purpose">name</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="txtPassword">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="input-purpose">password</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="1">btnTest</action-widget>
<action-widget response="-5">btnOkay</action-widget>
</action-widgets>
</object>
</interface>

View file

@ -144,7 +144,7 @@
<object class="GtkMenuItem" id="menuProjectBuildSettings">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Settings...</property>
<property name="label" translatable="yes">Server Settings...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectBuildSettings" swapped="no"/>
</object>

View file

@ -3,6 +3,7 @@
<gresource prefix="/com/kangaroopunch/joeydev">
<file preprocess="xml-stripblanks">JoeyDev.glade</file>
<file preprocess="xml-stripblanks">Project.glade</file>
<file preprocess="xml-stripblanks">BuildServer.glade</file>
<file preprocess="xml-stripblanks">Vector.glade</file>
<file>Logo.png</file>
</gresource>