From patchwork Fri Aug 21 21:06:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11730553 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E3F3D16B1 for ; Fri, 21 Aug 2020 21:06:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C58F52076E for ; Fri, 21 Aug 2020 21:06:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="tstiaWAz" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726429AbgHUVGU (ORCPT ); Fri, 21 Aug 2020 17:06:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725767AbgHUVGT (ORCPT ); Fri, 21 Aug 2020 17:06:19 -0400 Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8877DC061573 for ; Fri, 21 Aug 2020 14:06:19 -0700 (PDT) Received: by mail-wm1-x342.google.com with SMTP id u18so3105378wmc.3 for ; Fri, 21 Aug 2020 14:06:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=RtHmFdUygzahr63EplhuUWi4GrSbkocacAhyc4+oI5E=; b=tstiaWAzTui7JJP1U5K6gZh9MF22VxRKAcb3hU5+MGunY/HU+bOGdHoEgLNSGL5A7G leESFBQxT6LPPgV5Udg32cL5cAX1IIEt909SA78VHKInsjlORsVVciqgpTVC3RbO0ESJ NAk80BcocCQBkwMps8zYmM8tRIqUGTJBDaMFVB526D9msgcvuGiwcj3cWxeVd7GN+IuO l7MYRuwTAZub2hPV6L/GIpQabOP3HEEzDrjMqWYg5fwhDv9OdkyVRNxim99pFGutwsEx JEqTwdd9K09GkWTH3W4SAuLeC+20FEUt6MquXIXuRcMZh21Nb7+llnc3O2Ztx9h2LqKY JoFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=RtHmFdUygzahr63EplhuUWi4GrSbkocacAhyc4+oI5E=; b=rn/mYagMA0XXRK0lvfGsppG5MUrmVdVMVbhcdVTvLIlRxe2iO4J1Vu6Om2h4gXbiy+ dZ3LuJyOY5ZuOwOJ7rS7CI1aWlxgVdYEasYdP6oIe4EOeLYNcbKGckA40+BqJyFW8pJo 3YbByje/E340Ghc6yr/J2gHrHOdzlIeQo6Z4j739CXQ15w3tKEhHFszaZ3ytfsB9m4fG BAZn44h4i/B/+wNJVzo5Nv9KMk/4Uxss1P8nMFD/y1tHDWT4miPzqyUZejKNSA6bcqgo PP69t5IgFFxQa9R1FIf09vGEmlGskmJreKkJ58czfbH9xCAdHxGh33+mAxunzIjJlsOv I+wg== X-Gm-Message-State: AOAM531ihpDJUhzOAVihNDoeM5T31VfWm/M2JG3IRD9tzcEwckugK45z rjB9ydXF5M0DI/e2+dR0Xeo1ImApZa8= X-Google-Smtp-Source: ABdhPJyblIYZ7C3H5FB2oQasE7ZhBNk3ChC/jK1Y/vXgAk8uRaWLGfSS8M2DDtlLYzpA4td/QMEkkA== X-Received: by 2002:a7b:c38d:: with SMTP id s13mr5602126wmj.153.1598043978062; Fri, 21 Aug 2020 14:06:18 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r11sm6572912wrw.78.2020.08.21.14.06.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 14:06:17 -0700 (PDT) Message-Id: <383476b1778eb0d62c6cf013008388f72065beb0.1598043976.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Hariom Verma via GitGitGadget" Date: Fri, 21 Aug 2020 21:06:13 +0000 Subject: [PATCH v3 1/4] t6300: unify %(trailers) and %(contents:trailers) tests Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Hariom Verma , Hariom Verma Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Hariom Verma Currently, there are different tests for testing %(trailers) and %(contents:trailers) causing redundant copy. Its time to get rid of duplicate code. Mentored-by: Christian Couder Mentored-by: Heba Waly Signed-off-by: Hariom Verma --- t/t6300-for-each-ref.sh | 56 +++++++++++------------------------------ 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index a83579fbdf..0570380344 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -776,61 +776,40 @@ test_expect_success 'set up trailers for next test' ' ' test_expect_success '%(trailers:unfold) unfolds trailers' ' - git for-each-ref --format="%(trailers:unfold)" refs/heads/master >actual && { unfold expect && + git for-each-ref --format="%(trailers:unfold)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master >actual && test_cmp expect actual ' test_expect_success '%(trailers:only) shows only "key: value" trailers' ' - git for-each-ref --format="%(trailers:only)" refs/heads/master >actual && { grep -v patch.description expect && + git for-each-ref --format="%(trailers:only)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual && test_cmp expect actual ' test_expect_success '%(trailers:only) and %(trailers:unfold) work together' ' - git for-each-ref --format="%(trailers:only,unfold)" refs/heads/master >actual && - git for-each-ref --format="%(trailers:unfold,only)" refs/heads/master >reverse && - test_cmp actual reverse && { grep -v patch.description expect && - test_cmp expect actual -' - -test_expect_success '%(contents:trailers:unfold) unfolds trailers' ' - git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master >actual && - { - unfold expect && - test_cmp expect actual -' - -test_expect_success '%(contents:trailers:only) shows only "key: value" trailers' ' - git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual && - { - grep -v patch.description expect && - test_cmp expect actual -' - -test_expect_success '%(contents:trailers:only) and %(contents:trailers:unfold) work together' ' + git for-each-ref --format="%(trailers:only,unfold)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(trailers:unfold,only)" refs/heads/master >actual && + test_cmp actual actual && git for-each-ref --format="%(contents:trailers:only,unfold)" refs/heads/master >actual && - git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/master >reverse && - test_cmp actual reverse && - { - grep -v patch.description expect && - test_cmp expect actual + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/master >actual && + test_cmp actual actual ' test_expect_success '%(trailers) rejects unknown trailers arguments' ' @@ -839,14 +818,7 @@ test_expect_success '%(trailers) rejects unknown trailers arguments' ' fatal: unknown %(trailers) argument: unsupported EOF test_must_fail git for-each-ref --format="%(trailers:unsupported)" 2>actual && - test_i18ncmp expect actual -' - -test_expect_success '%(contents:trailers) rejects unknown trailers arguments' ' - # error message cannot be checked under i18n - cat >expect <<-EOF && - fatal: unknown %(trailers) argument: unsupported - EOF + test_i18ncmp expect actual && test_must_fail git for-each-ref --format="%(contents:trailers:unsupported)" 2>actual && test_i18ncmp expect actual ' From patchwork Fri Aug 21 21:06:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11730555 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 08BD2722 for ; Fri, 21 Aug 2020 21:06:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E28732076E for ; Fri, 21 Aug 2020 21:06:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="APTSIlSh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726672AbgHUVGY (ORCPT ); Fri, 21 Aug 2020 17:06:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49562 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725767AbgHUVGU (ORCPT ); Fri, 21 Aug 2020 17:06:20 -0400 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83CA0C061573 for ; Fri, 21 Aug 2020 14:06:20 -0700 (PDT) Received: by mail-wr1-x443.google.com with SMTP id y3so3137588wrl.4 for ; Fri, 21 Aug 2020 14:06:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=77R6AbXmTWZ77DHsAKLZQxMyUU7oRKoPASjgKoSLD3A=; b=APTSIlShcXv1jDIh3btZlBF4xK4dDK8ew7iAE09ElFBFjJukD40lQFPSfFYZ4RYKRS qy3eMAf8yGGHaGZqBtniGDrdwQmloSEdn3w8jN+cHjo8nsjVEOHzajIQzwAzanA4i1+W vGYwezA68SZA7btCWoSNyRsgr/jn1bqbYIBGrQcCAkuoEV31JnaWbqYaTNxdOCutoyw/ DDUcUHP/hJqnPt1FrEWJ8heNv8VIFTozYeSH9AWLBMwbFWKRmRIENLsxO4u8BRcaeFbO 31ujj5s2BVFMJZvlVyK6dS9A63qtg0bidQDf2D62KxYwMMSF+lJAVtDPWgfI2awP14mQ 00hA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=77R6AbXmTWZ77DHsAKLZQxMyUU7oRKoPASjgKoSLD3A=; b=FiDYFkxm3nP5+KNRssrgsW3wLH9EkTCtwS/p53eVfDUKZwUo+OVM73zruQByw9h00p Z3kjcbsuKjAQj68Yg7WKmCs0hUJHjgmSUDO9F6hNLn/+pXEoIrEM+ynRuKKaN2TDB/p8 4ieGqbR9Zj0ixWI1e3PvOrGxN/kO0+VtLB1la5tbOaS6qPjtz6bYh0EWdyzhAqE4EPTZ O13fUinfR2GzSH8z0IcicpI/iULKgpk64z4W+LC17xBSJ3Hye9U9OKydxDAlrk5F1d5O K9qdCRjDTh+k1O17YHpGbnsKOaT+XHaBZ5xTzitheia+YqmtJFOvAxdezjibhRTj2KUr CPww== X-Gm-Message-State: AOAM531NiJc0F3gIiGQUrxBZxGGi5ova3XvJR7zvIcifL1f+SLLDB3DV KuF1b+EnjJlXYkWplFZs/KfaEK+CTDU= X-Google-Smtp-Source: ABdhPJznPevUipy1rPG/mWqnFZjCv8MC2kF16l6szyUBdTfg+NpK/TZbUO6wJXszbfU0T+xI5CkTwA== X-Received: by 2002:adf:9d85:: with SMTP id p5mr4107887wre.286.1598043978952; Fri, 21 Aug 2020 14:06:18 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id g70sm8861976wmg.24.2020.08.21.14.06.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 14:06:18 -0700 (PDT) Message-Id: <659b9835dcd0b38ac3972eb19c08c3bf26dccc80.1598043976.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Hariom Verma via GitGitGadget" Date: Fri, 21 Aug 2020 21:06:14 +0000 Subject: [PATCH v3 2/4] ref-filter: 'contents:trailers' show error if `:` is missing Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Hariom Verma , Hariom Verma Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Hariom Verma The 'contents' atom does not show any error if used with 'trailers' atom and colon is missing before trailers arguments. e.g %(contents:trailersonly) works, while it shouldn't. It is definitely not an expected behavior. Let's fix this bug. Acked-by: Eric Sunshine Mentored-by: Christian Couder Mentored-by: Heba Waly Signed-off-by: Hariom Verma --- ref-filter.c | 8 +++++--- t/t6300-for-each-ref.sh | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index ba85869755..8ba0e31915 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -345,9 +345,11 @@ static int contents_atom_parser(const struct ref_format *format, struct used_ato atom->u.contents.option = C_SIG; else if (!strcmp(arg, "subject")) atom->u.contents.option = C_SUB; - else if (skip_prefix(arg, "trailers", &arg)) { - skip_prefix(arg, ":", &arg); - if (trailers_atom_parser(format, atom, *arg ? arg : NULL, err)) + else if (!strcmp(arg, "trailers")) { + if (trailers_atom_parser(format, atom, NULL, err)) + return -1; + } else if (skip_prefix(arg, "trailers:", &arg)) { + if (trailers_atom_parser(format, atom, arg, err)) return -1; } else if (skip_prefix(arg, "lines=", &arg)) { atom->u.contents.option = C_LINES; diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 0570380344..fdf2c442c5 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -823,6 +823,14 @@ test_expect_success '%(trailers) rejects unknown trailers arguments' ' test_i18ncmp expect actual ' +test_expect_success 'if arguments, %(contents:trailers) shows error if semicolon is missing' ' + cat >expect <<-EOF && + fatal: unrecognized %(contents) argument: trailersonly + EOF + test_must_fail git for-each-ref --format="%(contents:trailersonly)" 2>actual && + test_i18ncmp expect actual +' + test_expect_success 'basic atom: head contents:trailers' ' git for-each-ref --format="%(contents:trailers)" refs/heads/master >actual && sanitize_pgp actual.clean && From patchwork Fri Aug 21 21:06:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11730561 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AA7F1722 for ; Fri, 21 Aug 2020 21:06:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8D5FC207CD for ; Fri, 21 Aug 2020 21:06:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gggGPEs7" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726730AbgHUVGc (ORCPT ); Fri, 21 Aug 2020 17:06:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726495AbgHUVGW (ORCPT ); Fri, 21 Aug 2020 17:06:22 -0400 Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B9DFC061575 for ; Fri, 21 Aug 2020 14:06:21 -0700 (PDT) Received: by mail-wr1-x443.google.com with SMTP id d16so3115453wrq.9 for ; Fri, 21 Aug 2020 14:06:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=dZAUavJ6VP6u1mFNS5vtETsXLir357LHWkUpb5ONnvg=; b=gggGPEs763bfwS3CDgRVs0ky/8YsTEa30/Mdamx+e36ToZ2qMhbA+2wPWqA7ZwEyKz 1rHsmAMVyAqbUlFuSbP5NIYrJKSCmLYEMFSvdAjSZoC3/fZVWUdZKp5iklAWA3GpAWY1 IrNt6fQdsZTZfupmLIozXhv5ugDqGkKiVuUb+aZ0eYKRWpQsoYjuRe1QPp1UWl5H8XzX r0F3dWwBDJIuYToTN80j+kxcmqw9deSQmS+GUT3lxW+fzG7vMt4XRhkixb489X+vYlFz cuRUfEUUt1WhZM3bQXYrgpi9jLhYc/BZ1mdYXSWQECNpeJqvOBUUwtLIQMzh+PC465Ag XkSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=dZAUavJ6VP6u1mFNS5vtETsXLir357LHWkUpb5ONnvg=; b=QY60FMGTA4ULXuRra/nvZoYerh7AEEcI3bxsSv2a9HvdYqcw7lPYZqXNKWdJF8+6dz L9Y8u4UOmtdSoemrZIUtuEuDKpYxAUIW+0l/jzYG07zWlLALgILv9dy4faRoMB0rcCaK XiRnALdFDfbY8LXyjPi69MQC7GTBeh7f/F3dWecG8IfT8Ig4pwk6a5u+08YNwLpmaDyb qTAQs7F95zrRtQ14m17sB7Bb6D9STWozOu2yOkIuHdLPHTDt9Lr/xJ+EI3yUjreeaCA/ cn2G+Lqj94oX/q9qZmfL0D3K7+/emf/wAB+CZfEPkmjL9F79ZqHB1XIGF7aVyAO5ixs5 hvcg== X-Gm-Message-State: AOAM531fVnMCqFHr41Z3P+PyBkpBREpgsCr1sUVLnUtluGfoFWCux6KM PCefgw3ApNWu+boajfZg5UQP5JvAC7w= X-Google-Smtp-Source: ABdhPJwwkqDr+Z7B5o4y+8xzs9i26x2TDuqGa6772xC07jVDYMUF4vz5X2XtMQQuClE5RDe/PVzz+w== X-Received: by 2002:adf:bc4b:: with SMTP id a11mr4001498wrh.381.1598043979880; Fri, 21 Aug 2020 14:06:19 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id u16sm7417041wmc.7.2020.08.21.14.06.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 14:06:19 -0700 (PDT) Message-Id: <712ab9aacf240a02d808af6b6837e682b929493c.1598043976.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Hariom Verma via GitGitGadget" Date: Fri, 21 Aug 2020 21:06:15 +0000 Subject: [PATCH v3 3/4] pretty.c: refactor trailer logic to `format_set_trailers_options()` Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Hariom Verma , Hariom Verma Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Hariom Verma Refactored trailers formatting logic inside pretty.c to a new function `format_set_trailers_options()`. Also, introduced a code to get invalid trailer arguments. As we would like to use same logic in ref-filter, it's nice to get invalid trailer argument. This will allow us to print accurate error message, while using `format_set_trailers_options()` in ref-filter. Mentored-by: Christian Couder Mentored-by: Heba Waly Signed-off-by: Hariom Verma --- Hariom Verma via GitGitGadget | 0 pretty.c | 83 ++++++++++++++++++++++------------- pretty.h | 11 +++++ 3 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 Hariom Verma via GitGitGadget diff --git a/Hariom Verma via GitGitGadget b/Hariom Verma via GitGitGadget new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pretty.c b/pretty.c index 2a3d46bf42..bd8d38e27b 100644 --- a/pretty.c +++ b/pretty.c @@ -1147,6 +1147,55 @@ static int format_trailer_match_cb(const struct strbuf *key, void *ud) return 0; } +int format_set_trailers_options(struct process_trailer_options *opts, + struct string_list *filter_list, + struct strbuf *sepbuf, + const char **arg, + const char **err) +{ + for (;;) { + const char *argval; + size_t arglen; + + if (**arg != ')') { + size_t vallen = strcspn(*arg, "=,)"); + const char *valstart = xstrndup(*arg, vallen); + if (strcmp(valstart, "key") && + strcmp(valstart, "separator") && + strcmp(valstart, "only") && + strcmp(valstart, "valueonly") && + strcmp(valstart, "unfold")) { + *err = xstrdup(valstart); + return 1; + } + free((char *)valstart); + } + if (match_placeholder_arg_value(*arg, "key", arg, &argval, &arglen)) { + uintptr_t len = arglen; + + if (!argval) + return 1; + + if (len && argval[len - 1] == ':') + len--; + string_list_append(filter_list, argval)->util = (char *)len; + + opts->filter = format_trailer_match_cb; + opts->filter_data = filter_list; + opts->only_trailers = 1; + } else if (match_placeholder_arg_value(*arg, "separator", arg, &argval, &arglen)) { + char *fmt = xstrndup(argval, arglen); + strbuf_expand(sepbuf, fmt, strbuf_expand_literal_cb, NULL); + free(fmt); + opts->separator = sepbuf; + } else if (!match_placeholder_bool_arg(*arg, "only", arg, &opts->only_trailers) && + !match_placeholder_bool_arg(*arg, "unfold", arg, &opts->unfold) && + !match_placeholder_bool_arg(*arg, "valueonly", arg, &opts->value_only)) + break; + } + return 0; +} + static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ const char *placeholder, void *context) @@ -1417,41 +1466,14 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ struct string_list filter_list = STRING_LIST_INIT_NODUP; struct strbuf sepbuf = STRBUF_INIT; size_t ret = 0; + const char *unused = NULL; opts.no_divider = 1; if (*arg == ':') { arg++; - for (;;) { - const char *argval; - size_t arglen; - - if (match_placeholder_arg_value(arg, "key", &arg, &argval, &arglen)) { - uintptr_t len = arglen; - - if (!argval) - goto trailer_out; - - if (len && argval[len - 1] == ':') - len--; - string_list_append(&filter_list, argval)->util = (char *)len; - - opts.filter = format_trailer_match_cb; - opts.filter_data = &filter_list; - opts.only_trailers = 1; - } else if (match_placeholder_arg_value(arg, "separator", &arg, &argval, &arglen)) { - char *fmt; - - strbuf_reset(&sepbuf); - fmt = xstrndup(argval, arglen); - strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL); - free(fmt); - opts.separator = &sepbuf; - } else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) && - !match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) && - !match_placeholder_bool_arg(arg, "valueonly", &arg, &opts.value_only)) - break; - } + if (format_set_trailers_options(&opts, &filter_list, &sepbuf, &arg, &unused)) + goto trailer_out; } if (*arg == ')') { format_trailers_from_commit(sb, msg + c->subject_off, &opts); @@ -1460,6 +1482,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ trailer_out: string_list_clear(&filter_list, 0); strbuf_release(&sepbuf); + free((char *)unused); return ret; } diff --git a/pretty.h b/pretty.h index 071f2fb8e4..cfe2e8b39b 100644 --- a/pretty.h +++ b/pretty.h @@ -6,6 +6,7 @@ struct commit; struct strbuf; +struct process_trailer_options; /* Commit formats */ enum cmit_fmt { @@ -139,4 +140,14 @@ const char *format_subject(struct strbuf *sb, const char *msg, /* Check if "cmit_fmt" will produce an empty output. */ int commit_format_is_empty(enum cmit_fmt); +/* + * Set values of fields in "struct process_trailer_options" + * according to trailers arguments. + */ +int format_set_trailers_options(struct process_trailer_options *opts, + struct string_list *filter_list, + struct strbuf *sepbuf, + const char **arg, + const char **err); + #endif /* PRETTY_H */ From patchwork Fri Aug 21 21:06:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee via GitGitGadget X-Patchwork-Id: 11730557 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C090A1744 for ; Fri, 21 Aug 2020 21:06:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 951BD20791 for ; Fri, 21 Aug 2020 21:06:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Hsq3pWPH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726711AbgHUVG0 (ORCPT ); Fri, 21 Aug 2020 17:06:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726611AbgHUVGX (ORCPT ); Fri, 21 Aug 2020 17:06:23 -0400 Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7ED98C061755 for ; Fri, 21 Aug 2020 14:06:22 -0700 (PDT) Received: by mail-wr1-x444.google.com with SMTP id l2so3129931wrc.7 for ; Fri, 21 Aug 2020 14:06:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=YrfiyumIc+dnkMX191wSa+ug66Vr1S65SLxvTcQAIsw=; b=Hsq3pWPHaQfrcgPceQm4INAskOGb7nIwd/MnxCe6h1mf7DIkDqh1/7UAujZXF7ZDCk qKaihEHvB83PFD08EYDRz31EBY1CUwR3wY296HyuukN74DEaO6776PyWsWafVaTQ6jr2 9QlwLeA6W+Gl6wgM6sp0Ho8RRn2AQkkpzPWjcdNsgHAn3Hqm6GTvf3ncFaA5VKLgFDX6 /u9a0qSZMZF4cvJPOX20PDrCbyTIo7QwqnxyaVCyuJPAj6ON3QUak7pljayhM9y9Huhw bJLewTQoqhRtgpBvl1R0Q0nPfoshE8/oGLYhommw05INiR9w4H5ekXisXChvRddPX5L0 wWAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=YrfiyumIc+dnkMX191wSa+ug66Vr1S65SLxvTcQAIsw=; b=i0y88TZpUKhfjncECFn5ufs9Gnsqt0MOJcobT7FNP1pCusO9a0L8Q9YBfCty7C372K sY34n/UjL7AsJqg/zvYzlJkOZpsUj6Y1oe4GQSAdzMqq8MK4v5kpu7z4N1v6LSOCDZEj sOuoCryDvCM1CxuTf2MVOuYRWNFw7Eg7G1LTNSgCcntVrq25J6gihrc0isx8MLEi4lAD KUepWPmzAZ6kRDcHS8icvRXEHx6fjVAwCR4VKpwmxukYp1NsrRtcJZWUd8FxDFPnZric xvQBp7eFZCj5dLAj01A+OLZgGCOs74KrIR5QCdcs2/3y4UQbRiZpLBx4jCYIl/8yS3yQ 2TvQ== X-Gm-Message-State: AOAM533u3+2W2kBg2cxzQ/ccp0PwjQPTUBNKIfXdA8FNm39aJrQwdEVF KS7qQ4N2srzvOc/rm9zh0lz3tXVLZag= X-Google-Smtp-Source: ABdhPJydgvCbgKKS7H3AyL7tMTK8L0FvBOiXnhHKTgefpeWKYaed3vDLKM4iYRBqtntufioQE89UYA== X-Received: by 2002:adf:df85:: with SMTP id z5mr4142013wrl.267.1598043980692; Fri, 21 Aug 2020 14:06:20 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o3sm6160153wru.64.2020.08.21.14.06.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 14:06:20 -0700 (PDT) Message-Id: In-Reply-To: References: From: "Hariom Verma via GitGitGadget" Date: Fri, 21 Aug 2020 21:06:16 +0000 Subject: [PATCH v3 4/4] ref-filter: using pretty.c logic for trailers Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Hariom Verma , Hariom Verma Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Hariom Verma Now, ref-filter is using pretty.c logic for setting trailer options. New to ref-filter: :key= - only show trailers with specified key. :valueonly[=val] - only show the value part. :separator= - inserted between trailer lines Enhancement to existing options(now can take value and its optional): :only[=val] :unfold[=val] 'val' can be: true, on, yes or false, off, no. Mentored-by: Christian Couder Mentored-by: Heba Waly Signed-off-by: Hariom Verma --- Documentation/git-for-each-ref.txt | 36 +++++++-- ref-filter.c | 35 ++++----- t/t6300-for-each-ref.sh | 115 +++++++++++++++++++++++++---- 3 files changed, 151 insertions(+), 35 deletions(-) diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 2ea71c5f6c..f8e15916bc 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -254,11 +254,37 @@ contents:lines=N:: The first `N` lines of the message. Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1] -are obtained as `trailers` (or by using the historical alias -`contents:trailers`). Non-trailer lines from the trailer block can be omitted -with `trailers:only`. Whitespace-continuations can be removed from trailers so -that each trailer appears on a line by itself with its full content with -`trailers:unfold`. Both can be used together as `trailers:unfold,only`. +are obtained as `trailers[:options]` (or by using the historical alias +`contents:trailers[:options]`). Valid [:option] are: +** 'key=': only show trailers with specified key. Matching is done + case-insensitively and trailing colon is optional. If option is + given multiple times trailer lines matching any of the keys are + shown. This option automatically enables the `only` option so that + non-trailer lines in the trailer block are hidden. If that is not + desired it can be disabled with `only=false`. E.g., + `%(trailers:key=Reviewed-by)` shows trailer lines with key + `Reviewed-by`. +** 'only[=val]': select whether non-trailer lines from the trailer + block should be included. The `only` keyword may optionally be + followed by an equal sign and one of `true`, `on`, `yes` to omit or + `false`, `off`, `no` to show the non-trailer lines. If option is + given without value it is enabled. If given multiple times the last + value is used. +** 'separator=': specify a separator inserted between trailer + lines. When this option is not given each trailer line is + terminated with a line feed character. The string SEP may contain + the literal formatting codes described above. To use comma as + separator one must use `%x2C` as it would otherwise be parsed as + next option. If separator option is given multiple times only the + last one is used. E.g., `%(trailers:key=Ticket,separator=%x2C )` + shows all trailer lines whose key is "Ticket" separated by a comma + and a space. +** 'unfold[=val]': make it behave as if interpret-trailer's `--unfold` + option was given. In same way as to for `only` it can be followed + by an equal sign and explicit value. E.g., + `%(trailers:only,unfold=true)` unfolds and shows all trailer lines. +** 'valueonly[=val]': skip over the key part of the trailer line and only + show the value part. Also this optionally allows explicit value. For sorting purposes, fields with numeric values sort in numeric order (`objectsize`, `authordate`, `committerdate`, `creatordate`, `taggerdate`). diff --git a/ref-filter.c b/ref-filter.c index 8ba0e31915..20f5b829ee 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -67,6 +67,11 @@ struct refname_atom { int lstrip, rstrip; }; +struct ref_trailer_buf { + struct string_list filter_list; + struct strbuf sepbuf; +} ref_trailer_buf; + static struct expand_data { struct object_id oid; enum object_type type; @@ -307,28 +312,24 @@ static int subject_atom_parser(const struct ref_format *format, struct used_atom static int trailers_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg, struct strbuf *err) { - struct string_list params = STRING_LIST_INIT_DUP; - int i; - atom->u.contents.trailer_opts.no_divider = 1; - if (arg) { - string_list_split(¶ms, arg, ',', -1); - for (i = 0; i < params.nr; i++) { - const char *s = params.items[i].string; - if (!strcmp(s, "unfold")) - atom->u.contents.trailer_opts.unfold = 1; - else if (!strcmp(s, "only")) - atom->u.contents.trailer_opts.only_trailers = 1; - else { - strbuf_addf(err, _("unknown %%(trailers) argument: %s"), s); - string_list_clear(¶ms, 0); - return -1; - } + const char *argbuf = xstrfmt("%s)", arg); + const char *err_arg = NULL; + + if (format_set_trailers_options(&atom->u.contents.trailer_opts, + &ref_trailer_buf.filter_list, + &ref_trailer_buf.sepbuf, + &argbuf, &err_arg)) { + if (!err_arg) + strbuf_addf(err, _("expected %%(trailers:key=)")); + else + strbuf_addf(err, _("unknown %%(trailers) argument: %s"), err_arg); + free((char *)err_arg); + return -1; } } atom->u.contents.option = C_TRAILERS; - string_list_clear(¶ms, 0); return 0; } diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index fdf2c442c5..664af8588a 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -786,14 +786,32 @@ test_expect_success '%(trailers:unfold) unfolds trailers' ' test_cmp expect actual ' -test_expect_success '%(trailers:only) shows only "key: value" trailers' ' +test_show_key_value_trailers () { + option="$1" + test_expect_success "%($option) shows only 'key: value' trailers" ' + { + grep -v patch.description expect && + git for-each-ref --format="%($option)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:$option)" refs/heads/master >actual && + test_cmp expect actual + ' +} + +test_show_key_value_trailers 'trailers:only' +test_show_key_value_trailers 'trailers:only=no,only=true' +test_show_key_value_trailers 'trailers:only=yes' + +test_expect_success '%(trailers:only=no) shows all trailers' ' { - grep -v patch.description expect && - git for-each-ref --format="%(trailers:only)" refs/heads/master >actual && + git for-each-ref --format="%(trailers:only=no)" refs/heads/master >actual && test_cmp expect actual && - git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual && + git for-each-ref --format="%(contents:trailers:only=no)" refs/heads/master >actual && test_cmp expect actual ' @@ -812,17 +830,88 @@ test_expect_success '%(trailers:only) and %(trailers:unfold) work together' ' test_cmp actual actual ' -test_expect_success '%(trailers) rejects unknown trailers arguments' ' - # error message cannot be checked under i18n - cat >expect <<-EOF && - fatal: unknown %(trailers) argument: unsupported - EOF - test_must_fail git for-each-ref --format="%(trailers:unsupported)" 2>actual && - test_i18ncmp expect actual && - test_must_fail git for-each-ref --format="%(contents:trailers:unsupported)" 2>actual && - test_i18ncmp expect actual +test_trailer_option() { + title="$1" + option="$2" + expect="$3" + test_expect_success "$title" ' + echo $expect >expect && + git for-each-ref --format="%($option)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:$option)" refs/heads/master >actual && + test_cmp expect actual + ' +} + +test_trailer_option '%(trailers:key=foo) shows that trailer' \ + 'trailers:key=Signed-off-by' 'Signed-off-by: A U Thor \n' +test_trailer_option '%(trailers:key=foo) is case insensitive' \ + 'trailers:key=SiGned-oFf-bY' 'Signed-off-by: A U Thor \n' +test_trailer_option '%(trailers:key=foo:) trailing colon also works' \ + 'trailers:key=Signed-off-by:' 'Signed-off-by: A U Thor \n' +test_trailer_option '%(trailers:key=foo) multiple keys' \ + 'trailers:key=Reviewed-by:,key=Signed-off-by' 'Reviewed-by: A U Thor \nSigned-off-by: A U Thor \n' +test_trailer_option '%(trailers:key=nonexistent) becomes empty' \ + 'trailers:key=Shined-off-by:' '' + +test_expect_success '%(trailers:key=foo) handles multiple lines even if folded' ' + { + grep -v patch.description expect && + git for-each-ref --format="%(trailers:key=Acked-by)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:key=Acked-by)" refs/heads/master >actual && + test_cmp expect actual +' + +test_expect_success '%(trailers:key=foo,unfold) properly unfolds' ' + { + unfold expect && + git for-each-ref --format="%(trailers:key=Signed-Off-by,unfold)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:key=Signed-Off-by,unfold)" refs/heads/master >actual && + test_cmp expect actual ' +test_expect_success 'pretty format %(trailers:key=foo,only=no) also includes nontrailer lines' ' + { + echo "Signed-off-by: A U Thor " && + grep patch.description expect && + git for-each-ref --format="%(trailers:key=Signed-off-by,only=no)" refs/heads/master >actual && + test_cmp expect actual && + git for-each-ref --format="%(contents:trailers:key=Signed-off-by,only=no)" refs/heads/master >actual && + test_cmp expect actual +' + +test_trailer_option '%(trailers:key=foo,valueonly) shows only value' \ + 'trailers:key=Signed-off-by,valueonly' 'A U Thor \n' +test_trailer_option '%(trailers:separator) changes separator' \ + 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' 'Reviewed-by: A U Thor ,Signed-off-by: A U Thor ' + +test_failing_trailer_option () { + title="$1" + option="$2" + error="$3" + test_expect_success "$title" ' + # error message cannot be checked under i18n + echo $error >expect && + test_must_fail git for-each-ref --format="%($option)" refs/heads/master 2>actual && + test_i18ncmp expect actual && + test_must_fail git for-each-ref --format="%(contents:$option)" refs/heads/master 2>actual && + test_i18ncmp expect actual + ' +} + +test_failing_trailer_option '%(trailers:key) without value is error' \ + 'trailers:key' 'fatal: expected %(trailers:key=)' +test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \ + 'trailers:unsupported' 'fatal: unknown %(trailers) argument: unsupported' + test_expect_success 'if arguments, %(contents:trailers) shows error if semicolon is missing' ' cat >expect <<-EOF && fatal: unrecognized %(contents) argument: trailersonly