Browse Source

etcdctlv3: define non-interactive txn format to match interactive input

Fixes #4559
Anthony Romano 9 years ago
parent
commit
4bbbb52892
2 changed files with 27 additions and 14 deletions
  1. 18 7
      etcdctlv3/README.md
  2. 9 7
      etcdctlv3/command/txn_command.go

+ 18 - 7
etcdctlv3/README.md

@@ -129,16 +129,16 @@ OK
 
 
 ### TXN [options]
 ### TXN [options]
 
 
-TXN applies multiple etcd requests as a single atomic transaction. A transaction consists of list of conditions, a list of requests to apply if all the conditions are true, and a list of requests to apply if any condition is false.
+TXN reads multiple etcd requests from standard input and applies them as a single atomic transaction.
+A transaction consists of list of conditions, a list of requests to apply if all the conditions are true, and a list of requests to apply if any condition is false.
 
 
 #### Options
 #### Options
 
 
 - hex -- print out keys and values as hex encoded string
 - hex -- print out keys and values as hex encoded string
 
 
-- interactive -- input transaction with interactive mode
+- interactive -- input transaction with interactive prompting
 
 
 #### Input Format
 #### Input Format
-Interactive mode:
 ```ebnf
 ```ebnf
 <Txn> ::= <CMP>* "\n" <THEN> "\n" <ELSE> "\n"
 <Txn> ::= <CMP>* "\n" <THEN> "\n" <ELSE> "\n"
 <CMP> ::= (<CMPCREATE>|<CMPMOD>|<CMPVAL>|<CMPVER>) "\n"
 <CMP> ::= (<CMPCREATE>|<CMPMOD>|<CMPVAL>|<CMPVER>) "\n"
@@ -156,8 +156,6 @@ Interactive mode:
 <VERSION> ::= "\""[0-9]+"\""
 <VERSION> ::= "\""[0-9]+"\""
 ```
 ```
 
 
-TODO: non-interactive mode
-
 #### Return value
 #### Return value
 
 
 ##### Simple reply
 ##### Simple reply
@@ -178,6 +176,7 @@ The protobuf encoding of the Txn [RPC response][etcdrpc].
 
 
 #### Examples
 #### Examples
 
 
+txn in interactive mode:
 ``` bash
 ``` bash
 ./etcdctl txn -i
 ./etcdctl txn -i
 mod("key1") > "0"
 mod("key1") > "0"
@@ -194,10 +193,22 @@ OK
 OK
 OK
 ```
 ```
 
 
-#### Notes
+txn in non-interactive mode:
+```
+./etcdctl txn <<<'mod("key1") > "0"
+
+put key1 "overwrote-key1"
+
+put key1 "created-key1"
+put key2 "some extra key"
+
+'
+FAILURE
 
 
-TODO: non-interactive mode
+OK
 
 
+OK
+````
 
 
 ### WATCH [options] [key or prefix]
 ### WATCH [options] [key or prefix]
 
 

+ 9 - 7
etcdctlv3/command/txn_command.go

@@ -47,18 +47,14 @@ func txnCommandFunc(cmd *cobra.Command, args []string) {
 		ExitWithError(ExitBadArgs, fmt.Errorf("txn command does not accept argument."))
 		ExitWithError(ExitBadArgs, fmt.Errorf("txn command does not accept argument."))
 	}
 	}
 
 
-	if !txnInteractive {
-		ExitWithError(ExitBadFeature, fmt.Errorf("txn command only supports interactive mode"))
-	}
-
 	reader := bufio.NewReader(os.Stdin)
 	reader := bufio.NewReader(os.Stdin)
 
 
 	txn := mustClientFromCmd(cmd).Txn(context.Background())
 	txn := mustClientFromCmd(cmd).Txn(context.Background())
-	fmt.Println("compares:")
+	promptInteractive("compares:")
 	txn.If(readCompares(reader)...)
 	txn.If(readCompares(reader)...)
-	fmt.Println("success requests (get, put, delete):")
+	promptInteractive("success requests (get, put, delete):")
 	txn.Then(readOps(reader)...)
 	txn.Then(readOps(reader)...)
-	fmt.Println("failure requests (get, put, delete):")
+	promptInteractive("failure requests (get, put, delete):")
 	txn.Else(readOps(reader)...)
 	txn.Else(readOps(reader)...)
 
 
 	resp, err := txn.Commit()
 	resp, err := txn.Commit()
@@ -69,6 +65,12 @@ func txnCommandFunc(cmd *cobra.Command, args []string) {
 	display.Txn(*resp)
 	display.Txn(*resp)
 }
 }
 
 
+func promptInteractive(s string) {
+	if txnInteractive {
+		fmt.Println(s)
+	}
+}
+
 func readCompares(r *bufio.Reader) (cmps []clientv3.Cmp) {
 func readCompares(r *bufio.Reader) (cmps []clientv3.Cmp) {
 	for {
 	for {
 		line, err := r.ReadString('\n')
 		line, err := r.ReadString('\n')