0

I'm attempting to substitute a value in package.json by using sed to find a static value and replace it with a dynamic bash variable . However, Circle CI is reporting this is wrong but it looks good to me.

Circle CI

GETTING CURRENT DEPLOYMENT INFORMATION...
sed: bad option in substitution expression
sed: bad option in substitution expression

Dockerfile

COPY --from=build /home/node/app/ .

## Get current GIT BRANCH and COMMIT HASH and provide to image    
RUN mkdir /root/.gitinfo
COPY ./.git/HEAD /root/.gitinfo/.
COPY ./.git/config /root/.gitinfo/.
RUN echo "GETTING CURRENT DEPLOYMENT INFORMATION..."; \
    cat /root/.gitinfo/config | grep url | head -1 | xargs > /GIT_VERSION_URL.txt; \
    cat /root/.gitinfo/HEAD | head -1 | xargs > /GIT_VERSION_REF.txt; \
    FILE_LINE=$(cat /GIT_VERSION_URL.txt | head -1 | xargs | tr -d '\n'); \
    sed -i "s/DOCKER_WILL_PROVIDE_VALUE_A1/$FILE_LINE/g" /home/node/app/package.json; \
    FILE_LINE=$(cat /GIT_VERSION_REF.txt | head -1 | xargs | tr -d '\n'); \
    sed -i "s/DOCKER_WILL_PROVIDE_VALUE_A2/$FILE_LINE/g" /home/node/app/package.json; \
    cat /GIT*; \
    rm -rf /root/.gitinfo;
## END

package.json

...
  "git": {
    "GIT_URL": "DOCKER_WILL_PROVIDE_VALUE_A1",
    "GIT_REF": "DOCKER_WILL_PROVIDE_VALUE_A2"
  },
...

Why won't sed do the replacement?

EDIT: I do not believe this is a duplicate. What makes this situation unique is that I'm trying to run this inside Docker and doing a dynamic variable replacement in the replace regex. I am NOT using "/" in the regex so this Sed error : bad option in substitution expression is not similar to my problem. Thanks!

EDIT 2: I actually am using "/" in the GIT URL. As Charles pointed out below, this is the likely culprit.

Dan
  • 2,323
  • 1
  • 21
  • 30
  • 1
    Even if it's not a duplicate of *that specific* question (not asserting either way, haven't checked yet), it's certainly a duplicate in general. We get quite a lot of this particular bug. Put `set -x;` at the front of your `RUN`, and edit the `sed` operation into the question. It's basically certain that there's a `/` character in your replacement value, and everything past that `/` is treated by `sed` as an option to the regex. – Charles Duffy Sep 17 '18 at 23:07
  • (Also, using `sed` to modify structured content -- JSON, XML, HTML, etc -- is inherently bug-prone; much, *much* better practice is to use structure-aware tools. In the JSON case, this means `jq`, as in something like: `jq -v url="$FILE_LINE" -v ref="$FILE_LINE" '.git.GIT_URL=$url | .git.GIT_REF=$ref' out.json`). – Charles Duffy Sep 17 '18 at 23:10
  • Charles, you gave me a great clue.. it's likely the var does have a / inside of it.. thanks! – Dan Sep 17 '18 at 23:10
  • ...anyhow, if you're asserting that there's no `/` in the value, the `set -x` log will provide evidence for that. – Charles Duffy Sep 17 '18 at 23:10
  • 1
    Right -- that's the rub here; variable substitution (replacing `$FILE_LINE` with an actual value) is done by the shell *before* `sed` is started, so `sed` can't distinguish what was present in the original code from what was the result of a parameter expansion / variable substitution. – Charles Duffy Sep 17 '18 at 23:11
  • jq won't work easily here but I'm replacing a value that for sure won't have any quotes in it I believe this will work nicely and be valid json. no, I do blieve it has a "/" in the GIT URL so that's likely the issue. I was thinking that Docker was doing something funky and I wasn't testing with strings that had a / in it locally... thanks again! – Dan Sep 17 '18 at 23:12
  • (Aside to anyone reading this: I was thinking of `awk` usage when writing my suggested `jq` line above; it should be `jq --arg url="$foo"`, not `jq -v ...`). – Charles Duffy Sep 18 '18 at 01:01

0 Answers0