From patchwork Sun Jan 10 18:26:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Leonardo_M=C3=B6rlein?= X-Patchwork-Id: 1424285 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=irrelefant.net Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=EZDSw6R6; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DDQP82hbGz9sW8 for ; Mon, 11 Jan 2021 05:29:57 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=D6uKYFltifWL5VgORkkj65pwERfpW8RPZJJAQPVaRl8=; b=EZDSw6R6AI2B5aJPDXs7qNDIKZ WYg3w7mdcB3/xLnbu3V7CFLJnHvR5sm7K82a244s7VKk5O6ehzT5if3pNBYpi4OhII35bSwUxxJzU eLQXVcFAbDtpe9CSbwK/s2VJtj/IyUIqZSe1x3/z38IssYuA263mx+BUaVTLVVfsoCYgalJsKPDex a1N2ltHWNnBS3l+MyJVSGFIZzjs5IODm0uQ24ctXMO1topJ/9V3SjnFpDYggEgi8VcI/mrysVOVlD tGeadvLX/nWQQmtk4J3ojn/8kkOMbGluPuMiz46k60D4wGcb71m1HLAROA2Jn8UF9O8LdEDPsup8t NCtxl1FQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kyfQZ-0004D0-9N; Sun, 10 Jan 2021 18:26:59 +0000 Received: from smtprelay07.ispgateway.de ([134.119.228.103]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kyfQV-0004AU-Ms for openwrt-devel@lists.openwrt.org; Sun, 10 Jan 2021 18:26:56 +0000 Received: from [83.135.92.80] (helo=orange.fritz.box) by smtprelay07.ispgateway.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) (envelope-from ) id 1kyfOX-0006k2-84; Sun, 10 Jan 2021 19:24:53 +0100 From: =?utf-8?q?Leonardo_M=C3=B6rlein?= To: openwrt-devel@lists.openwrt.org Subject: [PATCH uci] delta: allow clearing delta path Date: Sun, 10 Jan 2021 19:26:34 +0100 Message-Id: <20210110182634.368461-1-me@irrelefant.net> X-Mailer: git-send-email 2.30.0 MIME-Version: 1.0 X-Df-Sender: bWVAaXJyZWxlZmFudC5uZXQ= X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210110_132655_805641_525F7E51 X-CRM114-Status: GOOD ( 18.85 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Leonardo_M=C3=B6rlein?= Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org The delta path can now be cleared from libuci, lua/uci and the cli. Only the savedir remains in the delta path after clearing. This enables safely committing new changes from scripts without also comitting potentially existing uncommited user changes. This introduces: - the cli option '-x'. - the lua method cur:clear_delta(). - the libuci function uci_clear_delta_path(). - a test case. To safely commit changes from shell scripts, use: local tmp="$(mktemp -d)" uci -P "$tmp" config.section.var=val uci -P "$tmp" -x commit rm -rf "$tmp" Signed-off-by: Leonardo Mörlein --- cli.c | 7 +++- delta.c | 14 ++++++++ lua/uci.c | 10 ++++++ .../cli.options.delta.commit2.result | 4 +++ .../cli.options.delta.commit3.result | 5 +++ tests/shunit2/tests.d/090_cli_options | 33 +++++++++++++++++++ uci.h | 6 ++++ 7 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/shunit2/references/cli.options.delta.commit2.result create mode 100644 tests/shunit2/references/cli.options.delta.commit3.result diff --git a/cli.c b/cli.c index 267437d..cee7baa 100644 --- a/cli.c +++ b/cli.c @@ -167,6 +167,7 @@ static void uci_usage(void) "\t-N don't name unnamed sections\n" "\t-p add a search path for config change files\n" "\t-P add a search path for config change files and use as default\n" + "\t-x clear search path except for default\n" "\t-q quiet mode (don't print error messages)\n" "\t-s force strict mode (stop on parser errors, default)\n" "\t-S disable strict mode\n" @@ -706,7 +707,7 @@ int main(int argc, char **argv) return 1; } - while((c = getopt(argc, argv, "c:d:f:LmnNp:P:sSqX")) != -1) { + while((c = getopt(argc, argv, "c:d:f:LmnNp:P:xsSqX")) != -1) { switch(c) { case 'c': uci_set_confdir(ctx, optarg); @@ -743,6 +744,10 @@ int main(int argc, char **argv) case 'N': ctx->flags &= ~UCI_FLAG_EXPORT_NAME; break; + case 'x': + uci_clear_delta_path(ctx); + flags &= ~CLI_FLAG_NOCOMMIT; + break; case 'p': uci_add_delta_path(ctx, optarg); break; diff --git a/delta.c b/delta.c index d8bd3a6..33a24a3 100644 --- a/delta.c +++ b/delta.c @@ -124,6 +124,20 @@ int uci_set_savedir(struct uci_context *ctx, const char *dir) return 0; } +int uci_clear_delta_path(struct uci_context *ctx) +{ + struct uci_element *e, *tmp; + UCI_HANDLE_ERR(ctx); + + uci_foreach_element_safe(&ctx->delta_path, tmp, e) { + if (strcmp(e->name, ctx->savedir)) { + uci_list_del(&e->list); + uci_free_element(e); + } + } + return 0; +} + int uci_add_delta_path(struct uci_context *ctx, const char *dir) { struct uci_element *e; diff --git a/lua/uci.c b/lua/uci.c index 196a25b..70c2b72 100644 --- a/lua/uci.c +++ b/lua/uci.c @@ -938,6 +938,15 @@ uci_lua_add_delta(lua_State *L) return uci_push_status(L, ctx, false); } +static int +uci_lua_clear_delta(lua_State *L) +{ + struct uci_context *ctx; + ctx = find_context(L, NULL); + uci_clear_delta_path(ctx); + return uci_push_status(L, ctx, false); +} + static int uci_lua_set_savedir(lua_State *L) { @@ -1039,6 +1048,7 @@ static const luaL_Reg uci[] = { { "foreach", uci_lua_foreach }, { "add_history", uci_lua_add_delta }, { "add_delta", uci_lua_add_delta }, + { "clear_delta", uci_lua_clear_delta }, { "get_confdir", uci_lua_get_confdir }, { "set_confdir", uci_lua_set_confdir }, { "get_savedir", uci_lua_get_savedir }, diff --git a/tests/shunit2/references/cli.options.delta.commit2.result b/tests/shunit2/references/cli.options.delta.commit2.result new file mode 100644 index 0000000..5beb9f7 --- /dev/null +++ b/tests/shunit2/references/cli.options.delta.commit2.result @@ -0,0 +1,4 @@ + +config sectype 'sec0' + list li0 '1' + diff --git a/tests/shunit2/references/cli.options.delta.commit3.result b/tests/shunit2/references/cli.options.delta.commit3.result new file mode 100644 index 0000000..3119b6f --- /dev/null +++ b/tests/shunit2/references/cli.options.delta.commit3.result @@ -0,0 +1,5 @@ + +config sectype 'sec0' + list li0 '1' + list li0 '0' + diff --git a/tests/shunit2/tests.d/090_cli_options b/tests/shunit2/tests.d/090_cli_options index 55920a2..0fbec69 100644 --- a/tests/shunit2/tests.d/090_cli_options +++ b/tests/shunit2/tests.d/090_cli_options @@ -44,3 +44,36 @@ delta.sec0.li0+='1'" "$cmdoutput" rm -f "$config_delta" } +test_clear_delta() { + local new_savedir="$TMP_DIR/new_savedir" + local config_delta="$CONFIG_DIR/delta" + local cmdoutput + + # commit normal changes + touch "$config_delta" + $UCI set delta.sec0=sectype + $UCI commit + + # add uncommited changes + $UCI add_list delta.sec0.li0=0 + + # save new changes in "$new_savedir" + mkdir -p "$new_savedir" + touch "$new_savedir/delta" + $UCI -P "$new_savedir" set delta.sec0=sectype + $UCI -P "$new_savedir" add_list delta.sec0.li0=1 + + # only commit changes in $new_savedir but not normal changes + $UCI -P "$new_savedir" -x commit + assertTrue "$?" + assertSameFile "$REF_DIR/cli.options.delta.commit2.result" "$config_delta" + + # do normal commit + $UCI commit + assertTrue "$?" + assertSameFile "$REF_DIR/cli.options.delta.commit3.result" "$config_delta" + + rm -rf "$new_savedir" + rm -f "$config_delta" +} + diff --git a/uci.h b/uci.h index b385e2b..e644d3a 100644 --- a/uci.h +++ b/uci.h @@ -277,6 +277,12 @@ extern int uci_set_confdir(struct uci_context *ctx, const char *dir); */ extern int uci_add_delta_path(struct uci_context *ctx, const char *dir); +/** + * uci_clear_delta_path: remove all paths from the delta path except for savedir + * @ctx: uci context + */ +extern int uci_clear_delta_path(struct uci_context *ctx); + /** * uci_revert: revert all changes to a config item * @ctx: uci context