Skip to content

Commit

Permalink
line-in-file :string-match implemented - #85
Browse files Browse the repository at this point in the history
  • Loading branch information
retrogradeorbit committed Jul 3, 2020
1 parent 5c1a128 commit 580b685
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 43 deletions.
91 changes: 63 additions & 28 deletions src/clj/spire/module/line_in_file.clj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
;;
;; (line-in-file :present ...)
;;
(defmethod preflight :present [_ {:keys [path regexp after before match insert-at]}]
(defmethod preflight :present [_ {:keys [path regexp string-match after before match insert-at]}]
(cond
(empty? path)
(assoc failed-result
Expand All @@ -31,6 +31,11 @@
:exit 3
:err "Cannot specify both :after and :before to :present")

(and regexp string-match)
(assoc failed-result
:exit 3
:err "Cannot specify both :regexp and :string-match to :present")

(not (options-match-choices (or match options-match-default)))
(assoc failed-result
:exit 3
Expand All @@ -52,14 +57,15 @@
(apply str))]
(str escaped (utils/string-escape remain))))

(defmethod make-script :present [_ {:keys [path regexp line-num line after before match insert-at]}]
(defmethod make-script :present [_ {:keys [path regexp string-match line-num line after before match insert-at]}]
;;(prn 'make-script :present (some->> line utils/string-escape))
;;(println (some->> line utils/string-escape))
;;(println line)
(facts/on-os
:linux (utils/make-script
"line_in_file_present.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:STRING_MATCH string-match
:FILE (some->> path utils/path-escape)
:LINENUM line-num
:LINE (some->> line utils/string-escape)
Expand All @@ -72,19 +78,20 @@
:all "cat")
:INSERTAT (some->> insert-at name)})
:else (utils/make-script
"line_in_file_present_bsd.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:FILE (some->> path utils/path-escape)
:LINENUM line-num
:LINE (some->> line utils/string-escape)
:SEDLINE (some->> line utils/string-escape utils/string-escape)
:AFTER (some->> after utils/re-pattern-to-sed)
:BEFORE (some->> before utils/re-pattern-to-sed)
:SELECTOR (case (or match options-match-default)
:first "head -1"
:last "tail -1"
:all "cat")
:INSERTAT (some->> insert-at name)})))
"line_in_file_present_bsd.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:STRING_MATCH string-match
:FILE (some->> path utils/path-escape)
:LINENUM line-num
:LINE (some->> line utils/string-escape)
:SEDLINE (some->> line utils/string-escape utils/string-escape)
:AFTER (some->> after utils/re-pattern-to-sed)
:BEFORE (some->> before utils/re-pattern-to-sed)
:SELECTOR (case (or match options-match-default)
:first "head -1"
:last "tail -1"
:all "cat")
:INSERTAT (some->> insert-at name)})))

(defmethod process-result :present
[_ {:keys [path line-num regexp]} {:keys [out err exit] :as result}]
Expand All @@ -106,30 +113,37 @@
;;
;; (line-in-file :absent ...)
;;
(defmethod preflight :absent [_ {:keys [path regexp line-num]}]
(defmethod preflight :absent [_ {:keys [path regexp string-match line-num]}]
(cond
(empty? path)
(assoc failed-result
:exit 4
:err ":path must be specified")

(and regexp string-match)
(assoc failed-result
:exit 3
:err "Cannot specify both :regexp and :string-match to :absent")

(not (or regexp line-num))
(assoc failed-result
:exit 3
:err "must specify :regexp or :line-num")))

(defmethod make-script :absent [_ {:keys [path regexp line-num]}]
(defmethod make-script :absent [_ {:keys [path regexp string-match line-num]}]
(facts/on-os
:linux (utils/make-script
"line_in_file_absent.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:FILE (some->> path utils/path-escape)
:LINENUM line-num})
"line_in_file_absent.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:STRING_MATCH string-match
:FILE (some->> path utils/path-escape)
:LINENUM line-num})
:else (utils/make-script
"line_in_file_absent_bsd.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:FILE (some->> path utils/path-escape)
:LINENUM line-num})))
"line_in_file_absent_bsd.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:STRING_MATCH string-match
:FILE (some->> path utils/path-escape)
:LINENUM line-num})))

(defmethod process-result :absent
[_ {:keys [path line-num regexp]} {:keys [out err exit] :as result}]
Expand All @@ -152,7 +166,7 @@
;;
;; (line-in-file :get ...)
;;
(defmethod preflight :get [_ {:keys [path line-num regexp match]}]
(defmethod preflight :get [_ {:keys [path line-num regexp string-match match]}]
(cond
(empty? path)
(assoc failed-result
Expand All @@ -164,6 +178,11 @@
:exit 3
:err "Cannot specify both :line-num and :regexp to :get")

(and regexp string-match)
(assoc failed-result
:exit 3
:err "Cannot specify both :regexp and :string-match to :present")

(not (options-match-choices (or match options-match-default)))
(assoc failed-result
:exit 3
Expand All @@ -175,10 +194,11 @@
:exit 2
:err "No line number 0 in file. File line numbers are 1 offset.")))

(defmethod make-script :get [_ {:keys [path line-num regexp match]}]
(defmethod make-script :get [_ {:keys [path line-num regexp string-match match]}]
(utils/make-script
"line_in_file_get.sh"
{:REGEX (some->> regexp utils/re-pattern-to-sed)
:STRING_MATCH string-match
:FILE (some->> path utils/path-escape)
:LINENUM line-num
:SELECTOR (case (or match options-match-default)
Expand Down Expand Up @@ -253,6 +273,9 @@
`:regexp` The regular expression to look for in every line of the
file. The line that matches will be replaced.
`:string-match` A string to look for in every line of the file. The
line that contains a match for the string will be replaced.
`:line-num` Specify the line to match by line number instead of
regular expression.
Expand Down Expand Up @@ -310,14 +333,26 @@
"The regular expression to look for in every line of the file"
"In `:present` mode, the pattern to replace if found. Replaces the last occurance of that pattern."
"In `:absent` mode, the pattern of lines to remove. All occurances of that line will be removed."
"In `:get` mode, the pattern of lines to bre returned. All occurances that match will be returned."
"In `:get` mode, the pattern of lines to be returned. All occurances that match will be returned."
"If the regular expression is not matched, the line will be added to the file. `:before` and `:after` will allow you to control where in the file the line is inserted."
"If `:before` or `:after` is not used then ensure the regular expression matches both the initial state of the line as well as its state after replacement to ensure idempotence."
"NOTE: The regular expression is passed as a clojure regex literal or a Java regex but is converted into a sed regular expression for operation on the host. As such the semantics of the regular expression are those of the sed implementation on the host and not of Java's Pattern class."
]
:aliases [:regex]
:type :regexp}]

[:string-match
:description
[
"A string to look for in every line of the file."
"In `:present` mode, the line that contains a match for the string will be replaced."
"In `:absent` mode, the line that contains a match for the string will be removed."
"In `:get` mode, the line that contains a match for the string will be returned."
"The same rules `:before` and `:after` rules for `:regexp` apply."
]
:required false
:type :string]

[:line
{
:description ["The contents of the line to insert into the file"]
Expand Down
11 changes: 8 additions & 3 deletions src/clj/spire/module/line_in_file_absent.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ if [ "$LINENUM" ]; then
exit -1
fi

# :absent by regexp
if [ "$REGEX" ]; then
LINENUM=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
# :absent by regexp or string-match
if [ "$REGEX" ] || [ "$STRING_MATCH" ]; then
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
else
LINENUMS=$(grep -n -F "${STRING_MATCH}" "$FILE" | cut -d: -f1 | $SELECTOR)
fi

if [ "$LINENUM" ]; then
sed -i "${LINENUM}d${LINE}" "$FILE"
exit -1
Expand Down
11 changes: 8 additions & 3 deletions src/clj/spire/module/line_in_file_absent_bsd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ if [ "$LINENUM" ]; then
exit -1
fi

# :absent by regexp
if [ "$REGEX" ]; then
LINENUM=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
# :absent by regexp or string-match
if [ "$REGEX" ] || [ "$STRING_MATCH" ]; then
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
else
LINENUMS=$(grep -n -F "${STRING_MATCH}" "$FILE" | cut -d: -f1 | $SELECTOR)
fi

if [ "$LINENUM" ]; then
sed -i "" "${LINENUM}d${LINE}" "$FILE"
exit -1
Expand Down
11 changes: 8 additions & 3 deletions src/clj/spire/module/line_in_file_get.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ if [ "$LINENUM" ]; then
exit 0
fi

# :get by regexp
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
# :get by regexp or string-match
if [ "$REGEX" ] || [ "$STRING_MATCH" ]; then
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
else
LINENUMS=$(grep -n -F "${STRING_MATCH}" "$FILE" | cut -d: -f1 | $SELECTOR)
fi

if [ "$LINENUMS" ]; then
SED_LP_CMD=$(echo $LINENUMS | sed 's/ /p;/g' | sed 's/$/p;/g')
LINECONTENTS=$(sed -n "$SED_LP_CMD" "$FILE")
Expand Down
10 changes: 7 additions & 3 deletions src/clj/spire/module/line_in_file_present.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ if [ "$LINENUM" ]; then
fi
fi

# :present by regexp
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
# :present by regexp or string-match
if [ "$REGEX" ] || [ "$STRING_MATCH" ]; then
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
else
LINENUMS=$(grep -n -F "${STRING_MATCH}" "$FILE" | cut -d: -f1 | $SELECTOR)
fi

if [ "$LINENUMS" ]; then
REVERSE=""
Expand Down
10 changes: 7 additions & 3 deletions src/clj/spire/module/line_in_file_present_bsd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ ${SEDLINE}\\
fi
fi

# :present by regexp
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
# :present by regexp or string-match
if [ "$REGEX" ] || [ "$STRING_MATCH" ]; then
if [ "$REGEX" ]; then
LINENUMS=$(sed -n "${REGEX}=" "$FILE" | $SELECTOR)
else
LINENUMS=$(grep -n -F "${STRING_MATCH}" "$FILE" | cut -d: -f1 | $SELECTOR)
fi

if [ "$LINENUMS" ]; then
REVERSE=""
Expand Down

0 comments on commit 580b685

Please sign in to comment.