Giter Site home page Giter Site logo

komondor's Introduction

Komondor

Git Hook automation for Swift and Xcode projects. A port of Husky to Swift.

TL:DR

  1. Add or amend a Package.swift
  2. Add this dependency .package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.0"),
  3. Run the install command: swift run komondor install
  4. Add a config section to your Package.swift

Then you'll get git-hooks consolidated and centralized so that everyone can work with the same tooling.

Why?

If you care about something, you should automate it.

Git Hooks like what Komondor provides gives you more surface area for per-project automation. Komondor provides an easily understood way to see how all the git automation touch-points in your project will come together. These hooks allow for much faster feedback during development and let different team-members to use different tools but still have the same bar of quality.

For example, adding SwiftFormat to your pre-commit hook means that no-one will ever need to discuss formatting in code review again. Perfect. It won't slow down your Xcode builds, because it lives outside of your project and you can verify it on CI if you'd like to be 100% that everyone conforms.

Another example, running tests before pushing - this means you don't have to come back 10-15m later once CI has told you that you have a failing test. This moves more validation to a point where you are still in-context.

An Example

This is from the repo you're looking at:

#if canImport(PackageConfig)
    import PackageConfig

    let config = PackageConfiguration([
        "komondor": [
            "pre-push": "swift test",
            "pre-commit": [
                "swift test",
                "swift run swiftformat .",
                "swift run swiftlint autocorrect --path Sources/",
                "git add .",
            ],
        ],
    ]).write()
#endif

See more about the config here.

Getting Set up

On a SwiftPM project On an Xcode Project

Deployment

Use swift run rocket [patch]

komondor's People

Contributors

cszatmary avatar daneov avatar dirtyhenry avatar duemunk avatar f-meloni avatar leogdion avatar minuscorp avatar orta avatar sahara-ooga avatar vknabel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

komondor's Issues

Invalid manifest

After swift build

error: Invalid manifest
/var/folders/9w/c9386qq55g36bkfc17n88rww0000gp/T/TemporaryFile.fqS4xv.swift:108:9: error: unexpected ',' separator
        )
        ^ in https://github.com/Realm/SwiftLint.git

Chage path of Package.swift

Hi,

I'm testing komodor, and I would like to know if it's possible, when installing, specify the path to the Package.swift to use. Since I don't have it on the base path of the project.

Thanks a lot

Usage from within a Beak script & uninstallability?

I'm just trying to use Komondor from within a Beak script, since there you can also specify SwiftPM dependencies and run them separately from the Package.swift file. I'm already confused because of #18 and #19, but what I also don't understand is how the definition of a config parameter leads to Komondor to know what things to run? Does that mean that Komondor is parsing the Package.swift file and trying to find a PackageConfig object there, I'm really confused about how this works.

Here's what I'm trying at the moment using Beak:

#!/usr/bin/env beak run --path

// MARK: - Script Dependencies
// beak: shibapm/Komondor @ .upToNextMajor(from: "1.0.4")

import Foundation
import PackageConfig

// MARK: - Runnable Tasks
/// Registers git hooks for the project to ensure you get notified of potential issues e.g. before committing.
public func register() throws {
    let config = PackageConfig([
        "komondor": [
            "pre-commit": ["bartycrouch lint --fail-on-warnings", "swiftlint lint --strict --quiet"]
        ]
    ])

    // TODO: make sure the `config` actually is being used by `kommondor install`, but how?
}

/// Unregisters any registered git hooks.
public func unregister() throws {
    let config = PackageConfig(["komondor": []])
    // TODO: make sure the `config` actually is being applied by `kommondor install` and updates previous hooks, but how?
}

My goal is to have both a hooks register and a hooks unregister command setup which developers who checkout the project can run in order to โ€“ well, register or unregister all hooks I might define within that file. Also, how does Komondor behave when I change my hooks and re-run kommondor install, does it remove all removed hooks and also ensure no duplicates appear in the final configured hooks?

Version Solving Failed

While using certain plugins, I get this version solving failed error in my pre-commit hook:

[Komondor] > pre-commit swift test
error: because no versions of SourceDocs match the requirement 1.0.0..<2.0.0 and root depends on SourceDocs 1.0.0..<2.0.0, version solving failed.
Updating https://github.com/nerdishbynature/RequestKit.git
Updating https://github.com/f-meloni/Logger
Updating https://github.com/jpsim/Yams
Updating https://github.com/f-meloni/danger-swift-xcodesummary
Updating https://github.com/f-meloni/danger-swift-coverage
Updating https://github.com/shibapm/Rocket
Updating https://github.com/shibapm/Komondor.git
Updating https://github.com/JohnSundell/ShellOut.git
Updating https://github.com/kareman/SwiftShell
Updating https://github.com/mxcl/Version
Updating https://github.com/nerdishbynature/octokit.swift
Updating https://github.com/nicklockwood/SwiftFormat
Updating https://github.com/shibapm/PackageConfig.git
Updating https://github.com/danger/swift.git
Updating https://github.com/eneko/SourceDocs
[Komondor] > pre-commit hook failed (add --no-verify to skip)

This happens when I tired to use SourceDocs and SwiftLint

Package.swift file

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Skip-Core-Swift",
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "SkipCore",
            targets: ["SkipCore"]
        ),
//        // Development Library
        .library(name: "DangerDeps", type: .dynamic, targets: ["DangerDependencies"]), // dev
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // Development Dependencies
        .package(name: "danger-swift", url: "https://github.com/danger/swift.git", from: "3.0.0"),
        .package(url: "https://github.com/shibapm/Rocket", from: "0.4.0"), // dev
        .package(name: "Komondor", url: "https://github.com/shibapm/Komondor.git", from: "1.0.0"), // dev
        .package(name: "SwiftFormat", url: "https://github.com/nicklockwood/SwiftFormat", from: "0.47.0"), // dev
        .package(name: "SourceDocs", url: "https://github.com/eneko/SourceDocs", from: "1.0.0"), // dev
        // Danger Plugins
        .package(name: "DangerSwiftCoverage", url: "https://github.com/f-meloni/danger-swift-coverage", from: "1.0.0"), // dev
        .package(name: "DangerXCodeSummary", url: "https://github.com/f-meloni/danger-swift-xcodesummary", from: "1.0.0"), // dev
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        // Development Target
        .target(
            name: "DangerDependencies",
            dependencies: [
                .product(name: "Danger", package: "danger-swift"),
                "DangerSwiftCoverage",
                "DangerXCodeSummary",
            ],
            path: "Sources/DangerDependencies",
            sources: ["Fake.swift"]
        ),
        .target(
            name: "SkipCore",
            dependencies: []
        ),
        .testTarget(
            name: "SkipCoreTests",
            dependencies: ["SkipCore"]
        ),
    ]
)

#if canImport(PackageConfig)
    import PackageConfig

    let config = PackageConfiguration([
        "komondor": [
            "pre-commit": [
                "swift test",
                "swift run swiftformat Sources/",
                "swift run sourcedocs generate --spm-module SkipCore"
            ],
            "pre-push": "swift test",
        ],
        "rocket": [
            "steps": [
                ["script": ["content": "ruby Scripts/update_changelog.rb"]],
                ["git_add": ["paths": ["CHANGELOG.md"]]],
                ["commit": ["message": "Releasing version $VERSION"]],
                "tag",
                "push",
            ],
        ],
    ]).write()
#endif

Add support for macros

[edited] could represent all the files changed, so you could run SwiftLint only against changed things

pre-push hook doesn't work in xcode

Hi,
we try to use Komondor to set up a pre-push hook to run swiftlint before pushing any changes in an IOS project. For some reason, the pre-push hook doesn't work in xcode(11.4.1), xcode allow a push without running swiftlint. The same config and same project, it works fine in the command line "git push". Also, in other IDE, vscode or tower. It does block push with a general error without showing the linting error. any idea why? Is it a known issue in xcode?

Hide development packages

The latest release 1.1.4 exposes all the development packages in the Package.swift file. You'd think SPM is smart enough to exclude these, but it isn't.

It's creating issues for certain packages that use Komondor (see SwiftGen/StencilSwiftKit#162 (review)), because of dependency conflicts further down (see krzysztofzablocki/Sourcery#1023 (comment)).

The issue was caused by this unhide commit. Normally release commits of Komondor hide these packages again, see for example the release commit for 1.1.3.

Trying to get "commit-msg" working but seems like git params aren't set

I've set commitlint locally, and I've been trying to use it from Komondor.

let config = PackageConfiguration([
    "komondor": [
        "commit-msg": "npx --no -- commitlint --edit",
    ],
]).write()
#endif

Apparently, the git parameter that the commit-msg hook expects is not being passed.

I've also tried things like:

 "commit-msg": "npx --no -- commitlint --edit $1",

or

 "commit-msg": "npx --no -- commitlint --edit '$1'",

... but cannot make it work; cannot find documentation about it either.

How could I get it working? ๐Ÿค” - Thanks in advance ๐Ÿ˜ฌ!

Use real configuration file instead of Package.swift code

The README doesn't really explain, why the configuration of the commits has to be done within Package.swift and I find it very confusing and misplaced there. To me, the example configuration looks like it should actually be just a configuration file (using YAML, TOML or whatever you prefer) like this (komondor.yml):

pre-push: swift test
pre-commit":
  - swift test
  - swift run swiftFormat .
  - swift run swiftlint autocorrect --path Sources/
  - git add .

I feel like that would be much cleaner. But feel free to explain, why you opted for the current solution. Maybe I don't see the whole picture ...

Xcode 13 Beta/Swift 5.5 - Unable to Run Hooks

Getting the following error when using Xcode 13/Swift 5.5 build:

[0/0] Build complete!
Package.swift:3:8: error: no such module 'PackageDescription'
import PackageDescription
       ^
Swift/ErrorType.swift:200: Fatal error: Error raised at top level: PackageConfig.Error(reason: "Could not find a file at /var/folders/_z/7dqmnmzj0k1_57ctrgqrdq840000gn/T/package-config - something went wrong with compilation step probably")
[1]    43747 trace trap  swift run komondor run pre-commit

Update SwiftFormat and SwiftLint versions in Package.swift

Is it possible to update the SwiftFormat and SwiftLint dependencies in the Package.swift to the latest version?
Because the version used are very old

        .package(url: "https://github.com/nicklockwood/SwiftFormat.git", from: "0.35.8"), // Update to 0.48.18
        .package(url: "https://github.com/Realm/SwiftLint.git", from: "0.28.1"), // Update to 0.45.0

Issue with running Komondor hooks

I'm using the latest version (master) and I keep getting the same output when I try to run a hook:

13/13] Linking komondor
Package.swift:6:15: error: 'init(name:platforms:pkgConfig:providers:products:dependencies:targets:swiftLanguageVersions:cLanguageStandard:cxxLanguageStandard:)' is unavailable
let package = Package(
              ^~~~~~~
PackageDescription.Package:29:12: note: 'init(name:platforms:pkgConfig:providers:products:dependencies:targets:swiftLanguageVersions:cLanguageStandard:cxxLanguageStandard:)' was introduced in PackageDescription 5
    public init(name: String, platforms: [PackageDescription.SupportedPlatform]? = nil, pkgConfig: String? = nil, providers: [PackageDescription.SystemPackageProvider]? = nil, products: [PackageDescription.Product] = [], dependencies: [PackageDescription.Package.Dependency] = [], targets: [PackageDescription.Target] = [], swiftLanguageVersions: [PackageDescription.SwiftVersion]? = nil, cLanguageStandard: PackageDescription.CLanguageStandard? = nil, cxxLanguageStandard: PackageDescription.CXXLanguageStandard? = nil)
           ^
Package.swift:35:10: error: 'target(name:dependencies:path:exclude:sources:publicHeadersPath:)' is unavailable
        .target(
         ^~~~~~
PackageDescription.Target:34:24: note: 'target(name:dependencies:path:exclude:sources:publicHeadersPath:)' was introduced in PackageDescription 4
    public static func target(name: String, dependencies: [PackageDescription.Target.Dependency] = [], path: String? = nil, exclude: [String] = [], sources: [String]? = nil, publicHeadersPath: String? = nil) -> PackageDescription.Target
                       ^
Package.swift:38:10: error: 'testTarget(name:dependencies:path:exclude:sources:)' is unavailable
        .testTarget(
         ^~~~~~~~~~
PackageDescription.Target:38:24: note: 'testTarget(name:dependencies:path:exclude:sources:)' was introduced in PackageDescription 4
    public static func testTarget(name: String, dependencies: [PackageDescription.Target.Dependency] = [], path: String? = nil, exclude: [String] = [], sources: [String]? = nil) -> PackageDescription.Target
                       ^
Fatal error: Error raised at top level: PackageConfig.Error(reason: "Could not find a file at /var/folders/n4/zbkl28756wj08660vtf58qz80000gn/T/package-config - something went wrong with compilation step probably"): file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1100.8.259.70/swift/stdlib/public/core/ErrorType.swift, line 200
[1]    54676 illegal hardware instruction  swift run komondor run pre-commit

As if the Package.swift is wrong structured or something. But swift build and swift test doesn't complain about anything. I'm using // swift-tools-version:5.1 but I tried to downgrade until 4.2 with no success. Any thoughts?

Pre-build dependencies during the install phase

#if canImport(PackageConfig)
    import PackageConfig

    let config = PackageConfig([
        "komondor": [
            "pre-push": "swift test",
            "pre-commit": [
                "swift test",
                "swift run swiftFormat .",
                "swift run swiftlint autocorrect --path Sources/",
                "git add .",
            ],
        ],
    ])
#endif

From this we can derive that swift run swiftlint and swift run swiftFormat rely on swift packages.

Komondor can batch look in the building folder to see if there are .build/*/[name].product but not .build/*/[name] and use swift build --product [name] to built them.

See sourcekitten, swiftFormat and swiftlint:

 ~/d/p/d/Komondor  $ ls .build/x86_64-apple-macosx10.10/debug/                                                                                                          master
CYaml.build                    KomondorPackageTests.product   Result.swiftmodule             SwiftyTextTable.swiftdoc       libPackageConfig.dylib
Clang_C.build                  ModuleCache                    SWXMLHash.build                SwiftyTextTable.swiftmodule    libPackageConfig.dylib.dSYM
Commandant.build               PackageConfig.build            SWXMLHash.swiftdoc             Yams.build                     package-config-example.product
Commandant.swiftdoc            PackageConfig.product          SWXMLHash.swiftmodule          Yams.swiftdoc                  sourcekitten.product
Commandant.swiftmodule         PackageConfig.swiftdoc         ShellOut.build                 Yams.swiftmodule               swiftFormat.product
CryptoSwift.build              PackageConfig.swiftmodule      ShellOut.swiftdoc              index                          swiftlint.product
Komondor.build                 QuickSpecBase.build            ShellOut.swiftmodule           komondor
Komondor.swiftdoc              Result.build                   SourceKit.build                komondor.dSYM
Komondor.swiftmodule           Result.swiftdoc                SwiftyTextTable.build          komondor.product

Document commit integration in README directly

I just wanted to test this out, but after reading the README I wasn't sure at first how commit hooks would get setup in my project since the swift run komondor install method was only documented within the "Getting Set Up" documents, but I personally think it's the key command and should be explained right within the README.

Xcode 12.2 Error: "illegal hardware instruction swift run komondor run" and "Illegal instruction: 4 $komondor run pre-commit $gitParams"

Hello,

I am trying to integrate Komondor into the codebases I work on. After setting it up, I started getting illegal instruction errors from Komondor and am unable to get it to run in any project.

This happens both when a git-hook runs:
git commit -m "test"

Fatal error: Error raised at top level: PackageConfig.Error(reason: "Could not find a file at /var/folders/nh/x1j0l91x28z35srsgltt4scc0000gn/T/package-config - something went wrong with compilation step probably"): file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200
.git/hooks/pre-commit: line 21: 80427 Illegal instruction: 4  $komondor run pre-commit $gitParams

or when I manually try running:
swift run komondor run

Fatal error: Error raised at top level: PackageConfig.Error(reason: "Could not find a file at /var/folders/nh/x1j0l91x28z35srsgltt4scc0000gn/T/package-config - something went wrong with compilation step probably"): file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200
[1]    68843 illegal hardware instruction  swift run komondor run

Reproduction steps:

mkdir TestKomondorPackage  
cd TestKomondorPackage 

swift package init --type library
git init

The package builids and runs.
swift Build

[2/2] Merging module TestKomondorPackage

swift test

[4/4] Linking TestKomondorPackagePackageTests
Test Suite 'All tests' started at 2020-12-09 18:44:51.287
Test Suite 'TestKomondorPackagePackageTests.xctest' started at 2020-12-09 18:44:51.287
Test Suite 'TestKomondorPackageTests' started at 2020-12-09 18:44:51.288
Test Case '-[TestKomondorPackageTests.TestKomondorPackageTests testExample]' started.
Test Case '-[TestKomondorPackageTests.TestKomondorPackageTests testExample]' passed (0.062 seconds).
Test Suite 'TestKomondorPackageTests' passed at 2020-12-09 18:44:51.349.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.062 (0.062) seconds
Test Suite 'TestKomondorPackagePackageTests.xctest' passed at 2020-12-09 18:44:51.349.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.062 (0.062) seconds
Test Suite 'All tests' passed at 2020-12-09 18:44:51.349.
	 Executed 1 test, with 0 failures (0 unexpected) in 0.062 (0.063) seconds

I then modified the package.swift file to the following:

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "TestKomondorPackage",
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "TestKomondorPackage",
            targets: ["TestKomondorPackage"]),
    ],
    dependencies: [
       .package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.0"),
    ],
    targets: [
        .target(
            name: "TestKomondorPackage",
            dependencies: []),
        .testTarget(
            name: "TestKomondorPackageTests",
            dependencies: ["TestKomondorPackage"]),
    ]
)

#if canImport(PackageConfig)
    import PackageConfig

    let config = PackageConfiguration([
        "komondor": [
            "pre-commit": "swift test",
            "pre-push": "swift test"
        ],
    ])
#endif

run swift run komondor install

Fetching https://github.com/shibapm/Komondor.git
Fetching https://github.com/shibapm/PackageConfig.git
Fetching https://github.com/JohnSundell/ShellOut.git
Cloning https://github.com/shibapm/PackageConfig.git
Resolving https://github.com/shibapm/PackageConfig.git at 0.13.0
Cloning https://github.com/JohnSundell/ShellOut.git
Resolving https://github.com/JohnSundell/ShellOut.git at 2.3.0
Cloning https://github.com/shibapm/Komondor.git
Resolving https://github.com/shibapm/Komondor.git at 1.0.6
/Users/mhays118/tmp/TestKomondorPackage/.build/checkouts/PackageConfig/Sources/PackageConfig/DynamicLibraries.swift:46:37: warning: 'encodedOffset' is deprecated: encodedOffset has been deprecated as most common usage is incorrect. Use utf16Offset(in:) to achieve the same behavior.
                                return String($0.prefix(comment.encodedOffset))
                                                                ^
[21/21] Linking komondor
[Komondor] git-hooks installed

Now, I get either of the errors I mentioned above.

Environment Details:

macOS: Catalina 10.15.7 (19H15)
Swift: Apple Swift version 5.3.1 (swiftlang-1200.0.41 clang-1200.0.32.8) Target: x86_64-apple-darwin19.6.0
Xcode: Version 12.2 (12B45b)
git: 2.28.0

Attempted workarounds

Similar issues

This is similar to #28, however, the solution presented ##28 (comment), doesn't seem to work.

I've tried running the solution from that PR multiple times, same issue.

swift package reset
swift run komondor install
swift run komondor run

Tried multiple versions of Komondor

Komondor versions tested: 1.0.6, 1.05, 1.04.

All three of these versions have the same issue.

Changing the swift-tools-version

I've tried changing the swift-tools-version in package.swift to 5.3, 5.1, and 4.2.

Same issue with all these tool versions.

Bash errors

Hello, I have some bash script errors, can someone explain how to fix it.

my Package.swift file looks like this

dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.0"),
        .package(url: "https://github.com/yonaskolb/XcodeGen.git", from: "2.17.0")
    ]
)
#if canImport(PackageConfig)
    import PackageConfig

    let config = PackageConfiguration([
        "komondor": [
            "post-checkout": [
                "xcodegen generate --use-cache",
            ],
        ],
    ]).write()
#endif

error output is

[Komondor] > post-checkout xcodegen generate --use-cache
/bin/bash: line 0: export: `101f878aa6adf509f70f50fae75f9c3900b335a4': not a valid identifier
/bin/bash: line 0: export: `1': not a valid identifier
/bin/bash: xcodegen: command not found

[Komondor] > post-checkout hook failed (cannot be skipped due to Git specs)

With Swift PM error is the same

[Komondor] > post-checkout swift run xcodegen generate --use-cache
/bin/bash: line 0: export: `5920bdfe799bdb266ec00e5dd4f797111a0d7d13': not a valid identifier
/bin/bash: line 0: export: `1': not a valid identifier
/bin/bash: pod: command not found

git-lfs support for hooks?

I'm doing a little bit of investigation into git-lfs, and it appears that it also manages its installation by setting up some hooks (specifically pre-push, post-checkout, post-commit, and post-merge). It stops if komondor already installed hooks into the repo, and recommends either manually editing the hooks scripts, or doing a force overwrite.

In the interest of not having to copy-paste lines into those hook scripts, would komondor be able to detect if git-lfs hooks were already installed, and append komondor's part to the end? Or perhaps komondor could detect if git-lfs is enabled for a repo somehow, and call git-lfs automatically so that developers don't need to manually edit the hooks after installing komondor?

How to run on staged files only? [edited] not working

Is it possible to run swiftformat/swiftlint on staged files only?

There's past issues showcasing swift run swiftformat [edited swift] but utilizing that command returns error: input path cannot contain wildcards.

Discussion: how to use in collaborative environments

Interested to hear any thought from the community on how to leverage this in a large team. We have so many separate packages that we would like to automate the process of linting / formatting for each one and without people doing any extra step(s) to setup or execute anything.

I know a server based solution might work better for this use case, but I'm still very interested in exploring any possibility to implement this on the client side, for the very reasons the author of this package listed (e.g. detecting errors as early as possible, having linting and formatting amended to each commit so we have cleaner history, etc.).

I can think of 2 problems right now:

  1. Since Git ignores hooks by default, what would be the best way to share this setup and have it installed on everyone's machine without the need for them to run the install command or anything? (I'm trying to make this 100% transparent to avoid current process's pain which require the engineers to execute a couple of commands where they, especially juniors, can pretty easily forget or get them wrong)
  2. I believe this is easier but I am not very familiar with SPM's executables to confirm. Let's say we could find a solution for (1), and given we have so many packages, what would be an easy way to avoid this boilerplate in each Package.swift manifest file? Can we probably package it as a wrapper executable dependency that can be just added to every package? The goal is to be able to reuse it across different packages with minimal effort and having a centralized single configurations.

Thanks a lot!

pre-commit hook failed (add --no-verify to skip)

when I create a project,and I add package.swift for project.

here is package.swift code:

`

import PackageDescription
let package = Package(
name: "LearningGitHook",
dependencies: [
.package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.0")
],
targets: [
.target(name: "LearningGitHook", dependencies: [], path: "LearningGitHook"),
]
)
#if canImport(PackageConfig)
import PackageConfig
let config = PackageConfiguration([
"komondor": [
"pre-commit": [
"swift test",
"swift run swiftFormat .",
"swift run swiftlint autocorrect --path LearningGitHook/",
"git add ."
],
"pre-push": [
"swift test",
"swift run danger-swift local",
"swift run swiftlint"
]
],
]).write()
#end

`

when I commite code I get this error:

[Komondor] > pre-commit swift test
error: fatalError
[1/1] Planning build
[1/3] Compiling LearningGitHook AppDelegate.swift
/Users/daibaisheng/Desktop/LearningGitHook/LearningGitHook/AppDelegate.swift:8:8: error: no such module 'UIKit'
import UIKit
^
[2/3] Compiling LearningGitHook SceneDelegate.swift
/Users/daibaisheng/Desktop/LearningGitHook/LearningGitHook/AppDelegate.swift:8:8: error: no such module 'UIKit'
import UIKit
^
[3/3] Compiling LearningGitHook ViewController.swift
/Users/daibaisheng/Desktop/LearningGitHook/LearningGitHook/AppDelegate.swift:8:8: error: no such module 'UIKit'
import UIKit
^
[Komondor] > pre-commit hook failed (add --no-verify to skip)

what reason for this error,and what should I do?

Handle showing/hiding information better

Could probably steal some ideas from husky too:

~/d/p/d/danger-js  $ git commit -m "Improve the error messaging"                                                                                        3 changed files  6.1.5
husky > pre-commit (node v10.13.0)
 โ†“ Running tasks for *.@(json|md) [skipped]
   โ†’ No staged files match *.@(json|md)
 โœ” Running tasks for *.@(ts|tsx)
[master 255307b] Improve the error messaging
 1 file changed, 5 insertions(+)
~/d/p/d/danger-js  $                                                                                                                                   2 changed files  master

Support for OS Platforms 2019

running Komondor give me:

Package.swift:8:21: error: 'v13' is unavailable
  platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6)],
                    ^~~
PackageDescription.SupportedPlatform:28:27: note: 'v13' was introduced in PackageDescription 5.1
        public static var v13: PackageDescription.SupportedPlatform.IOSVersion
                          ^
Package.swift:8:35: error: 'v10_15' is unavailable
  platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6)],
                                  ^~~~~~
PackageDescription.SupportedPlatform:9:27: note: 'v10_15' was introduced in PackageDescription 5.1
        public static var v10_15: PackageDescription.SupportedPlatform.MacOSVersion
                          ^
Package.swift:8:54: error: 'v6' is unavailable
  platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6)],
                                                     ^~
PackageDescription.SupportedPlatform:37:27: note: 'v6' was introduced in PackageDescription 5.1
        public static var v6: PackageDescription.SupportedPlatform.WatchOSVersion
                          ^
Fatal error: Error raised at top level: PackageConfig.Error(reason: "Could not find a file at /var/folders/6k/_f1dpksd0nq047ybxl941y_m0000gn/T/package-config - something went wrong with compilation step probably"): file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.8.25.8/swift/stdlib/public/core/ErrorType.swift, line 200
swift -v

Apple Swift version 5.2.2 (swiftlang-1103.0.32.6 clang-1103.0.32.51)
Target: x86_64-apple-darwin19.4.0
/Applications/Xcode.app/Contents/Developer/usr/bin/lldb "--repl=-enable-objc-interop -stack-check -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -color-diagnostics"
Welcome to Apple Swift version 5.2.2 (swiftlang-1103.0.32.6 clang-1103.0.32.51).
Type :help for assistance.

Package.swift:

// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
  name: "HeartwitchKit",
  platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6)],
  products: [
    // Products define the executables and libraries produced by a package, and make them visible to other packages.
    .library(
      name: "HeartwitchKit",
      targets: ["HeartwitchKit"]
    )
  ],
  dependencies: [
    // Dependencies declare other packages that this package depends on.
    // .package(url: /* package url */, from: "1.0.0"),
    .package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.0")
  ],
  targets: [
    // Targets are the basic building blocks of a package. A target can define a module or a test suite.
    // Targets can depend on other targets in this package, and on products in packages which this package depends on.
    .target(
      name: "HeartwitchKit",
      dependencies: []
    ),
    .testTarget(
      name: "HeartwitchKitTests",
      dependencies: ["HeartwitchKit"]
    )
  ]
)

#if canImport(PackageConfig)
  import PackageConfig

  let config = PackageConfiguration([
    "komondor": [
      "pre-push": ["swift test"],
      "pre-commit": [
        "swift test",
        "pod spec lint",
        "swiftlint autocorrect && swiftformat .",
        "swiftformat --lint . && swiftlint",
        "git add ."
      ]
    ]
  ]).write()
#endif

PackageConfig dependency broken

Getting this error when attempting to install Komondor with some hooks.

/Komondor/Sources/Komondor/Commands/runner.swift:11:21: error: use of unresolved identifier 'getPackageConfig'; did you mean 'PackageConfig'?
    let pkgConfig = getPackageConfig()

Seems related to changes that have occurred in PackageConfig dependency which have removed getPackageConfig()

Error: no such module 'PackageDescription'

Swift Version 5.5.2
Komondor Version 1.1.3
Xcode Version 13.2

// swift-tools-version:5.5
import PackageDescription

let package = Package(
    name: "kult",
    products: [
        .executable(name: "app", targets: ["app-cli"]),
    ],
    dependencies: [
        .package(url: "https://github.com/shibapm/Komondor.git", from: "1.1.3"),
        .package(url: "https://github.com/kylef/Commander", from: "0.9.1"),
        .package(url: "https://github.com/kareman/SwiftShell", from: "5.1.0"),
    ],
    targets: [
        .target(name: "app-cli", dependencies: ["Commander", "SwiftShell"], path: "cli"),
    ]
)

#if canImport(PackageConfig)
import PackageConfig

let config = PackageConfiguration([
    "komondor": [
        "pre-commit": [
            "./scripts/format.sh",
        ],
    ],
]).write()
#endif

protocol type 'PackageConfig' cannot be instantiated

Hello,

I'm having trouble getting the basic setup sample to work. I used the instructions here: https://github.com/shibapm/Komondor/blob/master/Documentation/with_swiftpm.md

// swift-tools-version:5.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "xxx",
    platforms: [
        .iOS(.v11),
        .macOS(.v10_13),
        .tvOS(.v11)
    ],
    products: [
        // Products define the executables and libraries produced by a package, and make them visible to other packages.
        .library(
            name: "xxx",
            targets: ["xxx"])
    ],
    dependencies: [
        .package(url: "https://github.com/shibapm/Komondor.git", from: "1.0.0"),
        .package(url: "https://github.com/Realm/SwiftLint", from: "0.35.8")
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages which this package depends on.
        .target(
            name: "xxx",
            dependencies: []),
        .testTarget(
            name: "xxxTests",
            dependencies: ["xxx"])
    ]
)

// The settings for the git hooks for our repo
#if canImport(PackageConfig)
    import PackageConfig

    let config = PackageConfig([
        "komondor": [
            "pre-commit": [
                "swift run swiftlint --path Sources --config .swiftlint.yml"
            ]
        ]
    ])
#endif

Which results in this error

Package.swift:39:18: error: protocol type 'PackageConfig' cannot be instantiated
    let config = PackageConfig([
                 ^~~~~~~~~~~~~
Package.swift:39:32: error: missing argument label 'from:' in call
    let config = PackageConfig([
                               ^
                               from: 
Package.swift:39:32: error: argument type '[String : [String : [String]]]' does not conform to expected type 'Decoder'
    let config = PackageConfig([
                               ^
Fatal error: Error raised at top level: PackageConfig.Error(reason: "Could not find a file at /var/folders/mf/jv01kf3d3nxdjtyp9dgnx9y80000gn/T/package-config - something went wrong with compilation step probably"): file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1100.8.280/swift/stdlib/public/core/ErrorType.swift, line 200
.git/hooks/pre-commit: line 21: 21516 Illegal instruction: 4  $komondor run pre-commit

May i ask what i could be doing wrong? or is this an issue with Komondor?

Thank you!

Script doesn't exit

Hey,

Nice tool! I succesfully set up some useful hooks using it ;)

I tried to set up pre commit hook to run swiftlint which I got installed globally:

"pre-commit": [ "swiftlint" ]

The problem is the hook doesn't exit when project has a lot of warnings. When I modify swiftlint to execute it against a single file (which has less number of warnings) it exits normally. Swiftlint is working correctly when running directly from terminal. It is likely caused by shellOut in runner.swift script

Komondor blocking user-interactivity?

Hello, I believe I have a potential bug report or just a general question.

I'm trying to have a pre-commit hook that is interactive, here is a basic example:

#!/bin/sh

exec </dev/tty

while read -p "Looks like you are committing directly to master, are you sure you want to continue? (Y/n) " yn; do
  case $yn in
  [Yy]) break ;;
  [Nn])
    echo "Good call. Make a new branch."
    exit 1
    ;;
  *) echo "Please answer y (yes) or n (no):" && continue ;;
  esac
done

exec <&-

Anyways. This script works fine when entered manually to .git/hooks/pre-commit, but does not work correctly when using Komondor. It doesn't display any message, and does not respond to any text:

> ./bin/verify-commit

Please let me know if there's a workaround to this issue.

Changing directory in pre-commit hook

Is there a way to execute a bash command, like cd as part of a git hook?

My project consists of two projects, so I need to do something like this, each of them with a separate SwiftLint config

let config = PackageConfig([
    "komondor": [            
        "pre-commit": [    
            "cd MainApp",                
            "swift run swiftformat .",
            "swift run swiftlint autocorrect",
            "cd ..",
            "cd Core",
            "swift run swiftformat .",
            "swift run swiftlint autocorrect",
            "cd ..",
            "git add .",
        ],
    ],
])

But the bash command do not work, everything gets executed in the root (and fails).

Abort commit if files are modified

It was mentioned here that it might be worth while considering if aborting a commit on file modification during a pre-commit hook could be incorporated directly into Komondor.

I had a look into the code to think about how this might be integrated and at once realised there was many different ways to tackle the problem.

  • Should this applicable to all or specific hook types?
  • Presumably this should be opt in, if so how is it configured?
    • There could be another hookOptions type dictionary, this could allow for additional options to be specified
    • we could check config for additional hook configuration config["\(hook)-option"]

The following demonstrates a possible way to add staged file modification for pre-commit hook only with out any opt in/out.

import Foundation
import PackageConfig
import ShellOut

// To emulate running the command as the script woudl do:
//
// swift run komondor run [hook-name]
//
//
public func runner(logger _: Logger, args: [String]) throws {
    let pkgConfig = getPackageConfig()

    guard let hook = args.first else {
        logger.logError("[Komondor] The runner was called without a hook")
        exit(1)
    }

    guard let config = pkgConfig["komondor"] else {
        logger.logError("[Komondor] Could not find komondor settings inside the Package.swift")
        exit(1)
    }

    guard let hookOptions = config[hook] else {
        logger.logError("[Komondor] Could not find a key for '\(hook)' under the komondor settings'")
        exit(1)
    }

    var commands = [] as [String]
    if let stringOption = hookOptions as? String {
        commands = [stringOption]
    } else if let arrayOptions = hookOptions as? [String] {
        commands = arrayOptions
    }

    logger.debug("Running commands for komondor \(commands.joined())")

    do {
        let hash = try stagedChangesHash()

        try commands.forEach { command in
            print("> \(command)")
            // Simple is fine for now
            print(try shellOut(to: command))
            // Ideal:
            //   Store STDOUT and STDERR, and only show it if it fails
            //   Show a stepper like system of all commands
        }

        if hook == "pre-commit", try stagedChangesHash() != hash {
            print("Staged files modified during \(hook) hook")
            exit(1)
        }
    } catch let error as ShellOutError {
        print(error.message)
        print(error.output)
        exit(error.terminationStatus)
    } catch {
        print(error)
        exit(1)
    }
}

private func stagedChangesHash() throws -> String {
    return try shellOut(to: "git diff --cached --name-only | xargs git diff | md5")
}

I played around a bit with the different options mentioned above but I always felt a little dirty like I was adding something too specific to what is currently a very generic.

Do you have any thoughts on how this might be implemented?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.