-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #214 from polac24/up-to-date-meta
Ensure up-to-date meta json in the unzipped artifact
- Loading branch information
Showing
7 changed files
with
253 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright (c) 2023 Spotify AB. | ||
// | ||
// Licensed to the Apache Software Foundation (ASF) under one | ||
// or more contributor license agreements. See the NOTICE file | ||
// distributed with this work for additional information | ||
// regarding copyright ownership. The ASF licenses this file | ||
// to you under the Apache License, Version 2.0 (the | ||
// "License"); you may not use this file except in compliance | ||
// with the License. You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, | ||
// software distributed under the License is distributed on an | ||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
// KIND, either express or implied. See the License for the | ||
// specific language governing permissions and limitations | ||
// under the License. | ||
|
||
import Foundation | ||
|
||
enum ArtifactMetaUpdaterError: Error { | ||
/// The prebuild plugin execution was called but the local | ||
/// path to the artifact directory is still unknown | ||
/// Might happen that the artifact processor didn't invoke the updater's | ||
/// .process() after downloading/activating an artifact | ||
case artifactLocationIsUnknown | ||
} | ||
|
||
/// Updates the meta file in an unzipped artifact directory, by placing an up-to-date | ||
/// and remapped meta file. Updating the meta in the artifact allows reusing existing | ||
/// artifacts it a new meta.json schema has been released to the meta format, while | ||
/// artifacts are still backward-compatible | ||
class ArtifactMetaUpdater: ArtifactProcessor { | ||
private var artifactLocation: URL? | ||
private let metaWriter: MetaWriter | ||
private let fileRemapper: FileDependenciesRemapper | ||
|
||
init( | ||
fileRemapper: FileDependenciesRemapper, | ||
metaWriter: MetaWriter | ||
) { | ||
self.metaWriter = metaWriter | ||
self.fileRemapper = fileRemapper | ||
} | ||
|
||
/// Remembers the artifact location, used later in the plugin | ||
/// - Parameter url: artifact's root directory | ||
func process(rawArtifact url: URL) throws { | ||
// Storing the location of the just downloaded/activated artifact | ||
// Note, the `url` location already includes a meta (generated by producer | ||
// while compiling and building an artifact) | ||
artifactLocation = url | ||
} | ||
|
||
func process(localArtifact url: URL) throws { | ||
// No need to do anything in the postbuild | ||
} | ||
} | ||
|
||
extension ArtifactMetaUpdater: ArtifactConsumerPrebuildPlugin { | ||
|
||
/// Updates the meta json file in a local, unzipped, artifact location. It also remaps | ||
/// all paths so other steps (like actool or postbuild) don't have to do it again | ||
func run(meta: MainArtifactMeta) throws { | ||
guard let artifactLocation = artifactLocation else { | ||
throw ArtifactMetaUpdaterError.artifactLocationIsUnknown | ||
} | ||
let metaURL = try metaWriter.write(meta, locationDir: artifactLocation) | ||
try fileRemapper.remap(fromGeneric: metaURL) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
Tests/XCRemoteCacheTests/Artifacts/ArtifactMetaUpdaterTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright (c) 2023 Spotify AB. | ||
// | ||
// Licensed to the Apache Software Foundation (ASF) under one | ||
// or more contributor license agreements. See the NOTICE file | ||
// distributed with this work for additional information | ||
// regarding copyright ownership. The ASF licenses this file | ||
// to you under the Apache License, Version 2.0 (the | ||
// "License"); you may not use this file except in compliance | ||
// with the License. You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, | ||
// software distributed under the License is distributed on an | ||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
// KIND, either express or implied. See the License for the | ||
// specific language governing permissions and limitations | ||
// under the License. | ||
|
||
@testable import XCRemoteCache | ||
import XCTest | ||
|
||
class ArtifactMetaUpdaterTests: XCTestCase { | ||
private let accessorFake = FileAccessorFake(mode: .normal) | ||
private var metaWriter: MetaWriter! | ||
private var fileRemapper: FileDependenciesRemapper! | ||
private var updater: ArtifactMetaUpdater! | ||
private let sampleMeta = MainArtifactMeta( | ||
dependencies: [], | ||
fileKey: "abc", | ||
rawFingerprint: "", | ||
generationCommit: "", | ||
targetName: "", | ||
configuration: "", | ||
platform: "", | ||
xcode: "", | ||
inputs: ["$(BASE)/myFile.swift"], | ||
pluginsKeys: [:] | ||
) | ||
|
||
override func setUp() async throws { | ||
metaWriter = JsonMetaWriter( | ||
fileWriter: accessorFake, | ||
pretty: true | ||
) | ||
fileRemapper = TextFileDependenciesRemapper( | ||
remapper: StringDependenciesRemapper( | ||
mappings: [ | ||
.init(generic: "$(BASE)", local: "/base") | ||
] | ||
), | ||
fileAccessor: accessorFake | ||
) | ||
updater = ArtifactMetaUpdater( | ||
fileRemapper: fileRemapper, | ||
metaWriter: metaWriter | ||
) | ||
} | ||
|
||
func testStoresInTheRawArtifact() throws { | ||
try updater.process(rawArtifact: "/artifact") | ||
try updater.run(meta: sampleMeta) | ||
|
||
XCTAssertTrue(accessorFake.fileExists(atPath: "/artifact/abc.json")) | ||
} | ||
|
||
func testRewirtesMetaPaths() throws { | ||
try updater.process(rawArtifact: "/artifact") | ||
try updater.run(meta: sampleMeta) | ||
|
||
let diskMetaData = try XCTUnwrap(accessorFake.contents(atPath: "/artifact/abc.json")) | ||
let diskMeta = try JSONDecoder().decode(MainArtifactMeta.self, from: diskMetaData) | ||
XCTAssertEqual(diskMeta.inputs, ["/base/myFile.swift"]) | ||
} | ||
|
||
func testFailsIfProcessorTriggerIsNotCalledBeforeRunningAPlugin() throws { | ||
XCTAssertThrowsError(try updater.run(meta: sampleMeta)) { error in | ||
switch error { | ||
case ArtifactMetaUpdaterError.artifactLocationIsUnknown: break | ||
default: | ||
XCTFail("Not expected error") | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
Tests/XCRemoteCacheTests/TestDoubles/DestroyerArtifactProcessor.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright (c) 2022 Spotify AB. | ||
// | ||
// Licensed to the Apache Software Foundation (ASF) under one | ||
// or more contributor license agreements. See the NOTICE file | ||
// distributed with this work for additional information | ||
// regarding copyright ownership. The ASF licenses this file | ||
// to you under the Apache License, Version 2.0 (the | ||
// "License"); you may not use this file except in compliance | ||
// with the License. You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, | ||
// software distributed under the License is distributed on an | ||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
// KIND, either express or implied. See the License for the | ||
// specific language governing permissions and limitations | ||
// under the License. | ||
|
||
|
||
import Foundation | ||
@testable import XCRemoteCache | ||
|
||
/// A Processor fake that deletes the artifact | ||
class DestroyerArtifactProcessor: ArtifactProcessor { | ||
private let dirAccesor: DirAccessor | ||
|
||
init(_ dirAccesor: DirAccessor) { | ||
self.dirAccesor = dirAccesor | ||
} | ||
func process(rawArtifact url: URL) throws { | ||
try dirAccesor.removeItem(atPath: url.path) | ||
} | ||
func process(localArtifact url: URL) throws { | ||
try dirAccesor.removeItem(atPath: url.path) | ||
} | ||
} |