Giter Site home page Giter Site logo

yonaskolb / xcodegen Goto Github PK

View Code? Open in Web Editor NEW
7.0K 92.0 810.0 11.76 MB

A Swift command line tool for generating your Xcode project

License: MIT License

Swift 98.99% Makefile 0.15% Shell 0.52% C 0.03% Objective-C 0.27% C++ 0.04%
swift xcode generator xcodeproject specification yaml xcodeproj cli ci

xcodegen's Issues

Add an option 'Run script only when installing'

I often use auto-increment build number script and some scripts that should invoked only when archiving.

Examples:
http://crunchybagel.com/auto-incrementing-build-numbers-in-xcode/
https://gist.github.com/sekati/3172554
https://github.com/realm/realm-cocoa/blob/master/scripts/strip-frameworks.sh

Those kind of scripts should run only when archiving (well, just personally I guess so). So I believe 'Run script only when installing' option would be nice...

Spec Includes

Ability to support spec includes. This would allow you to seperate the spec into multiple files, to for example seperate all the setting presets for sharing amongst multiple specs

Generation failed: “contents.xcworkspacedata” couldn’t be removed.

Generation fails unless App.xcodeproj/project.xcworkspace/contents.xcworkspacedata is present.

workaround:

$ mkdir LGTM.xcodeproj/project.xcworkspace
$ :> LGTM.xcodeproj/project.xcworkspace/contents.xcworkspacedata
$ xcodegen
📋  Loaded spec:
  Name: LGTM
  Targets:
    🖥  application: LGTM
    📱  framework: LGTMKit_iOS
    🖥  framework: LGTMKit_macOS
    📱  application: LGTM_iOS
⚙️  Generated project
💾  Saved project to LGTM.xcodeproj

Seeing homebrew build issues with 0.6.1

I have Xcode 9 GM installed, and have ensured that I am using them from the command-line. When I do the following homebrew commands:

        brew update
        brew tap yonaskolb/XcodeGen https://github.com/yonaskolb/XcodeGen.git
        brew install XcodeGen

then I am getting the following errors both on my local laptop and our CI servers:

Updated 2 taps (caskroom/cask, homebrew/core).
==> New Formulae
azure-cli@1
json-table
==> Updated Formulae
akamai
angular-cli
apache-opennlp
axel
azure-cli
bandcamp-dl
...
webpack
wpscan
xorriso
xtensor
you-get
youtube-dl
==> Deleted Formulae
kes
==> Tapping yonaskolb/xcodegen
Cloning into '/usr/local/Homebrew/Library/Taps/yonaskolb/homebrew-xcodegen'...
Tapped 1 formula (99 files, 2.7MB)
==> Installing xcodegen from yonaskolb/xcodegen
==> Downloading https://github.com/yonaskolb/XcodeGen/archive/0.6.1.tar.gz
==> Downloading from https://codeload.github.com/yonaskolb/XcodeGen/tar.gz/0.6.1
==> Building XcodeGen
==> swift build -c release -Xlinker -rpath -Xlinker @executable_path -Xswiftc -static-stdlib
Last 15 lines from /Users/builduser/Library/Logs/Homebrew/xcodegen/01.swift:
2017-09-18 18:59:50 +0000

swift build -c release -Xlinker -rpath -Xlinker @executable_path -Xswiftc -static-stdlib

error: manifest parse error(s):
sandbox-exec: sandbox_apply_container: Operation not permitted

If reporting this issue please do so to (not Homebrew/brew or Homebrew/core):
yonaskolb/xcodegen

/usr/local/Homebrew/Library/Homebrew/utils/github.rb:226:in `raise_api_error': curl failed! curl: (22) The requested URL returned error: 422 Unprocessable Entity (GitHub::Error)
curl: (3) <url> malformed
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:184:in `open'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:284:in `search'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:231:in `search_issues'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:244:in `issues_for_formula'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:369:in `fetch_issues'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:365:in `issues'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:419:in `dump'
	from /usr/local/Homebrew/Library/Homebrew/brew.rb:133:in `rescue in <main>'
	from /usr/local/Homebrew/Library/Homebrew/brew.rb:26:in `<main>'

Run scripts

Generate pre and post build run script build phases

Brew install does not currently work

Using the instructions from the README I currently get this:

brew install xcodegen
==> Installing xcodegen from yonaskolb/xcodegen
==> Downloading https://github.com/yonaskolb/XcodeGen/archive/0.6.1.tar.gz
Already downloaded: /Users/dbeard/Library/Caches/Homebrew/xcodegen-0.6.1.tar.gz
==> Building XcodeGen
==> swift build -c release -Xlinker -rpath -Xlinker @executable_path -Xswiftc -static-stdlib
Last 15 lines from /Users/dbeard/Library/Logs/Homebrew/xcodegen/01.swift:
2017-09-13 12:02:33 -0700

swift build -c release -Xlinker -rpath -Xlinker @executable_path -Xswiftc -static-stdlib

error: manifest parse error(s):
sandbox-exec: sandbox_apply_container: Operation not permitted

If reporting this issue please do so to (not Homebrew/brew or Homebrew/core):
yonaskolb/xcodegen

/usr/local/Homebrew/Library/Homebrew/utils/github.rb:226:in `raise_api_error': curl failed!  (GitHub::Error)
curl: (22) The requested URL returned error: 422 Unprocessable Entity
curl: (3) <url> malformed
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:184:in `open'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:284:in `search'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:231:in `search_issues'
	from /usr/local/Homebrew/Library/Homebrew/utils/github.rb:244:in `issues_for_formula'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:369:in `fetch_issues'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:365:in `issues'
	from /usr/local/Homebrew/Library/Homebrew/exceptions.rb:419:in `dump'
	from /usr/local/Homebrew/Library/Homebrew/brew.rb:133:in `rescue in <main>'
	from /usr/local/Homebrew/Library/Homebrew/brew.rb:26:in `<main>'

Project with nested xcconfigs included in sources breaks

Currently if I generate a project that has a xcconfig set for the configuration, and also includes the directory the xcconfig file lives in in the sources of a target, the project ends up in a broken state:

image

This is the configuration for this case:

name: Project
configs:
  Debug: debug
configFiles:
  Debug: xcconfigs/debug.xcconfig
targets:
  Project:
    type: application
    platform: iOS
    sources: xcconfigs

Sample project (with the generated project) as an example: XcodeGenTest.zip

Define testTarget

Add the ability to add a TestTargetID in project attributes
You can already set the TEST_TARGET_NAME build setting but that doesn't change the "Host application" in the Xcode UI

Inline script parsing is broken

example xcodegen.yml:

name: FooBar
targets:
  - name: FooBar
    type: application
    platform: iOS
    sources: 
      - Sources
    postbuildScripts:
      - path: Scripts/strip-frameworks.sh
        name: Strip Unused Architectures from Frameworks
        runOnlyWhenInstalling: true

Xcode now says Project *.xcodeproj cannot be opened because the project file cannot be parsed.. Script used above is: https://raw.githubusercontent.com/realm/realm-cocoa/master/scripts/strip-frameworks.sh
Although in the example I'm specifying path of the script, writing the script as string in yamls causes the same problem naturally.

Now, here is the concerned excerpt from generated project:

/* Begin PBXShellScriptBuildPhase section */
        SSBP35707201 /* Run Script */ = {
            isa = PBXShellScriptBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            inputPaths = (
            );
            name = "Strip Unused Architectures from Frameworks";
            outputPaths = (
            );
            runOnlyForDeploymentPostprocessing = 1;
            shellPath = /bin/sh;
            shellScript = "################################################################################\n#\n# Copyright 2015 Realm Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n################################################################################\n\n# This script strips all non-valid architectures from dynamic libraries in\n# the application's `Frameworks` directory.\n#\n# The following environment variables are required:\n#\n# BUILT_PRODUCTS_DIR\n# FRAMEWORKS_FOLDER_PATH\n# VALID_ARCHS\n# EXPANDED_CODE_SIGN_IDENTITY\n\n\n# Signs a framework with the provided identity\ncode_sign() {\n  # Use the current code_sign_identitiy\n  echo \"Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}\"\n  echo \"/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements $1\"\n  /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"\n}\n\n# Set working directory to product’s embedded frameworks \ncd \"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\n\nif [ \"$ACTION\" = \"install\" ]; then\n  echo \"Copy .bcsymbolmap files to .xcarchive\"\n  find . -name '*.bcsymbolmap' -type f -exec mv {} \"${CONFIGURATION_BUILD_DIR}\" \;\nelse\n  # Delete *.bcsymbolmap files from framework bundle unless archiving\n  find . -name '*.bcsymbolmap' -type f -exec rm -rf \"{}\" +\;\nfi\n\necho \"Stripping frameworks\"\n\nfor file in $(find . -type f -perm +111); do\n  # Skip non-dynamic libraries\n  if ! [[ \"$(file \"$file\")\" == *\"dynamically linked shared library\"* ]]; then\n    continue\n  fi\n  # Get architectures for current file\n  archs=\"$(lipo -info \"${file}\" | rev | cut -d ':' -f1 | rev)\"\n  stripped=\""\n  for arch in $archs; do\n    if ! [[ \"${VALID_ARCHS}\" == *\"$arch\"* ]]; then\n      # Strip non-valid architectures in-place\n      lipo -remove \"$arch\" -output \"$file\" \"$file\" || exit 1\n      stripped=\"$stripped $arch\"\n    fi\n  done\n  if [[ \"$stripped\" != \"" ]]; then\n    echo \"Stripped $file of architectures:$stripped\"\n    if [ \"${CODE_SIGNING_REQUIRED}\" == \"YES\" ]; then\n      code_sign \"${file}\"\n    fi\n  fi\ndone\n";
        };
/* End PBXShellScriptBuildPhase section */

Generating Playgrounds?

I am working on a a Swift project and I need to be able to generate a Playground inserting my own file into it to get some autocomplete

Support xcconfig

Motivation

Auto apply xcconfig configurations like this.
xcode-configuration

Current Problems

I notice documentations do mention about xcconfig but looks like it's not working as expected.

  • Setting configFiles does not affect anything. (Bug? or maybe my spec is wrong)
  • There is no way to set base xcconfigs for PBXProject.
  • xcconfigs not being added to project

Proposal

So this is my proposal.

  • Support baseConfiguration for PBXProj
  • Rename target's configFiles with baseConfigurations for consistency.
  • (Optional) Rename configs to configurations since it looks like xcconfig and is misleading.
name: MyProject
configurations:
  Debug:
    baseConfiguration: configs/Debug.xcconfig
  OTA:
    baseConfiguration: configs/OTA.xcconfig
  Release:
    baseConfiguration: configs/Release.xcconfig
targets:
  MyApp:
    type: application
    platform: iOS
    sources: Sources/MyApp
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: jp.toshi0383.hello
    baseConfigurations:
      Debug: configs/MyApp-Debug.xcconfig
      OTA: configs/MyApp-OTA.xcconfig
      Release: configs/MyApp-Release.xcconfig

If you guys feel happy with this outline, I can start working on a PR. 💪

Setup repository labels

I find it useful to include priority, difficulty and type useful to organize issues. It's also good for welcoming contributors in the project (e.g. they can start with the simple issues to get some context on the project).

This is the setup that I've used for xcodeproj, what do you think @yonaskolb?

image

Way to create universal framework target

lgtm $ xcodegen-debug
📋  Loaded spec:
  Name: LGTM
  Targets:
    🖥  application: LGTM
    📱  framework: LGTMKit_iOS
    🖥  framework: LGTMKit_macOS
    📺  framework: LGTMKit_tvOS
    ⌚️  framework: LGTMKit_watchOS
    📱  application: LGTM_iOS
2 Spec validations errors:
	- Target "LGTM" has invalid dependency: "LGTMKit"
	- Target "LGTM_iOS" has invalid dependency: "LGTMKit"

How could I generate an empty(buildSettings = { };) framework target?
I don't want each target for every platform.

Spec generation

Should be able to generate a spec from an existing project for easy migration

Link and embed all nested Carthage dependencies for macOS

Motivation

With spec like this,

targets:
  LGTM:
    platform: macOS
    type: application
    sources: LGTM
    dependencies:
      - target: LGTMKit_macOS
  LGTMKit:
    type: framework
    platform: [iOS, macOS]
    sources: LGTMKit
    dependencies:
      - carthage: APIKit

Generate xcodeproj like this.
screen shot 2017-10-14 at 5 49 12

Related: #82

'Shared' scheme option

Currently, if you have more than one configs xcodegen would make schemes Shared.
If there is an option to make a scheme Shared checked on, it would be great.

Generates non-parsable xcodeproj when a file name contains '@'

Using XcodeGen 0.3.0 and Xcode 8.3.3.

If one of files name contains "@", xcodegen generates non-parsable project by Xcode, somehow.
So it cannot deal with retina filenames such as [email protected], [email protected].
Adding those kind of assets to *.xcassets wouldn't really solve this problem as I intend not to use it, since using xcassets forces UIImage to be cached.

example:

name: FooBar
targets:
  - name: FooBar
    type: application
    platform: iOS
    sources: 
      - Assets

If "Assets" directory or its subdirectory contains a file that has "@" in its name, Xcode cannot parse generated project.
The other tool, struct, can correctly generates a project in the same situation, just fwiw.

Cross platform frameworks

This is by specifying multiple platforms for a target in the spec, which would generate multiple targets, each with a different platform

Generate bundle identifier

Hello,
Thanks for your this great solution that I really wanted.

Today I tried to generate my project using XcodeGen.
I faced the problem that Xcode shows the message This app was unable to be installed after build the project for the simulator.

I reproduced it on TestProject in this repository.

  1. xcodegen --spec spec.yml
  2. Open GeneratedProject.xcodeproj
  3. Select the simulator like iPhone 8 Plus
  4. Run

It can be fixed by removing frameworks from Copy Files in Build Phases or remove the line https://github.com/yonaskolb/XcodeGen/blob/master/Sources/XcodeGenKit/PBXProjGenerator.swift#L236

I don't know this is correct way to fix it. But do frameworks need to be copied when these add as Embedded Framework?

Clear default build settings

It would be nice if there were a way to clear the default settings XcodeGen provides. This is useful if you define all your settings in xcconfig files, so when you generate the project, you don't want its default settings to shadow yours. I almost expected it to with this configuration:

name: Project
settings:
  base: []
targets:
  Project:
    type: application
    platform: iOS

But I understand these base settings are just additive to the project. In the meantime I might use xcodeproj to wipe these settings out after project generation.

Add localized resources to a variant group

If a storyboard localized for some language, it should be grouped into one variant group.

2017-09-25 22 43 05

XcodeGen generates references same level.

2017-09-25 22 40 49

expectation

2017-09-24 18 02 29

VG1473702401 /* Main.storyboard */ = {
	isa = PBXVariantGroup;
	children = (
		FR3676338402 /* Base */,
	);
	name = Main.storyboard;
	sourceTree = "<group>";
};
VG2365450901 /* Main.strings */ = {
	isa = PBXVariantGroup;
	children = (
		FR7070045401 /* en */,
	);
	name = Main.strings;
	sourceTree = "<group>";
};

should be

VG1473702401 /* Main.storyboard */ = {
	isa = PBXVariantGroup;
	children = (
		FR3676338402 /* Base */,
		FR7070045401 /* en */,
	);
	name = Main.storyboard;
	sourceTree = "<group>";
};

Command for printing the combined build settings of a spec

This would add a command that would print out the specific settings that would be applied to a target for a specific config. This would combine

  • target build settings
  • target xcconfig file
  • project build settings
  • project xcconfig file

To begin with this wouldn't include settings that are applied by the top most level (the SDK) as we don't have easy access to that.

Generate basic projects without a spec file

I just had an idea. What do you think about being able to generate simple projects from the command line with XcodeGen. Something like:

xcodegen init -platform iOS -name MyTest --no-tests

That would create the xcodegen.yml file and generate the project from it. How does that sound? @yonaskolb

Change targets from list to map

At the moment targets is list. That was done to preserve the order of generated targets in the xcode project.
There would be some upsides to making it a map of names to targets however:

  • the include feature could edit and merge targets by name
  • more natural yaml styl
  • enforce the target name
  • better visual seperation

The points are very minor other than the first one which is a real consideration.
Is having the order of targets in the project worth it? Thoughts anyone?

Here is a visual difference

list - Array

targets:
  - name: MyTarget
    platform: iOS
    type: application
  - name: MyFramework
    platform: iOS
    type: framework

map - Dictionary

targets:
  MyTarget:
    platform: iOS
    type: application
  MyFramework:
    platform: iOS
    type: framework 

In either case targets in the ProjectSpec struct would still be an array, this just affects yaml

Support installation with Homebrew

Installation can be simplified by using Homebrew. The purpose of this issue is to provide a Homebrew formula that tells Homebrew how to install XcodeGen

Add Frameworks as Embedded Binaries

I often use Swift dynamic framework and specify them in xcodegen.yml like below:

name: Foo
targets:
  - name: Bar
    type: application
    platform: iOS
    sources: 
      - Sources
    dependencies:
      - framework: Frameworks/Foo.framework
      - framework: Frameworks/Bar.framework

XcodeGen correctly handle this and add those frameworks to Linked Frameworks and Libraries, but it seems we do not have an option to have them as Embedded Binaries?

Adding common Localizable.strings files

I have these Localizable settings under resources/language directory.

resources/language/
├── Base.lproj
│   └── Localizable.strings
└── ja.lproj
    └── Localizable.strings

I want to import them into separated target.

targets:
  LGTM:
    platform: macOS
    type: application
    sources:
      - LGTM
      - resources/language
  LGTM_iOS:
    platform: iOS
    type: application
    sources:
      - LGTM_iOS
      - resources/language

This spec ends-up with the files only added to LGTM target.
screen shot 2017-09-30 at 7 29 25

Also on Xcode, both files are displayed as same name, so maybe it's better if we could display the parent directory names for Localizable.strings.

File watcher

An optional file watcher that automatically regenerates the project when file system changes. Should be able to specify watched files with a glob

The file "Foo.swift" couldn’t be opened with absolute paths

With this config:

name: Project
targets:
  Project:
    type: application
    platform: iOS
    sources:
      - Sources/foo.swift

And this file structure:

.
├── Sources
│   └── Foo.swift
└── project.yml

1 directory, 2 files

xcodegen fails with this error message:

📋  Loaded spec:
  Name: Project
  Targets:
    📱  application: Project
Generation failed: The file “Foo.swift” couldn’t be opened.

Should you be able to reference a path like this absolutely? This is useful for when you have more complex file structures where sources and tests are nearby, meaning you can't reference the entire directory or you'll include test files in the non-test target.

Sample project: XcodeGenTest2.zip

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.