mirror of https://github.com/databricks/cli.git
merge
This commit is contained in:
commit
bd231012d1
|
@ -10,19 +10,65 @@ on:
|
|||
jobs:
|
||||
publish-to-winget-pkgs:
|
||||
runs-on:
|
||||
group: databricks-protected-runner-group
|
||||
labels: windows-server-latest
|
||||
group: databricks-deco-testing-runner-group
|
||||
labels: ubuntu-latest-deco
|
||||
|
||||
environment: release
|
||||
|
||||
steps:
|
||||
- uses: vedantmgoyal2009/winget-releaser@93fd8b606a1672ec3e5c6c3bb19426be68d1a8b0 # v2
|
||||
with:
|
||||
identifier: Databricks.DatabricksCLI
|
||||
installers-regex: 'windows_.*-signed\.zip$' # Only signed Windows releases
|
||||
token: ${{ secrets.ENG_DEV_ECOSYSTEM_BOT_TOKEN }}
|
||||
fork-user: eng-dev-ecosystem-bot
|
||||
- name: Checkout repository and submodules
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
# Use the tag from the input, or the ref name if the input is not provided.
|
||||
# The ref name is equal to the tag name when this workflow is triggered by the "sign-cli" command.
|
||||
release-tag: ${{ inputs.tag || github.ref_name }}
|
||||
# When updating the version of komac, make sure to update the checksum in the next step.
|
||||
# Find both at https://github.com/russellbanks/Komac/releases.
|
||||
- name: Download komac binary
|
||||
run: |
|
||||
curl -s -L -o $RUNNER_TEMP/komac-2.9.0-x86_64-unknown-linux-gnu.tar.gz https://github.com/russellbanks/Komac/releases/download/v2.9.0/komac-2.9.0-x86_64-unknown-linux-gnu.tar.gz
|
||||
|
||||
- name: Verify komac binary
|
||||
run: |
|
||||
echo "d07a12831ad5418fee715488542a98ce3c0e591d05c850dd149fe78432be8c4c $RUNNER_TEMP/komac-2.9.0-x86_64-unknown-linux-gnu.tar.gz" | sha256sum -c -
|
||||
|
||||
- name: Untar komac binary to temporary path
|
||||
run: |
|
||||
mkdir -p $RUNNER_TEMP/komac
|
||||
tar -xzf $RUNNER_TEMP/komac-2.9.0-x86_64-unknown-linux-gnu.tar.gz -C $RUNNER_TEMP/komac
|
||||
|
||||
- name: Add komac to PATH
|
||||
run: echo "$RUNNER_TEMP/komac" >> $GITHUB_PATH
|
||||
|
||||
- name: Confirm komac version
|
||||
run: komac --version
|
||||
|
||||
# Use the tag from the input, or the ref name if the input is not provided.
|
||||
# The ref name is equal to the tag name when this workflow is triggered by the "sign-cli" command.
|
||||
- name: Strip "v" prefix from version
|
||||
id: strip_version
|
||||
run: echo "version=$(echo ${{ inputs.tag || github.ref_name }} | sed 's/^v//')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Get URLs of signed Windows binaries
|
||||
id: get_windows_urls
|
||||
run: |
|
||||
urls=$(
|
||||
gh api https://api.github.com/repos/databricks/cli/releases/tags/${{ inputs.tag || github.ref_name }} | \
|
||||
jq -r .assets[].browser_download_url | \
|
||||
grep -E '_windows_.*-signed\.zip$' | \
|
||||
tr '\n' ' '
|
||||
)
|
||||
if [ -z "$urls" ]; then
|
||||
echo "No signed Windows binaries found" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "urls=$urls" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Publish to Winget
|
||||
run: |
|
||||
komac update Databricks.DatabricksCLI \
|
||||
--version ${{ steps.strip_version.outputs.version }} \
|
||||
--submit \
|
||||
--urls ${{ steps.get_windows_urls.outputs.urls }} \
|
||||
env:
|
||||
KOMAC_FORK_OWNER: eng-dev-ecosystem-bot
|
||||
GITHUB_TOKEN: ${{ secrets.ENG_DEV_ECOSYSTEM_BOT_TOKEN }}
|
||||
|
|
|
@ -60,12 +60,6 @@ jobs:
|
|||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@887a942a15af3a7626099df99e897a18d9e5ab3a # v5.1.0
|
||||
|
||||
- name: Run ruff
|
||||
uses: astral-sh/ruff-action@31a518504640beb4897d0b9f9e50a2a9196e75ba # v3.0.1
|
||||
with:
|
||||
version: "0.9.1"
|
||||
args: "format --check"
|
||||
|
||||
- name: Set go env
|
||||
run: |
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
|
@ -80,7 +74,7 @@ jobs:
|
|||
- name: Run tests with coverage
|
||||
run: make cover
|
||||
|
||||
golangci:
|
||||
linters:
|
||||
needs: cleanups
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -105,6 +99,11 @@ jobs:
|
|||
with:
|
||||
version: v1.63.4
|
||||
args: --timeout=15m
|
||||
- name: Run ruff
|
||||
uses: astral-sh/ruff-action@31a518504640beb4897d0b9f9e50a2a9196e75ba # v3.0.1
|
||||
with:
|
||||
version: "0.9.1"
|
||||
args: "format --check"
|
||||
|
||||
validate-bundle-schema:
|
||||
needs: cleanups
|
||||
|
|
4
NOTICE
4
NOTICE
|
@ -105,3 +105,7 @@ License - https://github.com/wI2L/jsondiff/blob/master/LICENSE
|
|||
https://github.com/hexops/gotextdiff
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
License - https://github.com/hexops/gotextdiff/blob/main/LICENSE
|
||||
|
||||
https://github.com/BurntSushi/toml
|
||||
Copyright (c) 2013 TOML authors
|
||||
https://github.com/BurntSushi/toml/blob/master/COPYING
|
||||
|
|
|
@ -17,3 +17,5 @@ For more complex tests one can also use:
|
|||
- `errcode` helper: if the command fails with non-zero code, it appends `Exit code: N` to the output but returns success to caller (bash), allowing continuation of script.
|
||||
- `trace` helper: prints the arguments before executing the command.
|
||||
- custom output files: redirect output to custom file (it must start with `out`), e.g. `$CLI bundle validate > out.txt 2> out.error.txt`.
|
||||
|
||||
See [selftest](./selftest) for a toy test.
|
||||
|
|
|
@ -66,12 +66,7 @@ func TestInprocessMode(t *testing.T) {
|
|||
if InprocessMode {
|
||||
t.Skip("Already tested by TestAccept")
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
// - catalogs A catalog is the first layer of Unity Catalog’s three-level namespace.
|
||||
// + catalogs A catalog is the first layer of Unity Catalog<6F>s three-level namespace.
|
||||
t.Skip("Fails on CI on unicode characters")
|
||||
}
|
||||
require.NotZero(t, testAccept(t, true, "help"))
|
||||
require.Equal(t, 1, testAccept(t, true, "selftest"))
|
||||
}
|
||||
|
||||
func testAccept(t *testing.T, InprocessMode bool, singleTest string) int {
|
||||
|
@ -187,6 +182,13 @@ func getTests(t *testing.T) []string {
|
|||
}
|
||||
|
||||
func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsContext) {
|
||||
config, configPath := LoadConfig(t, dir)
|
||||
|
||||
isEnabled, isPresent := config.GOOS[runtime.GOOS]
|
||||
if isPresent && !isEnabled {
|
||||
t.Skipf("Disabled via GOOS.%s setting in %s", runtime.GOOS, configPath)
|
||||
}
|
||||
|
||||
var tmpDir string
|
||||
var err error
|
||||
if KeepTmp {
|
||||
|
@ -200,6 +202,7 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
|
|||
}
|
||||
|
||||
repls.SetPathWithParents(tmpDir, "$TMPDIR")
|
||||
repls.Repls = append(repls.Repls, config.Repls...)
|
||||
|
||||
scriptContents := readMergedScriptContents(t, dir)
|
||||
testutil.WriteFile(t, filepath.Join(tmpDir, EntryPointScript), scriptContents)
|
||||
|
@ -250,9 +253,11 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
|
|||
server.WriteRequestsToDisk(outRequestsPath)
|
||||
}
|
||||
|
||||
printedRepls := false
|
||||
|
||||
// Compare expected outputs
|
||||
for relPath := range outputs {
|
||||
doComparison(t, repls, dir, tmpDir, relPath)
|
||||
doComparison(t, repls, dir, tmpDir, relPath, &printedRepls)
|
||||
}
|
||||
|
||||
// Make sure there are not unaccounted for new files
|
||||
|
@ -267,12 +272,12 @@ func runTest(t *testing.T, dir, coverDir string, repls testdiff.ReplacementsCont
|
|||
if strings.HasPrefix(relPath, "out") {
|
||||
// We have a new file starting with "out"
|
||||
// Show the contents & support overwrite mode for it:
|
||||
doComparison(t, repls, dir, tmpDir, relPath)
|
||||
doComparison(t, repls, dir, tmpDir, relPath, &printedRepls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doComparison(t *testing.T, repls testdiff.ReplacementsContext, dirRef, dirNew, relPath string) {
|
||||
func doComparison(t *testing.T, repls testdiff.ReplacementsContext, dirRef, dirNew, relPath string, printedRepls *bool) {
|
||||
pathRef := filepath.Join(dirRef, relPath)
|
||||
pathNew := filepath.Join(dirNew, relPath)
|
||||
bufRef, okRef := readIfExists(t, pathRef)
|
||||
|
@ -317,6 +322,15 @@ func doComparison(t *testing.T, repls testdiff.ReplacementsContext, dirRef, dirN
|
|||
t.Logf("Overwriting existing output file: %s", relPath)
|
||||
testutil.WriteFile(t, pathRef, valueNew)
|
||||
}
|
||||
|
||||
if !equal && printedRepls != nil && !*printedRepls {
|
||||
*printedRepls = true
|
||||
var items []string
|
||||
for _, item := range repls.Repls {
|
||||
items = append(items, fmt.Sprintf("REPL %s => %s", item.Old, item.New))
|
||||
}
|
||||
t.Log("Available replacements:\n" + strings.Join(items, "\n"))
|
||||
}
|
||||
}
|
||||
|
||||
// Returns combined script.prepare (root) + script.prepare (parent) + ... + script + ... + script.cleanup (parent) + ...
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
bundle:
|
||||
name: git-permerror
|
|
@ -0,0 +1,78 @@
|
|||
=== No permission to access .git. Badness: inferred flag is set to true even though we did not infer branch. bundle_root_path is not correct in subdir case.
|
||||
|
||||
>>> chmod 000 .git
|
||||
|
||||
>>> $CLI bundle validate
|
||||
Error: unable to load repository specific gitconfig: open config: permission denied
|
||||
|
||||
Name: git-permerror
|
||||
Target: default
|
||||
Workspace:
|
||||
User: $USERNAME
|
||||
Path: /Workspace/Users/$USERNAME/.bundle/git-permerror/default
|
||||
|
||||
Found 1 error
|
||||
|
||||
Exit code: 1
|
||||
|
||||
>>> $CLI bundle validate -o json
|
||||
Error: unable to load repository specific gitconfig: open config: permission denied
|
||||
|
||||
|
||||
Exit code: 1
|
||||
{
|
||||
"bundle_root_path": ".",
|
||||
"inferred": true
|
||||
}
|
||||
|
||||
>>> withdir subdir/a/b $CLI bundle validate -o json
|
||||
Error: unable to load repository specific gitconfig: open config: permission denied
|
||||
|
||||
|
||||
Exit code: 1
|
||||
{
|
||||
"bundle_root_path": ".",
|
||||
"inferred": true
|
||||
}
|
||||
|
||||
|
||||
=== No permissions to read .git/HEAD. Badness: warning is not shown. inferred is incorrectly set to true. bundle_root_path is not correct in subdir case.
|
||||
|
||||
>>> chmod 000 .git/HEAD
|
||||
|
||||
>>> $CLI bundle validate -o json
|
||||
{
|
||||
"bundle_root_path": ".",
|
||||
"inferred": true
|
||||
}
|
||||
|
||||
>>> withdir subdir/a/b $CLI bundle validate -o json
|
||||
{
|
||||
"bundle_root_path": ".",
|
||||
"inferred": true
|
||||
}
|
||||
|
||||
|
||||
=== No permissions to read .git/config. Badness: inferred is incorretly set to true. bundle_root_path is not correct is subdir case.
|
||||
|
||||
>>> chmod 000 .git/config
|
||||
|
||||
>>> $CLI bundle validate -o json
|
||||
Error: unable to load repository specific gitconfig: open config: permission denied
|
||||
|
||||
|
||||
Exit code: 1
|
||||
{
|
||||
"bundle_root_path": ".",
|
||||
"inferred": true
|
||||
}
|
||||
|
||||
>>> withdir subdir/a/b $CLI bundle validate -o json
|
||||
Error: unable to load repository specific gitconfig: open config: permission denied
|
||||
|
||||
|
||||
Exit code: 1
|
||||
{
|
||||
"bundle_root_path": ".",
|
||||
"inferred": true
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
mkdir myrepo
|
||||
cd myrepo
|
||||
cp ../databricks.yml .
|
||||
git-repo-init
|
||||
mkdir -p subdir/a/b
|
||||
|
||||
printf "=== No permission to access .git. Badness: inferred flag is set to true even though we did not infer branch. bundle_root_path is not correct in subdir case.\n"
|
||||
trace chmod 000 .git
|
||||
errcode trace $CLI bundle validate
|
||||
errcode trace $CLI bundle validate -o json | jq .bundle.git
|
||||
errcode trace withdir subdir/a/b $CLI bundle validate -o json | jq .bundle.git
|
||||
|
||||
printf "\n\n=== No permissions to read .git/HEAD. Badness: warning is not shown. inferred is incorrectly set to true. bundle_root_path is not correct in subdir case.\n"
|
||||
chmod 700 .git
|
||||
trace chmod 000 .git/HEAD
|
||||
errcode trace $CLI bundle validate -o json | jq .bundle.git
|
||||
errcode trace withdir subdir/a/b $CLI bundle validate -o json | jq .bundle.git
|
||||
|
||||
printf "\n\n=== No permissions to read .git/config. Badness: inferred is incorretly set to true. bundle_root_path is not correct is subdir case.\n"
|
||||
chmod 666 .git/HEAD
|
||||
trace chmod 000 .git/config
|
||||
errcode trace $CLI bundle validate -o json | jq .bundle.git
|
||||
errcode trace withdir subdir/a/b $CLI bundle validate -o json | jq .bundle.git
|
||||
|
||||
rm -fr .git
|
|
@ -0,0 +1,5 @@
|
|||
Badness = "Warning logs not shown; inferred flag is set to true incorrect; bundle_root_path is not correct"
|
||||
|
||||
[GOOS]
|
||||
# This test relies on chmod which does not work on Windows
|
||||
windows = false
|
|
@ -0,0 +1,104 @@
|
|||
package acceptance_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/databricks/cli/libs/testdiff"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const configFilename = "test.toml"
|
||||
|
||||
var (
|
||||
configCache map[string]TestConfig
|
||||
configMutex sync.Mutex
|
||||
)
|
||||
|
||||
type TestConfig struct {
|
||||
// Place to describe what's wrong with this test. Does not affect how the test is run.
|
||||
Badness string
|
||||
|
||||
// Which OSes the test is enabled on. Each string is compared against runtime.GOOS.
|
||||
// If absent, default to true.
|
||||
GOOS map[string]bool
|
||||
|
||||
// List of additional replacements to apply on this test.
|
||||
// Old is a regexp, New is a replacement expression.
|
||||
Repls []testdiff.Replacement
|
||||
}
|
||||
|
||||
// FindConfig finds the closest config file.
|
||||
func FindConfig(t *testing.T, dir string) (string, bool) {
|
||||
shared := false
|
||||
for {
|
||||
path := filepath.Join(dir, configFilename)
|
||||
_, err := os.Stat(path)
|
||||
|
||||
if err == nil {
|
||||
return path, shared
|
||||
}
|
||||
|
||||
shared = true
|
||||
|
||||
if dir == "" || dir == "." {
|
||||
break
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
dir = filepath.Dir(dir)
|
||||
continue
|
||||
}
|
||||
|
||||
t.Fatalf("Error while reading %s: %s", path, err)
|
||||
}
|
||||
|
||||
t.Fatal("Config not found: " + configFilename)
|
||||
return "", shared
|
||||
}
|
||||
|
||||
// LoadConfig loads the config file. Non-leaf configs are cached.
|
||||
func LoadConfig(t *testing.T, dir string) (TestConfig, string) {
|
||||
path, leafConfig := FindConfig(t, dir)
|
||||
|
||||
if leafConfig {
|
||||
return DoLoadConfig(t, path), path
|
||||
}
|
||||
|
||||
configMutex.Lock()
|
||||
defer configMutex.Unlock()
|
||||
|
||||
if configCache == nil {
|
||||
configCache = make(map[string]TestConfig)
|
||||
}
|
||||
|
||||
result, ok := configCache[path]
|
||||
if ok {
|
||||
return result, path
|
||||
}
|
||||
|
||||
result = DoLoadConfig(t, path)
|
||||
configCache[path] = result
|
||||
return result, path
|
||||
}
|
||||
|
||||
func DoLoadConfig(t *testing.T, path string) TestConfig {
|
||||
bytes, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read config: %s", err)
|
||||
}
|
||||
|
||||
var config TestConfig
|
||||
meta, err := toml.Decode(string(bytes), &config)
|
||||
require.NoError(t, err)
|
||||
|
||||
keys := meta.Undecoded()
|
||||
if len(keys) > 0 {
|
||||
t.Fatalf("Undecoded keys in %s: %#v", path, keys)
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
|
@ -47,3 +47,14 @@ title() {
|
|||
local label="$1"
|
||||
printf "\n=== %s" "$label"
|
||||
}
|
||||
|
||||
withdir() {
|
||||
local dir="$1"
|
||||
shift
|
||||
local orig_dir="$(pwd)"
|
||||
cd "$dir" || return $?
|
||||
"$@"
|
||||
local exit_code=$?
|
||||
cd "$orig_dir" || return $?
|
||||
return $exit_code
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
HELLO
|
|
@ -0,0 +1,35 @@
|
|||
=== Capturing STDERR
|
||||
>>> python3 -c import sys; sys.stderr.write("STDERR\n")
|
||||
STDERR
|
||||
|
||||
=== Capturing STDOUT
|
||||
>>> python3 -c import sys; sys.stderr.write("STDOUT\n")
|
||||
STDOUT
|
||||
|
||||
=== Capturing exit code
|
||||
>>> errcode python3 -c raise SystemExit(5)
|
||||
|
||||
Exit code: 5
|
||||
|
||||
=== Capturing exit code (alt)
|
||||
>>> python3 -c raise SystemExit(7)
|
||||
|
||||
Exit code: 7
|
||||
|
||||
=== Capturing pwd
|
||||
>>> python3 -c import os; print(os.getcwd())
|
||||
$TMPDIR
|
||||
|
||||
=== Capturing subdir
|
||||
>>> mkdir -p subdir/a/b/c
|
||||
|
||||
>>> withdir subdir/a/b/c python3 -c import os; print(os.getcwd())
|
||||
$TMPDIR/subdir/a/b/c
|
||||
|
||||
=== Custom output files - everything starting with out is captured and compared
|
||||
>>> echo HELLO
|
||||
|
||||
=== Custom regex can be specified in [[Repl]] section
|
||||
1234
|
||||
CUSTOM_NUMBER_REGEX
|
||||
123456
|
|
@ -0,0 +1,26 @@
|
|||
printf "=== Capturing STDERR"
|
||||
trace python3 -c 'import sys; sys.stderr.write("STDERR\n")'
|
||||
|
||||
printf "\n=== Capturing STDOUT"
|
||||
trace python3 -c 'import sys; sys.stderr.write("STDOUT\n")'
|
||||
|
||||
printf "\n=== Capturing exit code"
|
||||
trace errcode python3 -c 'raise SystemExit(5)'
|
||||
|
||||
printf "\n=== Capturing exit code (alt)"
|
||||
errcode trace python3 -c 'raise SystemExit(7)'
|
||||
|
||||
printf "\n=== Capturing pwd"
|
||||
trace python3 -c 'import os; print(os.getcwd())'
|
||||
|
||||
printf "\n=== Capturing subdir"
|
||||
trace mkdir -p subdir/a/b/c
|
||||
trace withdir subdir/a/b/c python3 -c 'import os; print(os.getcwd())'
|
||||
|
||||
printf "\n=== Custom output files - everything starting with out is captured and compared"
|
||||
trace echo HELLO > out.hello.txt
|
||||
|
||||
printf "\n=== Custom regex can be specified in [[Repl]] section\n"
|
||||
echo 1234
|
||||
echo 12345
|
||||
echo 123456
|
|
@ -0,0 +1,20 @@
|
|||
# Badness = "Brief description of what's wrong with the test output, if anything"
|
||||
|
||||
#[GOOS]
|
||||
# Disable on Windows
|
||||
#windows = false
|
||||
|
||||
# Disable on Mac
|
||||
#mac = false
|
||||
|
||||
# Disable on Linux
|
||||
#linux = false
|
||||
|
||||
[[Repls]]
|
||||
Old = '\b[0-9]{5}\b'
|
||||
New = "CUSTOM_NUMBER_REGEX"
|
||||
|
||||
[[Repls]]
|
||||
# Fix path with reverse slashes in the output for Windows.
|
||||
Old = '\$TMPDIR\\subdir\\a\\b\\c'
|
||||
New = '$$TMPDIR/subdir/a/b/c'
|
|
@ -0,0 +1,2 @@
|
|||
# If test directory nor any of its parents do not have test.toml then this file serves as fallback configuration.
|
||||
# The configurations are not merged across parents; the closest one is used fully.
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.23
|
|||
toolchain go1.23.4
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0 // MIT
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // MIT
|
||||
github.com/briandowns/spinner v1.23.1 // Apache 2.0
|
||||
github.com/databricks/databricks-sdk-go v0.55.0 // Apache 2.0
|
||||
|
|
|
@ -8,6 +8,8 @@ cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1h
|
|||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4=
|
||||
github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
|
|
|
@ -79,7 +79,11 @@ func (r *ReplacementsContext) Set(old, new string) {
|
|||
if err == nil {
|
||||
encodedOld, err := json.Marshal(old)
|
||||
if err == nil {
|
||||
r.appendLiteral(trimQuotes(string(encodedOld)), trimQuotes(string(encodedNew)))
|
||||
encodedStrNew := trimQuotes(string(encodedNew))
|
||||
encodedStrOld := trimQuotes(string(encodedOld))
|
||||
if encodedStrNew != new || encodedStrOld != old {
|
||||
r.appendLiteral(encodedStrOld, encodedStrNew)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue