File: SwiftSDKConfigurationStore.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (144 lines) | stat: -rw-r--r-- 5,673 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2014-2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import Basics

import class Foundation.JSONDecoder
import class Foundation.JSONEncoder

/// Storage for configuration properties of Swift SDKs.
public final class SwiftSDKConfigurationStore {
    /// Triple of the machine on which SwiftPM is running.
    private let hostTriple: Triple

    /// Path to the directory in which Swift SDKs and their configuration are stored. Usually
    /// `~/.swiftpm/swift-sdks` or a directory to which `~/.swiftpm/swift-sdks` symlinks to.
    private let swiftSDKsDirectoryPath: AbsolutePath

    /// Path to the directory in which Swift SDK configuration files are stored.
    private let configurationDirectoryPath: AbsolutePath

    /// File system that stores Swift SDK configuration and contains
    /// ``SwiftSDKConfigurationStore//configurationDirectoryPath``.
    private let fileSystem: FileSystem

    // An observability scope on which warnings can be reported if any appear.
    private let swiftSDKBundleStore: SwiftSDKBundleStore

    /// Encoder used for encoding updated configuration to be written to ``SwiftSDKConfigurationStore//fileSystem``.
    private let encoder: JSONEncoder

    /// Encoder used for reading existing configuration from  ``SwiftSDKConfigurationStore//fileSystem``.
    private let decoder: JSONDecoder

    /// Initializes a store for configuring Swift SDKs.
    /// - Parameters:
    ///   - hostTriple: Triple of the machine on which SwiftPM is running.
    ///   - swiftSDKsDirectoryPath: Path to the directory in which Swift SDKs and their configuration are
    ///   stored. Usually `~/.swiftpm/swift-sdks` or a directory to which `~/.swiftpm/swift-sdks` symlinks to.
    ///   If this directory doesn't exist, an error will be thrown.
    ///   - fileSystem: file system on which `swiftSDKsDirectoryPath` exists.
    ///   - observabilityScope: an observability scope on which warnings can be reported if any appear.
    public init(
        hostTimeTriple: Triple,
        swiftSDKBundleStore: SwiftSDKBundleStore
    ) throws {
        let configurationDirectoryPath = swiftSDKBundleStore.swiftSDKsDirectory.appending(component: "configuration")

        let fileSystem = swiftSDKBundleStore.fileSystem
        if fileSystem.exists(configurationDirectoryPath) {
            guard fileSystem.isDirectory(configurationDirectoryPath) else {
                throw SwiftSDKError.pathIsNotDirectory(configurationDirectoryPath)
            }
        } else {
            try fileSystem.createDirectory(configurationDirectoryPath)
        }

        self.hostTriple = hostTimeTriple
        self.swiftSDKsDirectoryPath = swiftSDKBundleStore.swiftSDKsDirectory
        self.configurationDirectoryPath = configurationDirectoryPath
        self.fileSystem = fileSystem
        self.swiftSDKBundleStore = swiftSDKBundleStore
        self.encoder = JSONEncoder.makeWithDefaults(prettified: true)
        self.decoder = JSONDecoder.makeWithDefaults()
    }

    public func updateConfiguration(
        sdkID: String,
        swiftSDK: SwiftSDK
    ) throws {
        let (targetTriple, properties) = try swiftSDK.serialized

        let configurationPath = configurationDirectoryPath.appending(
            component: "\(sdkID)_\(targetTriple).json"
        )

        try encoder.encode(path: configurationPath, fileSystem: fileSystem, properties)
    }

    public func readConfiguration(
        sdkID: String,
        targetTriple: Triple
    ) throws -> SwiftSDK? {
        let configurationPath = configurationDirectoryPath.appending(
            component: "\(sdkID)_\(targetTriple.tripleString).json"
        )

        let swiftSDKs = try self.swiftSDKBundleStore.allValidBundles

        guard var swiftSDK = swiftSDKs.selectSwiftSDK(
            id: sdkID,
            hostTriple: nil,
            targetTriple: targetTriple
        ) else {
            return nil
        }

        if fileSystem.isFile(configurationPath) {
            let properties = try decoder.decode(
                path: configurationPath,
                fileSystem: fileSystem,
                as: SwiftSDKMetadataV4.TripleProperties.self
            )

            swiftSDK.pathsConfiguration.merge(
                with: try SwiftSDK(
                    targetTriple: targetTriple,
                    properties: properties
                ).pathsConfiguration
            )
        }

        return swiftSDK
    }

    /// Resets configuration for identified target triple.
    /// - Parameters:
    ///   - sdkID: ID of the Swift SDK to operate on.
    ///   - tripleString: run-time triple for which the properties should be reset.
    /// - Returns: `true` if custom configuration was successfully removed, `false` if no custom configuration existed.
    public func resetConfiguration(
        sdkID: String,
        targetTriple triple: Triple
    ) throws -> Bool {
        let configurationPath = configurationDirectoryPath.appending(
            component: "\(sdkID)_\(triple.tripleString).json"
        )

        guard fileSystem.isFile(configurationPath) else {
            return false
        }

        try fileSystem.removeFileTree(configurationPath)
        return true
    }
}