diff --git a/.github/workflows/sync-ai-config.yml b/.github/workflows/sync-ai-config.yml index 6b3771a..29624f6 100644 --- a/.github/workflows/sync-ai-config.yml +++ b/.github/workflows/sync-ai-config.yml @@ -26,8 +26,9 @@ jobs: if: github.event_name == 'schedule' uses: CreativeCodersTeam/ai-base/.github/workflows/sync-ai-config.yml@main with: - languages: 'csharp' - ai-systems: 'copilot,claude,junie' + languages: ${{ vars.AI_LANGUAGES || 'csharp,superpowers' }} + ai-systems: ${{ vars.AI_SYSTEMS || 'copilot,claude,junie' }} + project-markdown-file: ${{ vars.AI_PROJECT_MARKDOWN_FILE || '' }} ai-base-version: 'main' create-pull-request: true @@ -35,8 +36,9 @@ jobs: if: github.event_name == 'workflow_dispatch' uses: CreativeCodersTeam/ai-base/.github/workflows/sync-ai-config.yml@main with: - languages: 'csharp' - ai-systems: 'copilot,claude,junie' + languages: ${{ vars.AI_LANGUAGES || 'csharp,superpowers' }} + ai-systems: ${{ vars.AI_SYSTEMS || 'copilot,claude,junie' }} + project-markdown-file: ${{ vars.AI_PROJECT_MARKDOWN_FILE || '' }} ai-base-version: ${{ inputs.ai-base-version }} create-pull-request: ${{ inputs.create-pull-request }} clear-ai-configs: ${{ inputs.clear-ai-configs }} diff --git a/README.md b/README.md index 3453459..ae766e8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,113 @@ # macsynkker -Tool for managing macOS settings and homebrew software + +[![Build Status](https://img.shields.io/github/actions/workflow/status/CreativeCodersTeam/macsynkker/main.yml?style=flat-square&label=Build)](https://github.com/CreativeCodersTeam/macsynkker/actions) +![.NET](https://img.shields.io/badge/.NET-10-512bd4?style=flat-square) +![macOS](https://img.shields.io/badge/Platform-macOS-000?style=flat-square&logo=apple) +[![License](https://img.shields.io/badge/License-Apache_2.0-blue?style=flat-square)](LICENSE) + +> Synchronize Homebrew packages and macOS user defaults across machines + +macsynkker is a .NET CLI tool that exports and imports your Homebrew formulae, casks, and macOS user defaults so you can +replicate your setup on a new Mac or keep multiple machines in sync. + +## Features + +- **Homebrew Export/Import** — Serialize installed formulae and casks to a JSON file and restore them on another + machine, including tap management +- **macOS User Defaults Export/Import** — Back up and restore per-domain `defaults` settings as plist files +- **Homebrew Upgrade** — Upgrade installed formulae and casks with configurable options +- **Dependency-aware Export** — Optionally include or exclude packages installed as dependencies + +## Prerequisites + +- macOS (the CLI refuses to run on other platforms) +- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) +- [Homebrew](https://brew.sh/) (for Homebrew-related features) + +## Installation + +### As a .NET global tool + +```bash +dotnet tool install -g CreativeCoders.MacSynkker.Cli +``` + +### From a GitHub release + +Download the latest `MacSynkker.Cli.tar.gz` from +the [Releases](https://github.com/CreativeCodersTeam/macsynkker/releases) page and extract it. + +## Usage + +The CLI is invoked as `mcs`. Run it without arguments to see available commands: + +```bash +mcs +``` + +### Export Homebrew packages + +```bash +mcs brew export --file ~/brew-packages.json +``` + +### Import Homebrew packages on another machine + +```bash +mcs brew import --file ~/brew-packages.json +``` + +### Export macOS user defaults + +```bash +mcs defaults export --domain com.apple.finder --file ~/finder-defaults.plist +``` + +> [!TIP] +> Store the exported JSON/plist files in a Git repository or cloud drive to keep your machines in sync. + +## Project structure + +``` +source/ + CreativeCoders.MacOS.Core/ Core macOS utilities (program locator) + CreativeCoders.MacOS.HomeBrew/ Homebrew query, install, upgrade, export, import + CreativeCoders.MacOS.UserDefaults/ macOS user defaults export/import + CreativeCoders.MacSynkker.Cli/ CLI entry point (mcs) +samples/ + SampleConsoleApp/ Sample showing library usage +tests/ + CreativeCoders.MacOS.HomeBrew.Tests/ Unit tests for Homebrew library + CreativeCoders.MacOS.UserDefaults.Tests/ +build/ Cake-based build system +``` + +## Development + +```bash +git clone https://github.com/CreativeCodersTeam/macsynkker.git +cd macsynkker +``` + +### Build + +```bash +dotnet build +``` + +### Run tests + +```bash +dotnet test +``` + +## CI/CD pipeline + +The CI/CD pipeline uses a [Cake](https://cakebuild.net/)-based build system. + +```bash +# Build targets +sh ./build.sh -t test +sh ./build.sh -t publish +sh ./build.sh -t createdistpackages +``` diff --git a/macSynkker.sln b/macSynkker.sln index d1448f9..ddbe8aa 100644 --- a/macSynkker.sln +++ b/macSynkker.sln @@ -10,8 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{A9CE4F source\Directory.Build.props = source\Directory.Build.props EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__ai", "__ai", "{3CA6C44F-1F49-4D5D-A26F-92046B51B4F5}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__global", "__global", "{BF2B8E40-4D03-41A1-8ABD-7AD1A33D5B53}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig @@ -29,13 +27,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cli", "cli", "{1C050676-278 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.MacSynkker.Cli", "source\CreativeCoders.MacSynkker.Cli\CreativeCoders.MacSynkker.Cli.csproj", "{4B29C32B-9BAF-471E-B83A-D7F5735F27B8}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "copilot", "copilot", "{083C21F2-8C37-4E30-9CA8-82AAD4F77DD9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "junie", "junie", "{16659358-8B04-4FAD-80A0-467982B00A9D}" - ProjectSection(SolutionItems) = preProject - .junie\guidelines.md = .junie\guidelines.md - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.MacOS.UserDefaults", "source\CreativeCoders.MacOS.UserDefaults\CreativeCoders.MacOS.UserDefaults.csproj", "{BFADD6C0-DB57-476C-A168-A1AE62DF4668}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.MacOS.HomeBrew", "source\CreativeCoders.MacOS.HomeBrew\CreativeCoders.MacOS.HomeBrew.csproj", "{16476670-C168-4DDD-B6A5-069F402E6960}" @@ -61,11 +52,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ci", "ci", "{076341D1-E2B7- .github\workflows\pull-request.yml = .github\workflows\pull-request.yml .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\release.yml = .github\workflows\release.yml - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "instructions", "instructions", "{3CAC9757-F7D3-4A37-9820-B8755EF7FF3F}" - ProjectSection(SolutionItems) = preProject - .github\instructions\csharp.instructions.md = .github\instructions\csharp.instructions.md + .github\workflows\sync-ai-config.yml = .github\workflows\sync-ai-config.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{1A70000D-DAC9-4D34-9306-7914CC837B05}" @@ -189,8 +176,6 @@ Global {C033DF64-285B-4C44-AFFC-400878C92C73} = {A9CE4FEF-F010-408C-9B5E-F00DC960A792} {1C050676-278A-4DD4-8396-A27BA85A89E6} = {C033DF64-285B-4C44-AFFC-400878C92C73} {4B29C32B-9BAF-471E-B83A-D7F5735F27B8} = {1C050676-278A-4DD4-8396-A27BA85A89E6} - {083C21F2-8C37-4E30-9CA8-82AAD4F77DD9} = {3CA6C44F-1F49-4D5D-A26F-92046B51B4F5} - {16659358-8B04-4FAD-80A0-467982B00A9D} = {3CA6C44F-1F49-4D5D-A26F-92046B51B4F5} {BFADD6C0-DB57-476C-A168-A1AE62DF4668} = {A9CE4FEF-F010-408C-9B5E-F00DC960A792} {16476670-C168-4DDD-B6A5-069F402E6960} = {A9CE4FEF-F010-408C-9B5E-F00DC960A792} {6C7AB20D-847C-48A0-92EF-C45C621E11F0} = {A9CE4FEF-F010-408C-9B5E-F00DC960A792} @@ -198,7 +183,6 @@ Global {BF53FB30-8068-426D-BC06-B692E45CE94D} = {D3F213BB-A6EC-4DDA-9C43-59094DF2FD09} {5D00B0B9-E9B4-423C-AFCF-0F7CB21B2A78} = {9A2D709F-395D-4373-9B73-FDAE4E606B64} {076341D1-E2B7-47A8-AB79-78BFD7DBA646} = {BF2B8E40-4D03-41A1-8ABD-7AD1A33D5B53} - {3CAC9757-F7D3-4A37-9820-B8755EF7FF3F} = {083C21F2-8C37-4E30-9CA8-82AAD4F77DD9} {1A70000D-DAC9-4D34-9306-7914CC837B05} = {BF2B8E40-4D03-41A1-8ABD-7AD1A33D5B53} {9D2DCA2F-3A9B-4258-92FB-91FDCEB714A0} = {D3F213BB-A6EC-4DDA-9C43-59094DF2FD09} EndGlobalSection