This thread contains a patchset. You're looking at the original emails,
but you may wish to use the patch review UI.
Review patch
13
[PATCH gcli 00/13] Patches for time_t timestamps
This is the giant patch that makes various place use time_t for
timestamps instead of plain strings.
This allows us to do regular time operations on the provided
timestamps.
In the future we may also do some more processing on these timestamps
such as outputting 'human readable formats' like '5 seconds ago' etc.
A PoC has already been done by gjn.
Review and comments highly appreciated.
Nico
Nico Sonack (13):
Add infrastructure for converting date values to use time_t instead of
strings
issues: Convert created_at to use a time_t
pulls: convert created_at field to using a time_t
table: teach table printer about timestamps
json_util: parse a null time stamp as unset
pipelines: convert timestamps to use time_t
releases: convert timestamps to use time_t
milestones: convert dates to use time_t
forks: convert to using time_t for timestamps
repos: convert to using time_t for timestamps
sshkeys: convert to using time_t for timestamps
attachments: convert to using time_t for timestamps
comments: convert to using a time_t for timestamps
include/gcli/attachments.h | 3 +-
include/gcli/cmd/table.h | 5 +++
include/gcli/comments.h | 3 +-
include/gcli/date_time.h | 7 ++++
include/gcli/forks.h | 4 +-
include/gcli/gitlab/pipelines.h | 10 ++---
include/gcli/issues.h | 3 +-
include/gcli/json_util.h | 2 +
include/gcli/milestones.h | 6 +--
include/gcli/pulls.h | 3 +-
include/gcli/releases.h | 4 +-
include/gcli/repos.h | 4 +-
include/gcli/sshkeys.h | 7 ++--
src/attachments.c | 1 -
src/cmd/comment.c | 13 +++++-
src/cmd/config.c | 2 +-
src/cmd/forks.c | 2 +-
src/cmd/issues.c | 5 +--
src/cmd/milestones.c | 14 +++----
src/cmd/pipelines.c | 48 +++++++++++-----------
src/cmd/pulls.c | 16 ++++----
src/cmd/releases.c | 16 ++++----
src/cmd/repos.c | 14 +++----
src/cmd/table.c | 33 ++++++++++++++--
src/comments.c | 1 -
src/date_time.c | 66 +++++++++++++++++++++++++++++++
src/forks.c | 1 -
src/gitlab/pipelines.c | 5 ---
src/issues.c | 1 -
src/json_util.c | 32 ++++++++++++++-
src/milestones.c | 6 ---
src/pulls.c | 1 -
src/releases.c | 1 -
src/repos.c | 1 -
src/sshkeys.c | 1 -
templates/bugzilla/bugs.t | 6 +--
templates/gitea/milestones.t | 6 +--
templates/github/comments.t | 2 +-
templates/github/forks.t | 2 +-
templates/github/issues.t | 2 +-
templates/github/milestones.t | 4 +-
templates/github/pulls.t | 2 +-
templates/github/releases.t | 2 +-
templates/github/repos.t | 2 +-
templates/gitlab/comments.t | 2 +-
templates/gitlab/forks.t | 2 +-
templates/gitlab/issues.t | 2 +-
templates/gitlab/merge_requests.t | 2 +-
templates/gitlab/milestones.t | 6 +--
templates/gitlab/pipelines.t | 10 ++---
templates/gitlab/releases.t | 2 +-
templates/gitlab/repos.t | 2 +-
templates/gitlab/sshkeys.t | 2 +-
tests/bugzilla-parse.c | 8 ++--
tests/github-parse.c | 20 +++++-----
tests/gitlab-parse.c | 20 +++++-----
56 files changed, 292 insertions(+), 155 deletions(-)
--
2.45.2
[PATCH gcli 01/13] Add infrastructure for converting date values to use time_t instead of strings
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/cmd/table.h | 4 +++
include/gcli/date_time.h | 7 +++++
include/gcli/json_util.h | 2 ++
src/cmd/table.c | 16 +++++++++++
src/date_time.c | 60 ++++++++++++++++++++++++++++++++++++++++
src/json_util.c | 27 +++++++++++++++++ -
6 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/include/gcli/cmd/table.h b/include/gcli/cmd/table.h
index 02a9384..32a8c76 100644
--- a/include/gcli/cmd/table.h
+++ b/include/gcli/cmd/table.h
@@ -36,6 +36,7 @@
#include <stdint.h>
#include <stdlib.h>
+ #include <time.h>
#include <gcli/gcli.h>
@@ -98,6 +99,9 @@ int gcli_dict_add(gcli_dict list, char const *key, int flags,
int gcli_dict_add_string(gcli_dict list, char const *key, int flags,
uint32_t colour_args, char const *str);
+ int gcli_dict_add_timestamp(gcli_dict list, char const *key, int flags,
+ uint32_t colour_args, time_t stamp);
+
int gcli_dict_add_sv_list(gcli_dict dict, char const *key, sn_sv const *list,
size_t list_size);
diff --git a/include/gcli/date_time.h b/include/gcli/date_time.h
index 4800dd3..8f03b6f 100644
--- a/include/gcli/date_time.h
+++ b/include/gcli/date_time.h
@@ -36,6 +36,8 @@
#include <gcli/gcli.h>
+ #include <time.h>
+
enum {
DATEFMT_ISO8601,
DATEFMT_GITLAB,
@@ -44,4 +46,9 @@ enum {
int gcli_normalize_date(struct gcli_ctx *ctx, int fmt, char const *const input,
char *output, size_t const output_size);
+ int gcli_parse_iso8601_date_time(struct gcli_ctx *ctx, char const *input,
+ time_t *out);
+
+ int gcli_format_as_localtime(struct gcli_ctx *ctx, time_t timestamp, char **out);
+
#endif /* GCLI_DATE_TIME_H */
diff --git a/include/gcli/json_util.h b/include/gcli/json_util.h
index dbe1432..ec4d8ba 100644
--- a/include/gcli/json_util.h
+++ b/include/gcli/json_util.h
@@ -58,6 +58,7 @@
#define get_label(ctx, input, out) get_label_(ctx, input, out, __func__)
#define get_is_string(ctx, input, out) ((void)ctx, (*out = json_next(input) == JSON_STRING), 1)
#define get_int_to_string(ctx, input, out) get_int_to_string_(ctx, input, out, __func__)
+ #define get_iso8601_time(ctx, input, out) get_iso8601_time_(ctx, input, out, __func__)
int get_int_(struct gcli_ctx *ctx, json_stream *input, int *out, char const *function);
int get_id_(struct gcli_ctx *ctx, json_stream *input, gcli_id *out, char const *function);
@@ -71,6 +72,7 @@ int get_string_(struct gcli_ctx *ctx, json_stream *input, char **out, char const
int get_sv_(struct gcli_ctx *ctx, json_stream *input, sn_sv *out, char const *function);
int get_user_(struct gcli_ctx *ctx, json_stream *input, char **out, char const *function);
int get_label_(struct gcli_ctx *ctx, json_stream *input, char const **out, char const *function);
+ int get_iso8601_time_(struct gcli_ctx *ctx, json_stream *input, time_t *out, char const *function);
int get_github_style_colour(struct gcli_ctx *ctx, json_stream *input, uint32_t *out);
int get_gitlab_style_colour(struct gcli_ctx *ctx, json_stream *input, uint32_t *out);
int get_github_is_pr(struct gcli_ctx *ctx, json_stream *input, int *out);
diff --git a/src/cmd/table.c b/src/cmd/table.c
index 0701e78..26166f8 100644
--- a/src/cmd/table.c
+++ b/src/cmd/table.c
@@ -27,9 +27,11 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+ #include <gcli/cmd/cmd.h>
#include <gcli/cmd/colour.h>
#include <gcli/cmd/table.h>
+ #include <gcli/date_time.h>
#include <gcli/gcli.h>
#include <stdarg.h>
@@ -426,6 +428,20 @@ gcli_dict_add_string(gcli_dict list,
strdup(str ? str : "<empty>"));
}
+ int
+ gcli_dict_add_timestamp(gcli_dict list, char const *key, int flags,
+ uint32_t colour_args, time_t stamp)
+ {
+ char *tmp = NULL;
+ int rc = 0;
+
+ rc = gcli_format_as_localtime(g_clictx, stamp, &tmp);
+ if (rc < 0)
+ return rc;
+
+ return gcli_dict_add_row(list, key, flags, colour_args, tmp);
+ }
+
int
gcli_dict_add_sv_list(gcli_dict dict,
char const *const key,
diff --git a/src/date_time.c b/src/date_time.c
index c026626..883aba5 100644
--- a/src/date_time.c
+++ b/src/date_time.c
@@ -32,6 +32,9 @@
#include <gcli/gcli.h>
#include <assert.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
#include <time.h>
int
@@ -75,3 +78,60 @@ gcli_normalize_date(struct gcli_ctx *ctx, int fmt, char const *const input,
return 0;
}
+
+ int
+ gcli_parse_iso8601_date_time(struct gcli_ctx *ctx, char const *const input,
+ time_t *const out)
+ {
+ char *endptr = NULL, *oldtz = NULL;
+ struct tm tm_buf = {0};
+
+ endptr = strptime(input, "%Y-%m-%dT%H:%M:%S", &tm_buf);
+ if (endptr && *endptr != '.' && *endptr != 'Z') {
+ return gcli_error(ctx, "failed to parse ISO8601 timestamp \"%s\": %s",
+ input, strerror(errno));
+ }
+
+ /* Thanks, POSIX, for this ugly pile of rubbish! */
+ {
+ oldtz = getenv("TZ");
+ if (oldtz)
+ oldtz = strdup(oldtz);
+
+ /* TODO error handling */
+ setenv("TZ", "GMT0", 1);
+ tzset();
+
+ *out = mktime(&tm_buf);
+
+ if (oldtz) {
+ setenv("TZ", oldtz, 1);
+ free(oldtz);
+ } else {
+ unsetenv("TZ");
+ }
+
+ tzset();
+ }
+
+
+ return 0;
+ }
+
+ int
+ gcli_format_as_localtime(struct gcli_ctx *ctx, time_t timestamp, char **out)
+ {
+ char tmp[sizeof "YYYY-MMM-DD HH:MM:SS"] = {0};
+ struct tm tm_buf = {0};
+ size_t rc = 0;
+
+ rc = strftime(tmp, sizeof tmp, "%Y-%b-%d %H:%M:%S",
+ localtime_r(×tamp, &tm_buf));
+
+ if (rc + 1 != sizeof tmp)
+ return gcli_error(ctx, "error formatting time stamp");
+
+ *out = strdup(tmp);
+
+ return 0;
+ }
diff --git a/src/json_util.c b/src/json_util.c
index b2402e4..e255cc4 100644
--- a/src/json_util.c
+++ b/src/json_util.c
@@ -27,8 +27,9 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- #include <gcli/json_util.h>
+ #include <gcli/date_time.h>
#include <gcli/forges.h>
+ #include <gcli/json_util.h>
#include <sn/sn.h>
#include <assert.h>
@@ -539,3 +540,27 @@ get_gitea_notification_target_type(struct gcli_ctx *ctx, json_stream *input,
return rc;
}
+
+ int
+ get_iso8601_time_(struct gcli_ctx *ctx, json_stream *input, time_t *out,
+ char const *where)
+ {
+ char *copy;
+ char const *it;
+ enum json_type type;
+ size_t len;
+ int rc = 0;
+
+ type = json_next(input);
+ if (type != JSON_STRING)
+ return gcli_error(ctx, "unexpected non-string field in %s", where);
+
+ it = json_get_string(input, &len);
+ copy = sn_strndup(it, len);
+
+ rc = gcli_parse_iso8601_date_time(ctx, copy, out);
+
+ free(copy);
+
+ return rc;
+ }
--
2.45.2
[PATCH gcli 03/13] pulls: convert created_at field to using a time_t
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/pulls.h | 3 ++ -
src/cmd/pulls.c | 16 ++++++++ --------
src/pulls.c | 1 -
templates/github/pulls.t | 2 + -
templates/gitlab/merge_requests.t | 2 + -
tests/github-parse.c | 2 + -
tests/gitlab-parse.c | 2 + -
7 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/include/gcli/pulls.h b/include/gcli/pulls.h
index faedece..c35c706 100644
--- a/include/gcli/pulls.h
+++ b/include/gcli/pulls.h
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <stdbool.h>
+ #include <time.h>
#include <gcli/diffutil.h>
#include <gcli/gcli.h>
@@ -51,7 +52,7 @@ struct gcli_pull {
char *state;
char *title;
char *body;
- char *created_at;
+ time_t created_at;
char *commits_link;
char *head_label;
char *base_label;
diff --git a/src/cmd/pulls.c b/src/cmd/pulls.c
index 27d0166..6103195 100644
--- a/src/cmd/pulls.c
+++ b/src/cmd/pulls.c
@@ -186,14 +186,14 @@ gcli_pull_print(struct gcli_pull const *const it)
dict = gcli_dict_begin();
- gcli_dict_add(dict, "NUMBER", 0, 0, "%"PRIid, it->number);
- gcli_dict_add_string(dict, "TITLE", 0, 0, it->title);
- gcli_dict_add_string(dict, "HEAD", 0, 0, it->head_label);
- gcli_dict_add_string(dict, "BASE", 0, 0, it->base_label);
- gcli_dict_add_string(dict, "CREATED", 0, 0, it->created_at);
- gcli_dict_add_string(dict, "AUTHOR", GCLI_TBLCOL_BOLD, 0, it->author);
- gcli_dict_add_string(dict, "STATE", GCLI_TBLCOL_STATECOLOURED, 0, it->state);
- gcli_dict_add(dict, "COMMENTS", 0, 0, "%d", it->comments);
+ gcli_dict_add(dict, "NUMBER", 0, 0, "%"PRIid, it->number);
+ gcli_dict_add_string(dict, "TITLE", 0, 0, it->title);
+ gcli_dict_add_string(dict, "HEAD", 0, 0, it->head_label);
+ gcli_dict_add_string(dict, "BASE", 0, 0, it->base_label);
+ gcli_dict_add_timestamp(dict, "CREATED", 0, 0, it->created_at);
+ gcli_dict_add_string(dict, "AUTHOR", GCLI_TBLCOL_BOLD, 0, it->author);
+ gcli_dict_add_string(dict, "STATE", GCLI_TBLCOL_STATECOLOURED, 0, it->state);
+ gcli_dict_add(dict, "COMMENTS", 0, 0, "%d", it->comments);
if (it->milestone)
gcli_dict_add_string(dict, "MILESTONE", 0, 0, it->milestone);
diff --git a/src/pulls.c b/src/pulls.c
index 84b1fd1..a0a5548 100644
--- a/src/pulls.c
+++ b/src/pulls.c
@@ -97,7 +97,6 @@ gcli_pull_free(struct gcli_pull *const it)
free(it->state);
free(it->title);
free(it->body);
- free(it->created_at);
free(it->commits_link);
free(it->head_label);
free(it->base_label);
diff --git a/templates/github/pulls.t b/templates/github/pulls.t
index fe476df..94a92ec 100644
--- a/templates/github/pulls.t
+++ b/templates/github/pulls.t
@@ -41,7 +41,7 @@ object of struct gcli_pull with
("title" => title as string,
"state" => state as string,
"body" => body as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"number" => number as id,
"id" => id as id,
"node_id" => node_id as string,
diff --git a/templates/gitlab/merge_requests.t b/templates/gitlab/merge_requests.t
index 058fc80..64dda4f 100644
--- a/templates/gitlab/merge_requests.t
+++ b/templates/gitlab/merge_requests.t
@@ -22,7 +22,7 @@ object of struct gcli_pull with
("title" => title as string,
"state" => state as string,
"description" => body as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"iid" => number as id,
"id" => id as id,
"labels" => labels as array of char* use get_string,
diff --git a/tests/github-parse.c b/tests/github-parse.c
index 5c2305a..d172277 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -129,7 +129,7 @@ ATF_TC_BODY(simple_github_pull, tc)
ATF_CHECK_STREQ(pull.state, "closed");
ATF_CHECK_STREQ(pull.title, "mark notifications as read/done");
ATF_CHECK_STREQ(pull.body, "Fixes #99\n");
- ATF_CHECK_STREQ(pull.created_at, "2022-03-22T13:20:57Z");
+ ATF_CHECK_EQ(pull.created_at, 1647955257);
ATF_CHECK_STREQ(pull.head_label, "herrhotzenplotz:99");
ATF_CHECK_STREQ(pull.base_label, "herrhotzenplotz:trunk");
ATF_CHECK_STREQ(pull.head_sha, "a00f475af1e31d56c7a5839508a21e2b76a31e49");
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index 0b98b6e..34e1280 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -59,7 +59,7 @@ ATF_TC_BODY(gitlab_simple_merge_request, tc)
ATF_CHECK_STREQ(pull.state, "merged");
ATF_CHECK_STREQ(pull.title, "Fix test suite");
ATF_CHECK_STREQ(pull.body, "This finally fixes the broken test suite");
- ATF_CHECK_STREQ(pull.created_at, "2023-08-31T23:37:50.848Z");
+ ATF_CHECK_EQ(pull.created_at, 1693525070);
ATF_CHECK(pull.commits_link == NULL);
ATF_CHECK_STREQ(pull.head_label, "fix-test-suite");
ATF_CHECK_STREQ(pull.base_label, "trunk");
--
2.45.2
[PATCH gcli 02/13] issues: Convert created_at to use a time_t
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/issues.h | 3 ++ -
src/cmd/issues.c | 3 + --
src/issues.c | 1 -
templates/bugzilla/bugs.t | 2 + -
templates/github/issues.t | 2 + -
templates/gitlab/issues.t | 2 + -
tests/bugzilla-parse.c | 2 + -
tests/github-parse.c | 4 ++ --
tests/gitlab-parse.c | 2 + -
9 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/include/gcli/issues.h b/include/gcli/issues.h
index baa38ec..5a6673b 100644
--- a/include/gcli/issues.h
+++ b/include/gcli/issues.h
@@ -40,6 +40,7 @@
#include <sn/sn.h>
#include <stdio.h>
#include <stdbool.h>
+ #include <time.h>
#include <gcli/attachments.h>
@@ -49,7 +50,7 @@ struct gcli_issue {
char *product; /* only on Bugzilla */
char *component; /* only on Bugzilla */
char *url; /* only on Bugzilla */
- char *created_at;
+ time_t created_at;
char *author;
char *state;
int comments;
diff --git a/src/cmd/issues.c b/src/cmd/issues.c
index 4bca8eb..b7de78e 100644
--- a/src/cmd/issues.c
+++ b/src/cmd/issues.c
@@ -161,7 +161,7 @@ gcli_issue_print_summary(struct gcli_issue const *const it)
gcli_dict_add(dict, "NUMBER", 0, 0, "%"PRIid, it->number);
gcli_dict_add(dict, "TITLE", 0, 0, "%s", it->title);
- gcli_dict_add(dict, "CREATED", 0, 0, "%s", it->created_at);
+ gcli_dict_add_timestamp(dict, "CREATED", 0, 0, it->created_at);
if ((quirks & GCLI_ISSUE_QUIRKS_PROD_COMP) == 0) {
gcli_dict_add(dict, "PRODUCT", 0, 0, "%s", it->product);
@@ -203,7 +203,6 @@ gcli_issue_print_summary(struct gcli_issue const *const it)
/* Dump the dictionary */
gcli_dict_end(dict);
-
}
void
diff --git a/src/issues.c b/src/issues.c
index 2d8d89a..9ec25b1 100644
--- a/src/issues.c
+++ b/src/issues.c
@@ -38,7 +38,6 @@ gcli_issue_free(struct gcli_issue *const it)
{
free(it->product);
free(it->component);
- free(it->created_at);
free(it->author);
free(it->state);
free(it->body);
diff --git a/templates/bugzilla/bugs.t b/templates/bugzilla/bugs.t
index 8983c0d..0bee370 100644
--- a/templates/bugzilla/bugs.t
+++ b/templates/bugzilla/bugs.t
@@ -15,7 +15,7 @@ parser bugzilla_bug_item is
object of struct gcli_issue with
("id" => number as id,
"summary" => title as string,
- "creation_time" => created_at as string,
+ "creation_time" => created_at as iso8601_time,
"creator_detail" => use parse_bugzilla_bug_creator,
"status" => state as string,
"product" => product as string,
diff --git a/templates/github/issues.t b/templates/github/issues.t
index 05de532..41f37b1 100644
--- a/templates/github/issues.t
+++ b/templates/github/issues.t
@@ -12,7 +12,7 @@ object of struct gcli_issue with
("title" => title as string,
"state" => state as string,
"body" => body as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"number" => number as id,
"comments" => comments as int,
"user" => author as user,
diff --git a/templates/gitlab/issues.t b/templates/gitlab/issues.t
index 46a90ea..3669cd1 100644
--- a/templates/gitlab/issues.t
+++ b/templates/gitlab/issues.t
@@ -11,7 +11,7 @@ object of struct gcli_issue with
("title" => title as string,
"state" => state as string,
"description" => body as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"iid" => number as id,
"user_notes_count" => comments as int,
"author" => author as user,
diff --git a/tests/bugzilla-parse.c b/tests/bugzilla-parse.c
index 96e3115..24f1485 100644
--- a/tests/bugzilla-parse.c
+++ b/tests/bugzilla-parse.c
@@ -87,7 +87,7 @@ ATF_TC_BODY(simple_bugzilla_issue, tc)
ATF_CHECK_EQ(issue->number, 1);
ATF_CHECK_STREQ(issue->title, "[aha] [scsi] Toshiba MK156FB scsi drive does not work with 2.0 kernel");
- ATF_CHECK_STREQ(issue->created_at, "1994-09-14T09:10:01Z");
+ ATF_CHECK_EQ(issue->created_at, 779533801);
ATF_CHECK_STREQ(issue->author, "Dave Evans");
ATF_CHECK_STREQ(issue->state, "Closed");
ATF_CHECK_STREQ(issue->product, "Base System");
diff --git a/tests/github-parse.c b/tests/github-parse.c
index a39756b..5c2305a 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -84,9 +84,9 @@ ATF_TC_BODY(simple_github_issue, tc)
ATF_REQUIRE(parse_github_issue(ctx, &stream, &issue) == 0);
- ATF_CHECK(issue.number = 115);
+ ATF_CHECK_EQ(issue.number, 115);
ATF_CHECK_STREQ(issue.title, "consider removing FILE *out from printing functions");
- ATF_CHECK_STREQ(issue.created_at, "2022-03-22T16:06:10Z");
+ ATF_CHECK_EQ(issue.created_at, 1647965170);
ATF_CHECK_STREQ(issue.author, "herrhotzenplotz");
ATF_CHECK_STREQ(issue.state, "closed");
ATF_CHECK(issue.comments == 0);
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index ae3b754..0b98b6e 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -97,7 +97,7 @@ ATF_TC_BODY(gitlab_simple_issue, tc)
ATF_CHECK(issue.number == 193);
ATF_CHECK_STREQ(issue.title, "Make notifications API use a list struct containing both the ptr and size");
- ATF_CHECK_STREQ(issue.created_at, "2023-08-13T18:43:05.766Z");
+ ATF_CHECK_EQ(issue.created_at, 1691952185);
ATF_CHECK_STREQ(issue.author, "herrhotzenplotz");
ATF_CHECK_STREQ(issue.state, "closed");
ATF_CHECK(issue.comments == 2);
--
2.45.2
[PATCH gcli 04/13] table: teach table printer about timestamps
This now assumes a time_t of zero to mean unset. For our cases this
should be sufficient.
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/cmd/table.h | 1 +
src/cmd/table.c | 17 +++++++++++++ ----
src/date_time.c | 6 ++++++
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/include/gcli/cmd/table.h b/include/gcli/cmd/table.h
index 32a8c76..120464a 100644
--- a/include/gcli/cmd/table.h
+++ b/include/gcli/cmd/table.h
@@ -68,6 +68,7 @@ enum gcli_tblcoltype {
GCLI_TBLCOLTYPE_LONG, /* signed long int */
GCLI_TBLCOLTYPE_ID, /* some ID type (uint64_t) */
GCLI_TBLCOLTYPE_STRING, /* C string */
+ GCLI_TBLCOLTYPE_TIME_T, /* a time_t unix timestamp */
GCLI_TBLCOLTYPE_DOUBLE, /* double precision float */
GCLI_TBLCOLTYPE_BOOL, /* yes/no */
};
diff --git a/src/cmd/table.c b/src/cmd/table.c
index 26166f8..ef4fa36 100644
--- a/src/cmd/table.c
+++ b/src/cmd/table.c
@@ -157,7 +157,7 @@ tablerow_add_cell(struct gcli_tbl *const table,
case GCLI_TBLCOLTYPE_STRING: {
char *it = va_arg(*vp, char *);
if (!it)
- it = "<empty>"; /* hack */
+ it = "N/A"; /* hack */
row->cells[col].text = strdup(it);
cell_size = strlen(it);
} break;
@@ -177,6 +177,15 @@ tablerow_add_cell(struct gcli_tbl *const table,
cell_size = 2;
}
} break;
+ case GCLI_TBLCOLTYPE_TIME_T: {
+ int rc = 0;
+ time_t val = va_arg(*vp, time_t);
+ rc = gcli_format_as_localtime(g_clictx, val, &row->cells[col].text);
+ if (rc < 0)
+ return rc;
+
+ cell_size = strlen(row->cells[col].text);
+ } break;
default:
return -1;
}
@@ -258,8 +267,8 @@ dump_row(struct gcli_tbl const *const table, size_t const i)
printf("%s", gcli_setbold());
/* Print cell if it is not NULL, otherwise indicate it by
- * printing <empty> */
- printf("%s", row->cells[col].text ? row->cells[col].text : "<empty>");
+ * printing N/A */
+ printf("%s", row->cells[col].text ? row->cells[col].text : "N/A");
/* End colour */
if (table->cols[col].flags &
@@ -425,7 +434,7 @@ gcli_dict_add_string(gcli_dict list,
char const *const str)
{
return gcli_dict_add_row(list, key, flags, colour_args,
- strdup(str ? str : "<empty>"));
+ strdup(str ? str : "N/A"));
}
int
diff --git a/src/date_time.c b/src/date_time.c
index 883aba5..dd46ad6 100644
--- a/src/date_time.c
+++ b/src/date_time.c
@@ -125,6 +125,12 @@ gcli_format_as_localtime(struct gcli_ctx *ctx, time_t timestamp, char **out)
struct tm tm_buf = {0};
size_t rc = 0;
+ /* if the timestamp is 0 we assume it is unset. */
+ if (timestamp == 0) {
+ *out = strdup("N/A");
+ return 0;
+ }
+
rc = strftime(tmp, sizeof tmp, "%Y-%b-%d %H:%M:%S",
localtime_r(×tamp, &tm_buf));
--
2.45.2
[PATCH gcli 05/13] json_util: parse a null time stamp as unset
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
src/json_util.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/json_util.c b/src/json_util.c
index e255cc4..72cbaa9 100644
--- a/src/json_util.c
+++ b/src/json_util.c
@@ -552,6 +552,11 @@ get_iso8601_time_(struct gcli_ctx *ctx, json_stream *input, time_t *out,
int rc = 0;
type = json_next(input);
+ if (type == JSON_NULL) {
+ *out = 0;
+ return 0;
+ }
+
if (type != JSON_STRING)
return gcli_error(ctx, "unexpected non-string field in %s", where);
--
2.45.2
[PATCH gcli 06/13] pipelines: convert timestamps to use time_t
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/gitlab/pipelines.h | 10 +++ ----
src/cmd/pipelines.c | 48 ++++++++++++++++ -----------------
src/gitlab/pipelines.c | 5 ----
templates/gitlab/pipelines.t | 10 +++ ----
tests/gitlab-parse.c | 4 + --
5 files changed, 36 insertions(+), 41 deletions(-)
diff --git a/include/gcli/gitlab/pipelines.h b/include/gcli/gitlab/pipelines.h
index 56e1cd6..7a24f66 100644
--- a/include/gcli/gitlab/pipelines.h
+++ b/include/gcli/gitlab/pipelines.h
@@ -39,8 +39,8 @@
struct gitlab_pipeline {
gcli_id id;
char *status;
- char *created_at;
- char *updated_at;
+ time_t created_at;
+ time_t updated_at;
char *ref;
char *sha;
char *source;
@@ -58,9 +58,9 @@ struct gitlab_job {
char *stage;
char *name;
char *ref;
- char *created_at;
- char *started_at;
- char *finished_at;
+ time_t created_at;
+ time_t started_at;
+ time_t finished_at;
double duration;
char *runner_name;
char *runner_description;
diff --git a/src/cmd/pipelines.c b/src/cmd/pipelines.c
index 8420508..54a1bcc 100644
--- a/src/cmd/pipelines.c
+++ b/src/cmd/pipelines.c
@@ -97,8 +97,8 @@ gitlab_print_pipelines(struct gitlab_pipeline_list const *const list)
struct gcli_tblcoldef cols[] = {
{ .name = "ID", .type = GCLI_TBLCOLTYPE_ID, .flags = GCLI_TBLCOL_JUSTIFYR },
{ .name = "STATUS", .type = GCLI_TBLCOLTYPE_STRING, .flags = GCLI_TBLCOL_STATECOLOURED },
- { .name = "CREATED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
- { .name = "UPDATED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "CREATED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
+ { .name = "UPDATED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "NAME", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
{ .name = "REF", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
};
@@ -133,8 +133,8 @@ gitlab_print_jobs(struct gitlab_job_list const *const list)
{ .name = "ID", .type = GCLI_TBLCOLTYPE_ID, .flags = GCLI_TBLCOL_JUSTIFYR },
{ .name = "NAME", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
{ .name = "STATUS", .type = GCLI_TBLCOLTYPE_STRING, .flags = GCLI_TBLCOL_STATECOLOURED },
- { .name = "STARTED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
- { .name = "FINISHED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "STARTED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
+ { .name = "FINISHED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "RUNNERDESC", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
{ .name = "REF", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
};
@@ -169,18 +169,18 @@ gitlab_print_job_status(struct gitlab_job const *const job)
printer = gcli_dict_begin();
- gcli_dict_add(printer, "ID", 0, 0, "%"PRIid, job->id);
- gcli_dict_add_string(printer, "STATUS", GCLI_TBLCOL_STATECOLOURED, 0, job->status);
- gcli_dict_add_string(printer, "STAGE", 0, 0, job->stage);
- gcli_dict_add_string(printer, "NAME", GCLI_TBLCOL_BOLD, 0, job->name);
- gcli_dict_add_string(printer, "REF", GCLI_TBLCOL_COLOUREXPL, GCLI_COLOR_YELLOW, job->ref);
- gcli_dict_add_string(printer, "CREATED", 0, 0, job->created_at);
- gcli_dict_add_string(printer, "STARTED", 0, 0, job->started_at);
- gcli_dict_add_string(printer, "FINISHED", 0, 0, job->finished_at);
- gcli_dict_add(printer, "DURATION", 0, 0, "%-.2lfs", job->duration);
- gcli_dict_add(printer, "COVERAGE", 0, 0, "%.1lf%%", job->coverage);
- gcli_dict_add_string(printer, "RUNNER NAME", 0, 0, job->runner_name);
- gcli_dict_add_string(printer, "RUNNER DESCR", 0, 0, job->runner_description);
+ gcli_dict_add(printer, "ID", 0, 0, "%"PRIid, job->id);
+ gcli_dict_add_string(printer, "STATUS", GCLI_TBLCOL_STATECOLOURED, 0, job->status);
+ gcli_dict_add_string(printer, "STAGE", 0, 0, job->stage);
+ gcli_dict_add_string(printer, "NAME", GCLI_TBLCOL_BOLD, 0, job->name);
+ gcli_dict_add_string(printer, "REF", GCLI_TBLCOL_COLOUREXPL, GCLI_COLOR_YELLOW, job->ref);
+ gcli_dict_add_timestamp(printer, "CREATED", 0, 0, job->created_at);
+ gcli_dict_add_timestamp(printer, "STARTED", 0, 0, job->started_at);
+ gcli_dict_add_timestamp(printer, "FINISHED", 0, 0, job->finished_at);
+ gcli_dict_add(printer, "DURATION", 0, 0, "%-.2lfs", job->duration);
+ gcli_dict_add(printer, "COVERAGE", 0, 0, "%.1lf%%", job->coverage);
+ gcli_dict_add_string(printer, "RUNNER NAME", 0, 0, job->runner_name);
+ gcli_dict_add_string(printer, "RUNNER DESCR", 0, 0, job->runner_description);
gcli_dict_end(printer);
}
@@ -192,14 +192,14 @@ gitlab_print_pipeline(struct gitlab_pipeline const *const pipeline)
printer = gcli_dict_begin();
- gcli_dict_add(printer, "ID", 0, 0, "%"PRIid, pipeline->id);
- gcli_dict_add_string(printer, "NAME", 0, 0, pipeline->name ? pipeline->name : "N/A");
- gcli_dict_add_string(printer, "STATUS", GCLI_TBLCOL_STATECOLOURED, 0, pipeline->status);
- gcli_dict_add_string(printer, "CREATED", 0, 0, pipeline->created_at);
- gcli_dict_add_string(printer, "UPDATED", 0, 0, pipeline->updated_at);
- gcli_dict_add_string(printer, "REF", GCLI_TBLCOL_COLOUREXPL, GCLI_COLOR_YELLOW, pipeline->ref);
- gcli_dict_add_string(printer, "SHA", GCLI_TBLCOL_COLOUREXPL, GCLI_COLOR_YELLOW, pipeline->sha);
- gcli_dict_add_string(printer, "SOURCE", 0, 0, pipeline->source);
+ gcli_dict_add(printer, "ID", 0, 0, "%"PRIid, pipeline->id);
+ gcli_dict_add_string(printer, "NAME", 0, 0, pipeline->name ? pipeline->name : "N/A");
+ gcli_dict_add_string(printer, "STATUS", GCLI_TBLCOL_STATECOLOURED, 0, pipeline->status);
+ gcli_dict_add_timestamp(printer, "CREATED", 0, 0, pipeline->created_at);
+ gcli_dict_add_timestamp(printer, "UPDATED", 0, 0, pipeline->updated_at);
+ gcli_dict_add_string(printer, "REF", GCLI_TBLCOL_COLOUREXPL, GCLI_COLOR_YELLOW, pipeline->ref);
+ gcli_dict_add_string(printer, "SHA", GCLI_TBLCOL_COLOUREXPL, GCLI_COLOR_YELLOW, pipeline->sha);
+ gcli_dict_add_string(printer, "SOURCE", 0, 0, pipeline->source);
gcli_dict_end(printer);
}
diff --git a/src/gitlab/pipelines.c b/src/gitlab/pipelines.c
index 94a674f..f6c7925 100644
--- a/src/gitlab/pipelines.c
+++ b/src/gitlab/pipelines.c
@@ -128,8 +128,6 @@ void
gitlab_pipeline_free(struct gitlab_pipeline *pipeline)
{
free(pipeline->status);
- free(pipeline->created_at);
- free(pipeline->updated_at);
free(pipeline->ref);
free(pipeline->sha);
free(pipeline->source);
@@ -204,9 +202,6 @@ gitlab_free_job(struct gitlab_job *const job)
free(job->stage);
free(job->name);
free(job->ref);
- free(job->created_at);
- free(job->started_at);
- free(job->finished_at);
free(job->runner_name);
free(job->runner_description);
}
diff --git a/templates/gitlab/pipelines.t b/templates/gitlab/pipelines.t
index 008ecf6..d34f27e 100644
--- a/templates/gitlab/pipelines.t
+++ b/templates/gitlab/pipelines.t
@@ -3,8 +3,8 @@ include "gcli/gitlab/pipelines.h";
parser gitlab_pipeline is
object of struct gitlab_pipeline with
("status" => status as string,
- "created_at" => created_at as string,
- "updated_at" => updated_at as string,
+ "created_at" => created_at as iso8601_time,
+ "updated_at" => updated_at as iso8601_time,
"ref" => ref as string,
"sha" => sha as string,
"source" => source as string,
@@ -24,9 +24,9 @@ object of struct gitlab_job with
"stage" => stage as string,
"name" => name as string,
"ref" => ref as string,
- "created_at" => created_at as string,
- "started_at" => started_at as string,
- "finished_at" => finished_at as string,
+ "created_at" => created_at as iso8601_time,
+ "started_at" => started_at as iso8601_time,
+ "finished_at" => finished_at as iso8601_time,
"runner" => use parse_gitlab_job_runner,
"duration" => duration as double,
"id" => id as id,
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index 34e1280..593c7c4 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -252,8 +252,8 @@ ATF_TC_BODY(gitlab_simple_pipeline, tc)
ATF_CHECK(pipeline.id == 989897020);
ATF_CHECK_STREQ(pipeline.status, "failed");
- ATF_CHECK_STREQ(pipeline.created_at, "2023-09-02T14:30:20.925Z");
- ATF_CHECK_STREQ(pipeline.updated_at, "2023-09-02T14:31:40.328Z");
+ ATF_CHECK_EQ(pipeline.created_at, 1693665020);
+ ATF_CHECK_EQ(pipeline.updated_at, 1693665100);
ATF_CHECK_STREQ(pipeline.ref, "refs/merge-requests/219/head");
ATF_CHECK_STREQ(pipeline.sha, "742affb88a297a6b34201ad61c8b5b72ec6eb679");
ATF_CHECK_STREQ(pipeline.source, "merge_request_event");
--
2.45.2
[PATCH gcli 08/13] milestones: convert dates to use time_t
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/milestones.h | 6 +++ ---
src/cmd/milestones.c | 14 +++++++ -------
src/milestones.c | 6 ------
templates/gitea/milestones.t | 6 +++ ---
templates/github/milestones.t | 4 ++ --
templates/gitlab/milestones.t | 6 +++ ---
tests/github-parse.c | 6 +++ ---
tests/gitlab-parse.c | 6 +++ ---
8 files changed, 24 insertions(+), 30 deletions(-)
diff --git a/include/gcli/milestones.h b/include/gcli/milestones.h
index 1da0fb4..1e6b1a8 100644
--- a/include/gcli/milestones.h
+++ b/include/gcli/milestones.h
@@ -44,12 +44,12 @@ struct gcli_milestone {
gcli_id id;
char *title;
char *state;
- char *created_at;
+ time_t created_at;
/* Extended info */
char *description;
- char *updated_at;
- char *due_date;
+ time_t updated_at;
+ time_t due_date;
bool expired;
/* Github and Gitea Specific */
diff --git a/src/cmd/milestones.c b/src/cmd/milestones.c
index defa7b6..9f63bd2 100644
--- a/src/cmd/milestones.c
+++ b/src/cmd/milestones.c
@@ -71,7 +71,7 @@ gcli_print_milestones(struct gcli_milestone_list const *const list, int max)
struct gcli_tblcoldef cols[] = {
{ .name = "ID", .type = GCLI_TBLCOLTYPE_ID, .flags = GCLI_TBLCOL_JUSTIFYR },
{ .name = "STATE", .type = GCLI_TBLCOLTYPE_STRING, .flags = GCLI_TBLCOL_STATECOLOURED },
- { .name = "CREATED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "CREATED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "TITLE", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
};
@@ -107,14 +107,14 @@ gcli_print_milestone(struct gcli_milestone const *const milestone)
uint32_t const quirks = gcli_forge(g_clictx)->milestone_quirks;
dict = gcli_dict_begin();
- gcli_dict_add(dict, "ID", 0, 0, "%"PRIid, milestone->id);
- gcli_dict_add_string(dict, "TITLE", 0, 0, milestone->title);
- gcli_dict_add_string(dict, "STATE", GCLI_TBLCOL_STATECOLOURED, 0, milestone->state);
- gcli_dict_add_string(dict, "CREATED", 0, 0, milestone->created_at);
- gcli_dict_add_string(dict, "UPDATED", 0, 0, milestone->created_at);
+ gcli_dict_add(dict, "ID", 0, 0, "%"PRIid, milestone->id);
+ gcli_dict_add_string(dict, "TITLE", 0, 0, milestone->title);
+ gcli_dict_add_string(dict, "STATE", GCLI_TBLCOL_STATECOLOURED, 0, milestone->state);
+ gcli_dict_add_timestamp(dict, "CREATED", 0, 0, milestone->created_at);
+ gcli_dict_add_timestamp(dict, "UPDATED", 0, 0, milestone->created_at);
if ((quirks & GCLI_MILESTONE_QUIRKS_DUEDATE) == 0)
- gcli_dict_add_string(dict, "DUE", 0, 0, milestone->due_date);
+ gcli_dict_add_timestamp(dict, "DUE", 0, 0, milestone->due_date);
if ((quirks & GCLI_MILESTONE_QUIRKS_EXPIRED) == 0)
gcli_dict_add_string(dict, "EXPIRED", 0, 0, sn_bool_yesno(milestone->expired));
diff --git a/src/milestones.c b/src/milestones.c
index fbac612..f4eac95 100644
--- a/src/milestones.c
+++ b/src/milestones.c
@@ -66,15 +66,9 @@ gcli_free_milestone(struct gcli_milestone *const it)
it->title = NULL;
free(it->state);
it->state = NULL;
- free(it->created_at);
- it->created_at = NULL;
free(it->description);
it->description = NULL;
- free(it->updated_at);
- it->updated_at = NULL;
- free(it->due_date);
- it->due_date = NULL;
}
void
diff --git a/templates/gitea/milestones.t b/templates/gitea/milestones.t
index d363ca9..9e1399e 100644
--- a/templates/gitea/milestones.t
+++ b/templates/gitea/milestones.t
@@ -4,12 +4,12 @@ parser gitea_milestone is
object of struct gcli_milestone with
("id" => id as id,
"title" => title as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"description" => description as string,
"state" => state as string,
- "updated_at" => updated_at as string,
+ "updated_at" => updated_at as iso8601_time,
"open_issues" => open_issues as int,
- "due_on" => due_date as string,
+ "due_on" => due_date as iso8601_time,
"closed_issues" => closed_issues as int);
parser gitea_milestones is
diff --git a/templates/github/milestones.t b/templates/github/milestones.t
index 6aea61f..1b010bf 100644
--- a/templates/github/milestones.t
+++ b/templates/github/milestones.t
@@ -4,9 +4,9 @@ parser github_milestone is
object of struct gcli_milestone with
("number" => id as id,
"title" => title as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"state" => state as string,
- "updated_at" => updated_at as string,
+ "updated_at" => updated_at as iso8601_time,
"description" => description as string,
"open_issues" => open_issues as int,
"closed_issues" => closed_issues as int);
diff --git a/templates/gitlab/milestones.t b/templates/gitlab/milestones.t
index 108a4ee..6e9cb99 100644
--- a/templates/gitlab/milestones.t
+++ b/templates/gitlab/milestones.t
@@ -5,10 +5,10 @@ object of struct gcli_milestone with
("title" => title as string,
"id" => id as id,
"state" => state as string,
- "created_at" => created_at as string,
+ "created_at" => created_at as iso8601_time,
"description" => description as string,
- "updated_at" => updated_at as string,
- "due_date" => due_date as string,
+ "updated_at" => updated_at as iso8601_time,
+ "due_date" => due_date as iso8601_time,
"expired" => expired as bool);
parser gitlab_milestones is array of struct gcli_milestone use parse_gitlab_milestone;
diff --git a/tests/github-parse.c b/tests/github-parse.c
index ed8c8c2..21a8117 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -191,10 +191,10 @@ ATF_TC_BODY(simple_github_milestone, tc)
ATF_CHECK(milestone.id == 1);
ATF_CHECK_STREQ(milestone.title, "Gitlab support");
ATF_CHECK_STREQ(milestone.state, "open");
- ATF_CHECK_STREQ(milestone.created_at, "2021-12-14T07:02:05Z");
+ ATF_CHECK_EQ(milestone.created_at, 1639465325);
ATF_CHECK_STREQ(milestone.description, "");
- ATF_CHECK_STREQ(milestone.updated_at, "2021-12-19T14:49:43Z");
- ATF_CHECK(milestone.due_date == NULL);
+ ATF_CHECK_EQ(milestone.updated_at, 1639925383);
+ ATF_CHECK_EQ(milestone.due_date, 0);
ATF_CHECK(milestone.expired == false);
ATF_CHECK(milestone.open_issues == 0);
ATF_CHECK(milestone.closed_issues == 8);
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index 02d75e5..b5f3279 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -226,9 +226,9 @@ ATF_TC_BODY(gitlab_simple_milestone, tc)
ATF_CHECK_STREQ(milestone.state, "active");
ATF_CHECK_STREQ(milestone.description,
"Things that need to be done for version 2");
- ATF_CHECK_STREQ(milestone.created_at, "2023-02-05T19:08:20.379Z");
- ATF_CHECK_STREQ(milestone.due_date, "<empty>");
- ATF_CHECK_STREQ(milestone.updated_at, "2023-02-05T19:08:20.379Z");
+ ATF_CHECK_EQ(milestone.created_at, 1675624100);
+ ATF_CHECK_EQ(milestone.due_date, 0);
+ ATF_CHECK_EQ(milestone.updated_at, 1675624100);
ATF_CHECK(milestone.expired == false);
json_close(&stream);
--
2.45.2
[PATCH gcli 07/13] releases: convert timestamps to use time_t
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/releases.h | 4 +++ -
src/cmd/releases.c | 16 ++++++++ --------
src/releases.c | 1 -
templates/github/releases.t | 2 + -
templates/gitlab/releases.t | 2 + -
tests/github-parse.c | 2 + -
tests/gitlab-parse.c | 2 + -
7 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/include/gcli/releases.h b/include/gcli/releases.h
index 5ac509a..45e1255 100644
--- a/include/gcli/releases.h
+++ b/include/gcli/releases.h
@@ -37,6 +37,8 @@
#include <gcli/gcli.h>
#include <sn/sn.h>
+ #include <time.h>
+
struct gcli_release_asset {
char *name;
char *url;
@@ -49,7 +51,7 @@ struct gcli_release {
char *name;
char *body;
char *author;
- char *date;
+ time_t date;
char *upload_url;
bool draft;
bool prerelease;
diff --git a/src/cmd/releases.c b/src/cmd/releases.c
index f79aab8..5d2cc3e 100644
--- a/src/cmd/releases.c
+++ b/src/cmd/releases.c
@@ -77,13 +77,13 @@ gcli_print_release(enum gcli_output_flags const flags,
dict = gcli_dict_begin();
- gcli_dict_add(dict, "ID", 0, 0, "%s", it->id);
- gcli_dict_add(dict, "NAME", 0, 0, "%s", it->name);
- gcli_dict_add(dict, "AUTHOR", 0, 0, "%s", it->author);
- gcli_dict_add(dict, "DATE", 0, 0, "%s", it->date);
- gcli_dict_add_string(dict, "DRAFT", 0, 0, sn_bool_yesno(it->draft));
- gcli_dict_add_string(dict, "PRERELEASE", 0, 0, sn_bool_yesno(it->prerelease));
- gcli_dict_add_string(dict, "ASSETS", 0, 0, "");
+ gcli_dict_add(dict, "ID", 0, 0, "%s", it->id);
+ gcli_dict_add(dict, "NAME", 0, 0, "%s", it->name);
+ gcli_dict_add(dict, "AUTHOR", 0, 0, "%s", it->author);
+ gcli_dict_add_timestamp(dict, "DATE", 0, 0, it->date);
+ gcli_dict_add_string(dict, "DRAFT", 0, 0, sn_bool_yesno(it->draft));
+ gcli_dict_add_string(dict, "PRERELEASE", 0, 0, sn_bool_yesno(it->prerelease));
+ gcli_dict_add_string(dict, "ASSETS", 0, 0, "");
/* asset urls */
for (size_t i = 0; i < it->assets_size; ++i) {
@@ -132,7 +132,7 @@ gcli_releases_print_short(enum gcli_output_flags const flags,
gcli_tbl table;
struct gcli_tblcoldef cols[] = {
{ .name = "ID", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
- { .name = "DATE", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "DATE", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "DRAFT", .type = GCLI_TBLCOLTYPE_BOOL, .flags = 0 },
{ .name = "PRERELEASE", .type = GCLI_TBLCOLTYPE_BOOL, .flags = 0 },
{ .name = "NAME", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
diff --git a/src/releases.c b/src/releases.c
index b6130f6..a36cbf3 100644
--- a/src/releases.c
+++ b/src/releases.c
@@ -48,7 +48,6 @@ gcli_release_free(struct gcli_release *release)
free(release->name);
free(release->body);
free(release->author);
- free(release->date);
free(release->upload_url);
for (size_t i = 0; i < release->assets_size; ++i) {
diff --git a/templates/github/releases.t b/templates/github/releases.t
index 4c176aa..a0accc2 100644
--- a/templates/github/releases.t
+++ b/templates/github/releases.t
@@ -11,7 +11,7 @@ object of struct gcli_release with
"body" => body as string,
"id" => id as int_to_string,
"author" => author as user,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"draft" => draft as bool,
"prerelease" => prerelease as bool,
"assets" => assets as array of gcli_release_asset
diff --git a/templates/gitlab/releases.t b/templates/gitlab/releases.t
index ad67b73..0040c0f 100644
--- a/templates/gitlab/releases.t
+++ b/templates/gitlab/releases.t
@@ -16,7 +16,7 @@ object of struct gcli_release with
"description" => body as string,
"assets" => use parse_gitlab_release_assets,
"author" => author as user,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"upcoming_release" => prerelease as bool);
parser gitlab_releases is
diff --git a/tests/github-parse.c b/tests/github-parse.c
index d172277..ed8c8c2 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -223,7 +223,7 @@ ATF_TC_BODY(simple_github_release, tc)
ATF_CHECK_STREQ(release.name, "1.2.0");
ATF_CHECK_STREQ(release.body, "# Version 1.2.0\n\nThis is version 1.2.0 of gcli.\n\n## Notes\n\nPlease test and report bugs.\n\nYou can download autotoolized tarballs at: https://herrhotzenplotz.de/gcli/releases/gcli-1.2.0/\n\n## Bug Fixes\n\n- Fix compile error when providing --with-libcurl without any arguments\n- Fix memory leaks in string processing functions\n- Fix missing nul termination in read-file function\n- Fix segmentation fault when clearing the milestone of a PR on Gitea\n- Fix missing documentation for milestone action in issues and pulls\n- Set the 'merged' flag properly when showing Gitlab merge requests\n\n## New features\n\n- Add a config subcommand for managing ssh keys (see gcli-config(1))\n- Show number of comments/notes in list of issues and PRs\n- Add support for milestone management in pull requests\n");
ATF_CHECK_STREQ(release.author, "herrhotzenplotz");
- ATF_CHECK_STREQ(release.date, "2023-08-11T07:42:37Z");
+ ATF_CHECK_EQ(release.date, 1691739757);
ATF_CHECK_STREQ(release.upload_url, "https://uploads.github.com/repos/herrhotzenplotz/gcli/releases/116031718/assets{?name,label}");
ATF_CHECK(release.draft == false);
ATF_CHECK(release.prerelease == false);
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index 593c7c4..02d75e5 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -179,7 +179,7 @@ ATF_TC_BODY(gitlab_simple_release, tc)
ATF_CHECK_STREQ(release.name, "1.2.0");
ATF_CHECK_STREQ(release.body, "# Version 1.2.0\n\nThis is version 1.2.0 of gcli.\n\n## Notes\n\nPlease test and report bugs.\n\nYou can download autotoolized tarballs at: https://herrhotzenplotz.de/gcli/releases/gcli-1.2.0/\n\n## Bug Fixes\n\n- Fix compile error when providing --with-libcurl without any arguments\n- Fix memory leaks in string processing functions\n- Fix missing nul termination in read-file function\n- Fix segmentation fault when clearing the milestone of a PR on Gitea\n- Fix missing documentation for milestone action in issues and pulls\n- Set the 'merged' flag properly when showing Gitlab merge requests\n\n## New features\n\n- Add a config subcommand for managing ssh keys (see gcli-config(1))\n- Show number of comments/notes in list of issues and PRs\n- Add support for milestone management in pull requests\n");
ATF_CHECK_STREQ(release.author, "herrhotzenplotz");
- ATF_CHECK_STREQ(release.date, "2023-08-11T07:56:06.371Z");
+ ATF_CHECK_EQ(release.date, 1691740566);
ATF_CHECK(release.upload_url == NULL);
ATF_CHECK(release.draft == false);
ATF_CHECK(release.prerelease == false);
--
2.45.2
[PATCH gcli 11/13] sshkeys: convert to using time_t for timestamps
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/sshkeys.h | 7 ++++ ---
src/cmd/config.c | 2 + -
src/sshkeys.c | 1 -
templates/gitlab/sshkeys.t | 2 + -
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/gcli/sshkeys.h b/include/gcli/sshkeys.h
index 911b352..2d667b1 100644
--- a/include/gcli/sshkeys.h
+++ b/include/gcli/sshkeys.h
@@ -34,15 +34,16 @@
#include <config.h>
#endif
- #include <stddef.h>
-
#include <gcli/gcli.h>
+ #include <stddef.h>
+ #include <time.h>
+
struct gcli_sshkey {
gcli_id id;
char *title;
char *key;
- char *created_at;
+ time_t created_at;
};
struct gcli_sshkey_list {
diff --git a/src/cmd/config.c b/src/cmd/config.c
index cd2d49c..22b3e8a 100644
--- a/src/cmd/config.c
+++ b/src/cmd/config.c
@@ -64,7 +64,7 @@ gcli_sshkeys_print_keys(struct gcli_sshkey_list const *list)
gcli_tbl *tbl;
struct gcli_tblcoldef cols[] = {
{ .name = "ID", .type = GCLI_TBLCOLTYPE_ID, .flags = 0 },
- { .name = "CREATED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "CREATED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "TITLE", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
};
diff --git a/src/sshkeys.c b/src/sshkeys.c
index 5f079d4..2a569be 100644
--- a/src/sshkeys.c
+++ b/src/sshkeys.c
@@ -47,7 +47,6 @@ gcli_sshkeys_free_keys(struct gcli_sshkey_list *list)
for (size_t i = 0; i < list->keys_size; ++i) {
free(list->keys[i].title);
free(list->keys[i].key);
- free(list->keys[i].created_at);
}
free(list->keys);
diff --git a/templates/gitlab/sshkeys.t b/templates/gitlab/sshkeys.t
index b0be207..4119812 100644
--- a/templates/gitlab/sshkeys.t
+++ b/templates/gitlab/sshkeys.t
@@ -5,6 +5,6 @@ object of struct gcli_sshkey with
("title" => title as string,
"id" => id as id,
"key" => key as string,
- "created_at" => created_at as string);
+ "created_at" => created_at as iso8601_time);
parser gitlab_sshkeys is array of struct gcli_sshkey use parse_gitlab_sshkey;
--
2.45.2
[PATCH gcli 09/13] forks: convert to using time_t for timestamps
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/forks.h | 4 +++ -
src/cmd/forks.c | 2 + -
src/forks.c | 1 -
templates/github/forks.t | 2 + -
templates/gitlab/forks.t | 2 + -
tests/github-parse.c | 2 + -
tests/gitlab-parse.c | 2 + -
7 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/gcli/forks.h b/include/gcli/forks.h
index 695452a..495e16b 100644
--- a/include/gcli/forks.h
+++ b/include/gcli/forks.h
@@ -37,10 +37,12 @@
#include <sn/sn.h>
#include <gcli/gcli.h>
+ #include <time.h>
+
struct gcli_fork {
char *full_name;
char *owner;
- char *date;
+ time_t date;
int forks;
};
diff --git a/src/cmd/forks.c b/src/cmd/forks.c
index f38e213..38acf97 100644
--- a/src/cmd/forks.c
+++ b/src/cmd/forks.c
@@ -69,7 +69,7 @@ gcli_print_forks(enum gcli_output_flags const flags,
gcli_tbl table;
struct gcli_tblcoldef cols[] = {
{ .name = "OWNER", .type = GCLI_TBLCOLTYPE_STRING, .flags = GCLI_TBLCOL_BOLD },
- { .name = "DATE", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "DATE", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "FORKS", .type = GCLI_TBLCOLTYPE_INT, .flags = GCLI_TBLCOL_JUSTIFYR },
{ .name = "FULLNAME", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
};
diff --git a/src/forks.c b/src/forks.c
index b8ee77a..266821c 100644
--- a/src/forks.c
+++ b/src/forks.c
@@ -52,7 +52,6 @@ gcli_fork_free(struct gcli_fork *fork)
{
free(fork->full_name);
free(fork->owner);
- free(fork->date);
}
void
diff --git a/templates/github/forks.t b/templates/github/forks.t
index 55e2a96..8f5b930 100644
--- a/templates/github/forks.t
+++ b/templates/github/forks.t
@@ -4,7 +4,7 @@ parser github_fork is
object of struct gcli_fork with
("full_name" => full_name as string,
"owner" => owner as user,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"forks_count" => forks as int);
parser github_forks is array of struct gcli_fork
diff --git a/templates/gitlab/forks.t b/templates/gitlab/forks.t
index d63ab51..09949c4 100644
--- a/templates/gitlab/forks.t
+++ b/templates/gitlab/forks.t
@@ -8,7 +8,7 @@ parser gitlab_fork is
object of struct gcli_fork with
("path_with_namespace" => full_name as string,
"namespace" => use parse_gitlab_fork_namespace,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"forks_count" => forks as int);
parser gitlab_forks is
diff --git a/tests/github-parse.c b/tests/github-parse.c
index 21a8117..19e2dd8 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -274,7 +274,7 @@ ATF_TC_BODY(simple_github_fork, tc)
ATF_CHECK_STREQ(fork.full_name, "gjnoonan/quick-lint-js");
ATF_CHECK_STREQ(fork.owner, "gjnoonan");
- ATF_CHECK_STREQ(fork.date, "2023-05-11T05:37:41Z");
+ ATF_CHECK_EQ(fork.date, 1683783461);
ATF_CHECK(fork.forks == 0);
json_close(&stream);
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index b5f3279..0cb3960 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -202,7 +202,7 @@ ATF_TC_BODY(gitlab_simple_fork, tc)
ATF_CHECK_STREQ(fork.full_name, "gjnoonan/gcli");
ATF_CHECK_STREQ(fork.owner, "gjnoonan");
- ATF_CHECK_STREQ(fork.date, "2022-10-02T13:54:20.517Z");
+ ATF_CHECK_EQ(fork.date, 1664718860);
ATF_CHECK(fork.forks == 0);
json_close(&stream);
--
2.45.2
[PATCH gcli 12/13] attachments: convert to using time_t for timestamps
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/attachments.h | 3 ++ -
src/attachments.c | 1 -
src/cmd/issues.c | 2 + -
templates/bugzilla/bugs.t | 2 + -
tests/bugzilla-parse.c | 4 ++ --
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/gcli/attachments.h b/include/gcli/attachments.h
index 1b93f0a..5cb708e 100644
--- a/include/gcli/attachments.h
+++ b/include/gcli/attachments.h
@@ -38,13 +38,14 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
+ #include <time.h>
#include <gcli/gcli.h>
struct gcli_attachment {
gcli_id id;
bool is_obsolete;
- char *created_at;
+ time_t created_at;
char *author;
char *file_name;
char *summary;
diff --git a/src/attachments.c b/src/attachments.c
index 5e6f813..b32de7f 100644
--- a/src/attachments.c
+++ b/src/attachments.c
@@ -47,7 +47,6 @@ gcli_attachments_free(struct gcli_attachment_list *list)
void
gcli_attachment_free(struct gcli_attachment *it)
{
- free(it->created_at);
free(it->author);
free(it->file_name);
free(it->summary);
diff --git a/src/cmd/issues.c b/src/cmd/issues.c
index b7de78e..5b80563 100644
--- a/src/cmd/issues.c
+++ b/src/cmd/issues.c
@@ -647,7 +647,7 @@ gcli_print_attachments(struct gcli_attachment_list const *const list)
struct gcli_tblcoldef columns[] = {
{ .name = "ID", .type = GCLI_TBLCOLTYPE_ID, .flags = GCLI_TBLCOL_JUSTIFYR },
{ .name = "AUTHOR", .type = GCLI_TBLCOLTYPE_STRING, .flags = GCLI_TBLCOL_BOLD },
- { .name = "CREATED", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
+ { .name = "CREATED", .type = GCLI_TBLCOLTYPE_TIME_T, .flags = 0 },
{ .name = "CONTENT", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
{ .name = "OBSOLETE", .type = GCLI_TBLCOLTYPE_BOOL, .flags = 0 },
{ .name = "FILENAME", .type = GCLI_TBLCOLTYPE_STRING, .flags = 0 },
diff --git a/templates/bugzilla/bugs.t b/templates/bugzilla/bugs.t
index 0bee370..c43ed57 100644
--- a/templates/bugzilla/bugs.t
+++ b/templates/bugzilla/bugs.t
@@ -65,7 +65,7 @@ object of struct gcli_attachment with
("id" => id as id,
"summary" => summary as string,
"file_name" => file_name as string,
- "creation_time" => created_at as string,
+ "creation_time" => created_at as iso8601_time,
"creator" => author as string,
"content_type" => content_type as string,
"is_obsolete" => is_obsolete as bool_relaxed,
diff --git a/tests/bugzilla-parse.c b/tests/bugzilla-parse.c
index 24f1485..20f5eb4 100644
--- a/tests/bugzilla-parse.c
+++ b/tests/bugzilla-parse.c
@@ -147,7 +147,7 @@ ATF_TC_BODY(bugzilla_attachments, tc)
ATF_CHECK_EQ(it->is_obsolete, true);
ATF_CHECK_STREQ(it->author, "nsonack@outlook.com");
ATF_CHECK_STREQ(it->content_type, "text/plain");
- ATF_CHECK_STREQ(it->created_at, "2023-11-04T20:19:11Z");
+ ATF_CHECK_EQ(it->created_at, 1699129151);
ATF_CHECK_STREQ(it->file_name, "0001-devel-open62541-Update-to-version-1.3.8.patch");
ATF_CHECK_STREQ(it->summary, "Patch for updating the port");
@@ -156,7 +156,7 @@ ATF_TC_BODY(bugzilla_attachments, tc)
ATF_CHECK_EQ(it->is_obsolete, false);
ATF_CHECK_STREQ(it->author, "nsonack@outlook.com");
ATF_CHECK_STREQ(it->content_type, "text/plain");
- ATF_CHECK_STREQ(it->created_at, "2023-12-08T17:10:06Z");
+ ATF_CHECK_EQ(it->created_at, 1702055406);
ATF_CHECK_STREQ(it->file_name, "0001-devel-open62541-Update-to-version-1.3.8.patch");
ATF_CHECK_STREQ(it->summary, "Patch v2 (now for version 1.3.9)");
--
2.45.2
[PATCH gcli 10/13] repos: convert to using time_t for timestamps
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/repos.h | 4 +++ -
src/cmd/repos.c | 14 +++++++ -------
src/repos.c | 1 -
templates/github/repos.t | 2 + -
templates/gitlab/repos.t | 2 + -
tests/github-parse.c | 2 + -
tests/gitlab-parse.c | 2 + -
7 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/include/gcli/repos.h b/include/gcli/repos.h
index 1cefe1e..5127a22 100644
--- a/include/gcli/repos.h
+++ b/include/gcli/repos.h
@@ -37,12 +37,14 @@
#include <sn/sn.h>
#include <gcli/gcli.h>
+ #include <time.h>
+
struct gcli_repo {
gcli_id id;
char *full_name;
char *name;
char *owner;
- char *date;
+ time_t date;
char *visibility;
bool is_fork;
};
diff --git a/src/cmd/repos.c b/src/cmd/repos.c
index bbacc14..293decc 100644
--- a/src/cmd/repos.c
+++ b/src/cmd/repos.c
@@ -121,13 +121,13 @@ gcli_repo_print(struct gcli_repo const *it)
gcli_dict dict;
dict = gcli_dict_begin();
- gcli_dict_add(dict, "ID", 0, 0, "%"PRIid, it->id);
- gcli_dict_add(dict, "FULL NAME", 0, 0, "%s", it->full_name);
- gcli_dict_add(dict, "NAME", 0, 0, "%s", it->name);
- gcli_dict_add(dict, "OWNER", 0, 0, "%s", it->owner);
- gcli_dict_add(dict, "DATE", 0, 0, "%s", it->date);
- gcli_dict_add(dict, "VISIBILITY", 0, 0, "%s", it->visibility);
- gcli_dict_add(dict, "IS FORK", 0, 0, "%s", sn_bool_yesno(it->is_fork));
+ gcli_dict_add(dict, "ID", 0, 0, "%"PRIid, it->id);
+ gcli_dict_add(dict, "FULL NAME", 0, 0, "%s", it->full_name);
+ gcli_dict_add(dict, "NAME", 0, 0, "%s", it->name);
+ gcli_dict_add(dict, "OWNER", 0, 0, "%s", it->owner);
+ gcli_dict_add_timestamp(dict, "DATE", 0, 0, it->date);
+ gcli_dict_add(dict, "VISIBILITY", 0, 0, "%s", it->visibility);
+ gcli_dict_add(dict, "IS FORK", 0, 0, "%s", sn_bool_yesno(it->is_fork));
gcli_dict_end(dict);
}
diff --git a/src/repos.c b/src/repos.c
index 14a5c50..aa7a7af 100644
--- a/src/repos.c
+++ b/src/repos.c
@@ -47,7 +47,6 @@ gcli_repo_free(struct gcli_repo *it)
free(it->full_name);
free(it->name);
free(it->owner);
- free(it->date);
free(it->visibility);
memset(it, 0, sizeof(*it));
}
diff --git a/templates/github/repos.t b/templates/github/repos.t
index 533bd43..6f54026 100644
--- a/templates/github/repos.t
+++ b/templates/github/repos.t
@@ -7,7 +7,7 @@ object of struct gcli_repo with
"full_name" => full_name as string,
"name" => name as string,
"owner" => owner as user,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"visibility" => visibility as string,
"private" => visibility as gitea_visibility,
"fork" => is_fork as bool);
diff --git a/templates/gitlab/repos.t b/templates/gitlab/repos.t
index 01429ee..19834b4 100644
--- a/templates/gitlab/repos.t
+++ b/templates/gitlab/repos.t
@@ -5,7 +5,7 @@ object of struct gcli_repo with
("path_with_namespace" => full_name as string,
"name" => name as string,
"owner" => owner as user,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"visibility" => visibility as string,
"fork" => is_fork as bool,
"id" => id as id);
diff --git a/tests/github-parse.c b/tests/github-parse.c
index 19e2dd8..f033bba 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -250,7 +250,7 @@ ATF_TC_BODY(simple_github_repo, tc)
ATF_CHECK_STREQ(repo.full_name, "herrhotzenplotz/gcli");
ATF_CHECK_STREQ(repo.name, "gcli");
ATF_CHECK_STREQ(repo.owner, "herrhotzenplotz");
- ATF_CHECK_STREQ(repo.date, "2021-10-08T14:20:15Z");
+ ATF_CHECK_EQ(repo.date, 1633702815);
ATF_CHECK_STREQ(repo.visibility, "public");
ATF_CHECK(repo.is_fork == false);
diff --git a/tests/gitlab-parse.c b/tests/gitlab-parse.c
index 0cb3960..dadd871 100644
--- a/tests/gitlab-parse.c
+++ b/tests/gitlab-parse.c
@@ -278,7 +278,7 @@ ATF_TC_BODY(gitlab_simple_repo, tc)
ATF_CHECK_STREQ(repo.full_name, "herrhotzenplotz/gcli");
ATF_CHECK_STREQ(repo.name, "gcli");
ATF_CHECK_STREQ(repo.owner, "herrhotzenplotz");
- ATF_CHECK_STREQ(repo.date, "2022-03-22T16:57:59.891Z");
+ ATF_CHECK_EQ(repo.date, 1647968279);
ATF_CHECK_STREQ(repo.visibility, "public");
ATF_CHECK(repo.is_fork == false);
--
2.45.2
[PATCH gcli 13/13] comments: convert to using a time_t for timestamps
Signed-off-by: Nico Sonack <nsonack@herrhotzenplotz.de>
---
include/gcli/comments.h | 3 ++ -
src/cmd/comment.c | 13 ++++++++++++ -
src/comments.c | 1 -
templates/bugzilla/bugs.t | 2 + -
templates/github/comments.t | 2 + -
templates/gitlab/comments.t | 2 + -
tests/bugzilla-parse.c | 2 + -
tests/github-parse.c | 2 + -
8 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/include/gcli/comments.h b/include/gcli/comments.h
index 4e508cd..ce37942 100644
--- a/include/gcli/comments.h
@@ -38,12 +38,13 @@
#include <stdio.h>
#include <stdlib.h>
+ #include <time.h>
#include <sn/sn.h>
struct gcli_comment {
char *author; /* Login name of the comment author */
- char *date; /* Creation date of the comment */
+ time_t date; /* Creation date of the comment */
gcli_id id; /* id of the comment */
char *body; /* Raw text of the comment */
};
diff --git a/src/cmd/comment.c b/src/cmd/comment.c
index cae3954..f9f14e9 100644
--- a/src/cmd/comment.c
@@ -36,6 +36,7 @@
#include <gcli/cmd/editor.h>
#include <gcli/comments.h>
+ #include <gcli/date_time.h>
#include <gcli/json_util.h>
#include <assert.h>
@@ -196,14 +197,24 @@ void
gcli_print_comment_list(struct gcli_comment_list const *const list)
{
for (size_t i = 0; i < list->comments_size; ++i) {
+ int rc = 0;
+ char *date = NULL;
+
+ rc = gcli_format_as_localtime(g_clictx, list->comments[i].date,
+ &date);
+ if (rc < 0)
+ err(1, "gcli: error: couldn't format timestamp");
+
printf("AUTHOR : %s%s%s\n"
"DATE : %s\n"
"ID : %"PRIid"\n",
gcli_setbold(), list->comments[i].author, gcli_resetbold(),
- list->comments[i].date,
+ date,
list->comments[i].id);
gcli_pretty_print(list->comments[i].body, 9, 80, stdout);
putchar('\n');
+
+ free(date);
}
}
diff --git a/src/comments.c b/src/comments.c
index 1020605..bf9f259 100644
--- a/src/comments.c
@@ -40,7 +40,6 @@ void
gcli_comment_free(struct gcli_comment *const it)
{
free(it->author);
- free(it->date);
free(it->body);
}
diff --git a/templates/bugzilla/bugs.t b/templates/bugzilla/bugs.t
index c43ed57..7e84160 100644
--- a/templates/bugzilla/bugs.t
+++ b/templates/bugzilla/bugs.t
@@ -34,7 +34,7 @@ parser bugzilla_comment is
object of struct gcli_comment with
("id" => id as id,
"text" => body as string,
- "creation_time" => date as string,
+ "creation_time" => date as iso8601_time,
"creator" => author as string);
parser bugzilla_comments_internal_skip_first is
diff --git a/templates/github/comments.t b/templates/github/comments.t
index e06f87b..90c015c 100644
--- a/templates/github/comments.t
@@ -3,7 +3,7 @@ include "gcli/github/comments.h";
parser github_comment is
object of struct gcli_comment with
("id" => id as id,
- "created_at" => date as string,
+ "created_at" => date as iso8601_time,
"body" => body as string,
"user" => author as user);
diff --git a/templates/gitlab/comments.t b/templates/gitlab/comments.t
index 6ee0f3a..7bf29c9 100644
--- a/templates/gitlab/comments.t
@@ -2,7 +2,7 @@ include "gcli/gitlab/comments.h";
parser gitlab_comment is
object of struct gcli_comment with
- ("created_at" => date as string,
+ ("created_at" => date as iso8601_time,
"body" => body as string,
"author" => author as user,
"id" => id as id);
diff --git a/tests/bugzilla-parse.c b/tests/bugzilla-parse.c
index 20f5eb4..44d1fc5 100644
--- a/tests/bugzilla-parse.c
+++ b/tests/bugzilla-parse.c
@@ -119,7 +119,7 @@ ATF_TC_BODY(bugzilla_comments, tc)
cmt = &list.comments[0];
ATF_CHECK_EQ(cmt->id, 1285943);
ATF_CHECK_STREQ(cmt->author, "zlei@FreeBSD.org");
- ATF_CHECK_STREQ(cmt->date, "2023-11-27T17:20:15Z");
+ ATF_CHECK_EQ(cmt->date, 1701105615);
ATF_CHECK(cmt->body != NULL);
gcli_comments_free(&list);
diff --git a/tests/github-parse.c b/tests/github-parse.c
index f033bba..1090bfa 100644
--- a/tests/github-parse.c
+++ b/tests/github-parse.c
@@ -297,7 +297,7 @@ ATF_TC_BODY(simple_github_comment, tc)
ATF_CHECK(comment.id == 1424392601);
ATF_CHECK_STREQ(comment.author, "herrhotzenplotz");
- ATF_CHECK_STREQ(comment.date, "2023-02-09T15:37:54Z");
+ ATF_CHECK_EQ(comment.date, 1675957074);
ATF_CHECK_STREQ(comment.body, "Hey,\n\nthe current trunk on Github might be a little outdated. I pushed the staging branch for version 1.0.0 from Gitlab to Github (cleanup-1.0). Could you try again with that branch and see if it still faults at the same place? If it does, please provide a full backtrace and if possible check with valgrind.\n");
json_close(&stream);
--
2.45.2