Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift support audit #231

Open
wants to merge 102 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
3ea86ce
cocoapods-audit
barv-jfrog Sep 17, 2024
606169e
fixes
barv-jfrog Sep 18, 2024
fc6df17
cocoapods-audit
barv-jfrog Sep 29, 2024
243dfcd
cocoapods-audit
barv-jfrog Sep 29, 2024
a181880
cocoapods-audit
barv-jfrog Sep 30, 2024
08e3bd5
cocoapods-audit
barv-jfrog Sep 30, 2024
895ccfa
cocoapods-audit
barv-jfrog Sep 30, 2024
5f51f0a
cocoapods-audit
barv-jfrog Sep 30, 2024
4763b35
cocoapods-audit
barv-jfrog Oct 1, 2024
17d8b80
cocoapods-audit
barv-jfrog Oct 1, 2024
9db6be2
Merge branch 'dev' into cocoapods-audit
barv-jfrog Oct 6, 2024
de4c5fd
cocoapods-audit
srmish-jfrog Oct 31, 2024
26481ec
cocoapods-audit
barv-jfrog Nov 4, 2024
775f8e0
cocoapods-audit
barv-jfrog Nov 4, 2024
8c56a03
cocoapods-audit
barv-jfrog Nov 4, 2024
a9aebdb
cocoapods-audit
barv-jfrog Nov 4, 2024
93fdf5c
cocoapods-audit
barv-jfrog Nov 4, 2024
4cf116c
cocoapods-audit
barv-jfrog Nov 4, 2024
9d47eae
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-security int…
barv-jfrog Nov 6, 2024
56d08f9
cocoapods-audit
barv-jfrog Nov 6, 2024
1fad622
Merge branch 'dev' into cocoapods-audit
barv-jfrog Nov 6, 2024
28c54af
Merge branch 'dev' of https://github.com/jfrog/jfrog-cli-security int…
barv-jfrog Nov 6, 2024
5ce8592
cocoapods-audit
barv-jfrog Nov 6, 2024
8ba3f33
Merge remote-tracking branch 'origin/cocoapods-audit' into cocoapods-…
barv-jfrog Nov 6, 2024
34f274e
cocoapods-audit
barv-jfrog Nov 6, 2024
2cfe712
cocoapods-audit
barv-jfrog Nov 6, 2024
eab106d
cocoapods-audit
barv-jfrog Nov 6, 2024
cd9d4f5
cocoapods-audit
barv-jfrog Nov 6, 2024
c13100d
cocoapods-audit
barv-jfrog Nov 6, 2024
ebb37cd
cocoapods-audit
barv-jfrog Nov 6, 2024
da10ea2
cocoapods-audit
barv-jfrog Nov 7, 2024
27af044
cocoapods-audit
barv-jfrog Nov 7, 2024
8e2eb99
cocoapods-audit
barv-jfrog Nov 7, 2024
88079c2
cocoapods-audit
barv-jfrog Nov 7, 2024
fe71f16
swift-audit
barv-jfrog Nov 10, 2024
b162393
swift-audit
barv-jfrog Nov 10, 2024
fa6fce5
Merge branch 'dev' into cocoapods-audit
barv-jfrog Nov 10, 2024
bd31c8a
Merge branch 'dev' into cocoapods-audit
barv-jfrog Nov 10, 2024
18a3772
Merge branch 'dev' into swift-support-audit
barv-jfrog Nov 11, 2024
c3b98d0
Merge branch 'dev' into cocoapods-audit
barv-jfrog Nov 11, 2024
6364688
cocoapods-audit
barv-jfrog Nov 11, 2024
452920e
Align core changes (#228)
sverdlov93 Nov 7, 2024
63969c9
Add NoTech Technology for directories with no tech (#230)
attiasas Nov 10, 2024
7604a33
Enable allow-partial-results to Yarn V1 dependencies map construction…
eranturgeman Nov 11, 2024
5b92419
Merge remote-tracking branch 'origin/cocoapods-audit' into cocoapods-…
barv-jfrog Nov 11, 2024
10eb136
cocoapods-audit
barv-jfrog Nov 11, 2024
d227dc0
cocoapods-audit
barv-jfrog Nov 11, 2024
76d5d9b
cocoapods-audit
barv-jfrog Nov 11, 2024
ac58152
cocoapods-audit
barv-jfrog Nov 12, 2024
4f9d0cb
cocoapods-audit
barv-jfrog Nov 12, 2024
cc9adc7
cocoapods-audit
barv-jfrog Nov 12, 2024
914366a
cocoapods-audit
barv-jfrog Nov 12, 2024
0e21bff
cocoapods-audit
barv-jfrog Nov 12, 2024
d9a3355
cocoapods-audit
barv-jfrog Nov 12, 2024
4bea9a1
cocoapods-audit
barv-jfrog Nov 12, 2024
78445f4
cocoapods-audit
barv-jfrog Nov 12, 2024
9f423af
cocoapods-audit
barv-jfrog Nov 12, 2024
1d0632f
cocoapods-audit
barv-jfrog Nov 12, 2024
5bcd943
cocoapods-audit
barv-jfrog Nov 12, 2024
76b85aa
cocoapods-audit
barv-jfrog Nov 12, 2024
cf6b309
cocoapods-audit
barv-jfrog Nov 12, 2024
a27b3de
cocoapods-audit
barv-jfrog Nov 12, 2024
e0a6e8d
cocoapods-audit
barv-jfrog Nov 12, 2024
574efca
cocoapods-audit
barv-jfrog Nov 12, 2024
c26837e
cocoapods-audit
barv-jfrog Nov 12, 2024
067148e
cocoapods-audit
barv-jfrog Nov 12, 2024
a95c72e
cocoapods-audit
barv-jfrog Nov 13, 2024
fa5db32
swift-audit
barv-jfrog Nov 13, 2024
fca6c56
swift-audit
barv-jfrog Nov 13, 2024
391927e
cocoapods-audit
barv-jfrog Nov 13, 2024
a4e0c5d
swift-audit
barv-jfrog Nov 13, 2024
ced827e
cocoapods-audit
barv-jfrog Nov 13, 2024
490aa8f
cocoapods-audit
barv-jfrog Nov 13, 2024
4a1e634
cocoapods-audit
barv-jfrog Nov 13, 2024
9a7abd3
swift-audit
barv-jfrog Nov 13, 2024
17ec960
swift-audit
barv-jfrog Nov 13, 2024
3ed68cd
swift-audit
barv-jfrog Nov 13, 2024
6f36dac
swift-audit
barv-jfrog Nov 13, 2024
8878c7b
swift-audit
barv-jfrog Nov 13, 2024
24db4c1
swift-audit
barv-jfrog Nov 13, 2024
6165f5b
swift-audit
barv-jfrog Nov 13, 2024
7490eb0
swift-audit
barv-jfrog Nov 14, 2024
17548a4
swift-audit
barv-jfrog Nov 14, 2024
97496f0
swift-audit
barv-jfrog Nov 14, 2024
c068b15
swift-audit
barv-jfrog Nov 14, 2024
95647b9
swift-audit
barv-jfrog Nov 14, 2024
a88da1e
swift-audit
barv-jfrog Nov 14, 2024
6c35cd6
swift-audit
barv-jfrog Nov 14, 2024
4894da0
cocoapods-audit
barv-jfrog Nov 14, 2024
481e57b
cocoapods-audit
barv-jfrog Nov 14, 2024
318d469
swift-audit
barv-jfrog Nov 17, 2024
d64a632
swift-audit
barv-jfrog Nov 17, 2024
3aacf67
swift-audit
barv-jfrog Nov 17, 2024
c8a84bf
swift-audit
barv-jfrog Nov 17, 2024
bc59b78
swift-audit
barv-jfrog Nov 17, 2024
a7a6063
swift-audit
barv-jfrog Nov 17, 2024
004a085
cocoapods-fix
barv-jfrog Nov 17, 2024
ea5b311
cocoapods-test
barv-jfrog Nov 17, 2024
df8559b
cocoapods-test
barv-jfrog Nov 17, 2024
5f6c242
swift-test
barv-jfrog Nov 17, 2024
9a443ff
swift-test
barv-jfrog Nov 17, 2024
78cca2e
swift-audit
barv-jfrog Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ jobs:
testFlags: '--test.audit.C'
- name: 'Cocoapods Suite'
testFlags: '--test.audit.Cocoapods'

- name: 'Swift Suite'
testFlags: '--test.audit.Swift'

steps:
# Prepare the environment
- name: Checkout code
Expand All @@ -110,6 +112,14 @@ jobs:
- name: Install and Setup Dependencies
uses: ./.github/actions/install-and-setup

- name: Install Swift on Ubuntu
uses: swift-actions/setup-swift@v2
if: ${{ matrix.os == 'ubuntu' && matrix.suite.testFlags == '--test.audit.Swift' }}

- name: Install Swift on MacOS
run: brew install swift
if: ${{ matrix.os == 'macos' && matrix.suite.testFlags == '--test.audit.Swift' }}

# Test
- name: Run tests
run: go test ${{ env.GO_COMMON_TEST_ARGS }} ${{ matrix.suite.testFlags }}
Expand Down
16 changes: 16 additions & 0 deletions audit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,13 @@ func TestXrayAuditCocoapods(t *testing.T) {
})
}

func TestXrayAuditSwift(t *testing.T) {
output := testXrayAuditSwift(t, string(format.Json))
validations.VerifyJsonResults(t, output, validations.ValidationParams{
Vulnerabilities: 1,
})
}

func TestXrayAuditPipSimpleJson(t *testing.T) {
output := testXrayAuditPip(t, string(format.SimpleJson), "")
validations.VerifySimpleJsonResults(t, output, validations.ValidationParams{
Expand Down Expand Up @@ -481,6 +488,15 @@ func testXrayAuditCocoapods(t *testing.T, format string) string {
return securityTests.PlatformCli.RunCliCmdWithOutput(t, args...)
}

func testXrayAuditSwift(t *testing.T, format string) string {
integration.InitAuditSwiftTest(t, scangraph.GraphScanMinXrayVersion)
_, cleanUp := securityTestUtils.CreateTestProjectEnvAndChdir(t, filepath.Join(filepath.FromSlash(securityTests.GetTestResourcesPath()), "projects", "package-managers", "swift"))
defer cleanUp()
// Add dummy descriptor file to check that we run only specific audit
args := []string{"audit", "--format=" + format}
return securityTests.PlatformCli.RunCliCmdWithOutput(t, args...)
}

func TestXrayAuditPipenvJson(t *testing.T) {
output := testXrayAuditPipenv(t, string(format.Json))
validations.VerifyJsonResults(t, output, validations.ValidationParams{
Expand Down
221 changes: 221 additions & 0 deletions commands/audit/sca/swift/swift.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package swift

import (
"encoding/json"
"fmt"
"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-security/utils"
"github.com/jfrog/jfrog-cli-security/utils/formats/sarifutils"
"github.com/jfrog/jfrog-cli-security/utils/techutils"
"github.com/jfrog/jfrog-client-go/utils/log"
xrayUtils "github.com/jfrog/jfrog-client-go/xray/services/utils"
"github.com/owenrumney/go-sarif/v2/sarif"
"os"
"path"
"path/filepath"
"strings"
)

// VersionForMainModule - We don't have information in swift on the current package, or main module, we only have information on its
// dependencies.

const (
VersionForMainModule = "0.0.0"
)

type Dependencies struct {
Name string `json:"url,omitempty"`
Version string `json:"version,omitempty"`
Dependencies []*Dependencies `json:"dependencies,omitempty"`
}

func GetTechDependencyLocation(directDependencyName, directDependencyVersion string, descriptorPaths ...string) ([]*sarif.Location, error) {
var swiftPositions []*sarif.Location
for _, descriptorPath := range descriptorPaths {
path.Clean(descriptorPath)
if !strings.HasSuffix(descriptorPath, "Package.swift") {
log.Logger.Warn("Cannot support other files besides Package.swift: %s", descriptorPath)
continue
}
data, err := os.ReadFile(descriptorPath)
if err != nil {
continue
}
lines := strings.Split(string(data), "\n")
var startLine, startCol int
foundDependency := false
var tempIndex int
for i, line := range lines {
foundDependency, tempIndex, startLine, startCol = parsePodLine(line, directDependencyName, directDependencyVersion, descriptorPath, i, tempIndex, startLine, startCol, lines, foundDependency, &swiftPositions)
}
}
return swiftPositions, nil
}

func parsePodLine(line, directDependencyName, directDependencyVersion, descriptorPath string, i, tempIndex, startLine, startCol int, lines []string, foundDependency bool, swiftPositions *[]*sarif.Location) (bool, int, int, int) {
if strings.Contains(line, directDependencyName) {
startLine = i
startCol = strings.Index(line, directDependencyName)
foundDependency = true
tempIndex = i
}
// This means we are in a new dependency (we cannot find dependency name and version together)
if i > tempIndex && foundDependency && strings.Contains(line, ".package") {
foundDependency = false
} else if foundDependency && strings.Contains(line, directDependencyVersion) {
endLine := i
endCol := strings.Index(line, directDependencyVersion) + len(directDependencyVersion) + 1
var snippet string
// if the tech dependency is a one-liner
if endLine == startLine {
snippet = lines[startLine][startCol:endCol]
// else it is more than one line, so we need to parse all lines
} else {
for snippetLine := 0; snippetLine < endLine-startLine+1; snippetLine++ {
switch snippetLine {
case 0:
snippet += "\n" + lines[snippetLine][startLine:]
case endLine - startLine:
snippet += "\n" + lines[snippetLine][:endCol]
default:
snippet += "\n" + lines[snippetLine]
}
}
}
*swiftPositions = append(*swiftPositions, sarifutils.CreateLocation(descriptorPath, startLine, endLine, startCol, endCol, snippet))
foundDependency = false
}
return foundDependency, tempIndex, startLine, startCol
}

func FixTechDependency(dependencyName, dependencyVersion, fixVersion string, descriptorPaths ...string) error {
for _, descriptorPath := range descriptorPaths {
path.Clean(descriptorPath)
if !strings.HasSuffix(descriptorPath, "Package.swift") {
log.Logger.Warn("Cannot support other files besides Package.swift: %s", descriptorPath)
continue
}
data, err := os.ReadFile(descriptorPath)
var newLines []string
if err != nil {
continue
}
lines := strings.Split(string(data), "\n")
foundDependency := false
var tempIndex int
for index, line := range lines {
if strings.Contains(line, dependencyName) {
foundDependency = true
tempIndex = index
}
// This means we are in a new dependency (we cannot find dependency name and version together)
//nolint:gocritic
if index > tempIndex && foundDependency && strings.Contains(line, ".package") {
foundDependency = false
} else if foundDependency && strings.Contains(line, dependencyVersion) {
newLine := strings.Replace(line, dependencyVersion, fixVersion, 1)
newLines = append(newLines, newLine)
foundDependency = false
} else {
newLines = append(newLines, line)
}
}
output := strings.Join(newLines, "\n")
err = os.WriteFile(descriptorPath, []byte(output), 0644)
if err != nil {
return fmt.Errorf("failed to write file: %v", err)
}
}
return nil
}

func GetSwiftDependenciesGraph(data *Dependencies, dependencyMap map[string][]string, versionMap map[string]string) {
data.Name = strings.TrimSuffix(data.Name, ".git")
data.Name = strings.TrimPrefix(data.Name, "https://")
_, ok := dependencyMap[data.Name]
if !ok {
dependencyMap[data.Name] = []string{}
versionMap[data.Name] = data.Version
}
for _, dependency := range data.Dependencies {
dependency.Name = strings.TrimSuffix(dependency.Name, ".git")
dependency.Name = strings.TrimPrefix(dependency.Name, "https://")
dependencyMap[data.Name] = append(dependencyMap[data.Name], dependency.Name)
GetSwiftDependenciesGraph(dependency, dependencyMap, versionMap)
}
}

func GetDependenciesData(exePath, currentDir string) (*Dependencies, error) {
result, _, err := runSwiftCmd(exePath, currentDir, []string{"package", "show-dependencies", "--format", "json"})
if err != nil {
return nil, err
}
var data *Dependencies
err = json.Unmarshal(result, &data)
if err != nil {
return nil, err
}
return data, nil
}

func BuildDependencyTree(params utils.AuditParams) (dependencyTree []*xrayUtils.GraphNode, uniqueDeps []string, err error) {
currentDir, err := coreutils.GetWorkingDirectory()
if err != nil {
return nil, nil, err
}

packageName := filepath.Base(currentDir)
packageInfo := fmt.Sprintf("%s:%s", packageName, VersionForMainModule)
_, _, err = getSwiftVersionAndExecPath()
if err != nil {
err = fmt.Errorf("failed while retrieving swift path: %s", err.Error())
return
}
// Calculate pod dependencies
data, err := GetDependenciesData("swift", currentDir)
if err != nil {
return nil, nil, err
}
uniqueDepsSet := datastructures.MakeSet[string]()
dependencyMap := make(map[string][]string)
versionMap := make(map[string]string)
data.Name = packageName
data.Version = VersionForMainModule
GetSwiftDependenciesGraph(data, dependencyMap, versionMap)
for key := range dependencyMap {
if key != packageName {
dependencyMap[packageName] = append(dependencyMap[packageName], key)
}
}
versionMap[packageName] = VersionForMainModule
rootNode := &xrayUtils.GraphNode{
Id: techutils.Swift.GetPackageTypeId() + packageInfo,
Nodes: []*xrayUtils.GraphNode{},
}
// Parse the dependencies into Xray dependency tree format
parseSwiftDependenciesList(rootNode, dependencyMap, versionMap, uniqueDepsSet)
dependencyTree = []*xrayUtils.GraphNode{rootNode}
uniqueDeps = uniqueDepsSet.ToSlice()
return
}

// Parse the dependencies into a Xray dependency tree format
func parseSwiftDependenciesList(currNode *xrayUtils.GraphNode, dependenciesGraph map[string][]string, versionMap map[string]string, uniqueDepsSet *datastructures.Set[string]) {
if currNode.NodeHasLoop() {
return
}
uniqueDepsSet.Add(currNode.Id)
pkgName := strings.Split(strings.TrimPrefix(currNode.Id, techutils.Swift.GetPackageTypeId()), ":")[0]
currDepChildren := dependenciesGraph[pkgName]
for _, childName := range currDepChildren {
fullChildName := fmt.Sprintf("%s:%s", childName, versionMap[childName])
childNode := &xrayUtils.GraphNode{
Id: techutils.Swift.GetPackageTypeId() + fullChildName,
Nodes: []*xrayUtils.GraphNode{},
Parent: currNode,
}
currNode.Nodes = append(currNode.Nodes, childNode)
parseSwiftDependenciesList(childNode, dependenciesGraph, versionMap, uniqueDepsSet)
}
}
116 changes: 116 additions & 0 deletions commands/audit/sca/swift/swift_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package swift

import (
"fmt"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-cli-core/v2/utils/tests"
"github.com/jfrog/jfrog-cli-security/utils/techutils"
"github.com/owenrumney/go-sarif/v2/sarif"
"os"
"path/filepath"
"testing"

"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-security/commands/audit/sca"
xrayutils "github.com/jfrog/jfrog-cli-security/utils"

"github.com/stretchr/testify/assert"
)

func TestBuildSwiftDependencyList(t *testing.T) {
// Create and change directory to test workspace
_, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "swift"))
defer cleanUp()

// Run getModulesDependencyTrees
server := &config.ServerDetails{
Url: "https://api.swift.here",
ArtifactoryUrl: "https://api.swift.here/artifactory",
User: "user",
AccessToken: "sdsdccs2232",
}
currentDir, err := coreutils.GetWorkingDirectory()
assert.NoError(t, err)
packageName := filepath.Base(currentDir)
packageInfo := fmt.Sprintf("%s:%s", packageName, VersionForMainModule)
expectedUniqueDeps := []string{
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-algorithms:1.2.0",
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-numerics:1.0.2",
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-nio-http2:1.19.0",
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-atomics:1.2.0",
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-collections:1.1.4",
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-system:1.4.0",
techutils.Swift.GetPackageTypeId() + "github.com/apple/swift-nio:2.76.1",
techutils.Swift.GetPackageTypeId() + packageInfo,
}

auditBasicParams := (&xrayutils.AuditBasicParams{}).SetServerDetails(server)
rootNode, uniqueDeps, err := BuildDependencyTree(auditBasicParams)
assert.NoError(t, err)
assert.ElementsMatch(t, uniqueDeps, expectedUniqueDeps, "First is actual, Second is Expected")
assert.NotEmpty(t, rootNode)

assert.Equal(t, rootNode[0].Id, techutils.Swift.GetPackageTypeId()+packageInfo)
assert.Len(t, rootNode[0].Nodes, 9)

child1 := tests.GetAndAssertNode(t, rootNode[0].Nodes, "github.com/apple/swift-algorithms:1.2.0")
assert.Len(t, child1.Nodes, 1)

child2 := tests.GetAndAssertNode(t, rootNode[0].Nodes, "github.com/apple/swift-numerics:1.0.2")
assert.Len(t, child2.Nodes, 0)
}

func TestGetTechDependencyLocation(t *testing.T) {
_, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "swift"))
defer cleanUp()
currentDir, err := coreutils.GetWorkingDirectory()
assert.NoError(t, err)
locations, err := GetTechDependencyLocation("github.com/apple/swift-algorithms", "1.2.0", filepath.Join(currentDir, "Package.swift"))
assert.NoError(t, err)
assert.Len(t, locations, 1)
assert.Equal(t, *locations[0].PhysicalLocation.Region.StartLine, 10)
assert.Equal(t, *locations[0].PhysicalLocation.Region.StartColumn, 10)
assert.Equal(t, *locations[0].PhysicalLocation.Region.EndLine, 31)
assert.Equal(t, *locations[0].PhysicalLocation.Region.EndColumn, 80)
assert.Contains(t, *locations[0].PhysicalLocation.Region.Snippet.Text, "github.com/apple/swift-algorithms\", from: \"1.2.0\"")
}

func TestPodLineParse(t *testing.T) {
var swiftPositions []*sarif.Location
foundDependency, _, startLine, startCol := parsePodLine(".package(url: \"https://github.com/apple/swift-algorithms\", from: \"1.2.0\")", "github.com/apple/swift-algorithms", "1.2.0", "test", 0, 0, 0, 0, []string{".package(url: \"https://github.com/apple/swift-algorithms\", from: \"1.2.0\")"}, false, &swiftPositions)
assert.Equal(t, foundDependency, false)
assert.Equal(t, startLine, 0)
assert.Equal(t, startCol, 23)
}

func TestPodLineParseFoundOnlyDependencyName(t *testing.T) {
var swiftPositions []*sarif.Location
foundDependency, _, startLine, startCol := parsePodLine(".package(url: \"https://github.com/apple/swift-algorithms\", from: \"1.2.0\")", "github.com/apple/swift-algorithms", "6.2.4", "test", 0, 0, 0, 0, []string{".package(url: \"https://github.com/apple/swift-algorithms\", from: \"1.2.0\")"}, false, &swiftPositions)
assert.Equal(t, foundDependency, true)
assert.Equal(t, startLine, 0)
assert.Equal(t, startCol, 23)
}

func TestFixTechDependencySingleLocation(t *testing.T) {
_, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "swift"))
defer cleanUp()
currentDir, err := coreutils.GetWorkingDirectory()
assert.NoError(t, err)
err = FixTechDependency("github.com/apple/swift-nio-http2", "1.0.0", "1.0.1", filepath.Join(currentDir, "Package.swift"))
assert.NoError(t, err)
file, err := os.ReadFile(filepath.Join(currentDir, "Package.swift"))
assert.NoError(t, err)
assert.Contains(t, string(file), ".package(url: \"https://github.com/apple/swift-nio-http2\", \"1.0.1\"..<\"1.19.1\")")
}

func TestFixTechDependencyNoLocations(t *testing.T) {
_, cleanUp := sca.CreateTestWorkspace(t, filepath.Join("projects", "package-managers", "swift"))
defer cleanUp()
currentDir, err := coreutils.GetWorkingDirectory()
assert.NoError(t, err)
err = FixTechDependency("github.com/apple/swift-nio-http2", "1.8.2", "1.8.3", filepath.Join(currentDir, "Package.swift"))
assert.NoError(t, err)
file, err := os.ReadFile(filepath.Join(currentDir, "Package.swift"))
assert.NoError(t, err)
assert.Contains(t, string(file), ".package(url: \"https://github.com/apple/swift-nio-http2\", \"1.0.0\"..<\"1.19.1\")")
}
Loading
Loading