diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..66ea1c2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.json] +insert_final_newline = false + +[*.md] +max_line_length = off +insert_final_newline = false +trim_trailing_whitespace = false + +[*.{yaml,yml}] +indent_size = 2 diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 0000000..4f57edd --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,19 @@ +## 概要 + + + +## 作業内容 +### 完了条件 +* TODO + +### 想定される範囲 +* TODO + +### 対応しないこと +* TODO + + + +## 備考 +### 参考文献 +* TODO diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..40f8c42 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,27 @@ +* [ ] 新規追加 +* [ ] 既存改良 +* [ ] 不具合修正 + +## 概要 + + + +## 変更点 +### 追加 +* TODO + +### 削除 +* TODO + +### 修正 +* TODO + + + +## 確認事項 +* [ ] TODO + + + +## 備考 +* TODO diff --git a/.github/workflows/create-merge-pr.yml b/.github/workflows/create-merge-pr.yml new file mode 100644 index 0000000..0265eee --- /dev/null +++ b/.github/workflows/create-merge-pr.yml @@ -0,0 +1,37 @@ +name: Create merge pull request + +on: + pull_request: + types: + - closed + branches-ignore: + - 'released' + paths: + - 'Build.xcconfig' + workflow_dispatch: + +jobs: + create-merge-pr: + if: >- + github.event_name == 'workflow_dispatch' || + (github.event.pull_request.merged == true && startsWith(github.event.pull_request.title, 'アプリバージョン更新')) + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + # https://github.com/actions/checkout + - uses: actions/checkout@v4 + + # https://github.com/ruby/setup-ruby + - uses: ruby/setup-ruby@v1 + + - name: Pick version name + id: app-version + run: | + echo "$(ruby scripts/pick-version-name.rb)" > TMP_LOG + echo "message=Merge $(cat TMP_LOG)" >> "$GITHUB_OUTPUT" + + - name: Create pull request + run: gh pr create --base released --title "${{ steps.app-version.outputs.message }}" --body "" + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..eee8334 --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,36 @@ +name: Create release + +on: + push: + branches: + - released + workflow_dispatch: + +jobs: + create-release: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + # https://github.com/actions/checkout + - uses: actions/checkout@v4 + + # https://github.com/ruby/setup-ruby + - uses: ruby/setup-ruby@v1 + + - name: Pick version name + id: app-version + run: | + echo "$(ruby scripts/pick-version-name.rb)" > TMP_LOG + echo "version-name=$(cat TMP_LOG)" >> "$GITHUB_OUTPUT" + + - name: Set git tag + run: | + echo "${{ steps.app-version.outputs.version-name }}" > TAG_NAME + git tag "$(cat TAG_NAME)" + git push origin "$(cat TAG_NAME)" + + - name: Create release + run: gh release create "${{ steps.app-version.outputs.version-name }}" --generate-notes --title "${{ steps.app-version.outputs.version-name }}" + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/update-app-version.yml b/.github/workflows/update-app-version.yml new file mode 100644 index 0000000..dadee0f --- /dev/null +++ b/.github/workflows/update-app-version.yml @@ -0,0 +1,55 @@ +name: Update app version + +on: + workflow_dispatch: + inputs: + versionMajor: + description: 'バージョン情報: major' + required: true + type: string + versionMinor: + description: 'バージョン情報: minor' + required: true + type: string + versionPatch: + description: 'バージョン情報: patch' + required: true + type: string + +jobs: + update-app-version: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + # https://github.com/actions/checkout + - uses: actions/checkout@v4 + + # https://github.com/ruby/setup-ruby + - uses: ruby/setup-ruby@v1 + + - name: Update app version + id: app-version + run: | + ruby scripts/set-version.rb ${{ inputs.versionMajor }} ${{ inputs.versionMinor }} ${{ inputs.versionPatch }} + echo "$(ruby scripts/pick-version-name.rb)" > TMP_LOG + echo "branch-name=feature/update_$(cat TMP_LOG)" >> "$GITHUB_OUTPUT" + echo "message=アプリバージョン更新: $(cat TMP_LOG)" >> "$GITHUB_OUTPUT" + + - name: Setup git settings + run: | + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "GitHub Actions" + + - name: Git push + run: | + git switch -c ${{ steps.app-version.outputs.branch-name }} + git add Build.xcconfig + git commit -m "${{ steps.app-version.outputs.message }}" + git push --set-upstream origin ${{ steps.app-version.outputs.branch-name }} + + - name: Create pull request + run: gh pr create --title "${{ steps.app-version.outputs.message }}" --body "" + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/.gitignore b/.gitignore index bd39a7b..e2baa30 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ - -# Created by https://www.toptal.com/developers/gitignore/api/macos,swift,xcode -# Edit at https://www.toptal.com/developers/gitignore?templates=macos,swift,xcode - +############# ### macOS ### +############# # General .DS_Store .AppleDouble @@ -31,7 +29,73 @@ Network Trash Folder Temporary Items .apdisk + + +############ +### Ruby ### +############ +*.gem +*.rbc +/.config +/coverage/ +/InstalledFiles +/pkg/ +/spec/reports/ +/spec/examples.txt +/test/tmp/ +/test/version_tmp/ +/tmp/ + +# Used by dotenv library to load environment variables. +# .env + +# Ignore Byebug command history file. +.byebug_history + +## Specific to RubyMotion: +.dat* +.repl_history +build/ +*.bridgesupport +build-iPhoneOS/ +build-iPhoneSimulator/ + +## Specific to RubyMotion (use of CocoaPods): +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# vendor/Pods/ + +## Documentation cache and generated files: +/.yardoc/ +/_yardoc/ +/doc/ +/rdoc/ + +## Environment normalization: +/.bundle/ +/vendor/bundle +/lib/bundler/man/ + +# for a library or gem, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# Gemfile.lock +# .ruby-version +# .ruby-gemset + +# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +.rvmrc + +# Used by RuboCop. Remote config files pulled in from inherit_from directive. +# .rubocop-https?--* + + + +############# ### Swift ### +############# # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore @@ -69,11 +133,13 @@ timeline.xctimeline playground.xcworkspace # Swift Package Manager +# # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. # Packages/ # Package.pins # Package.resolved # *.xcodeproj +# # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata # hence it is not needed unless you have added a package configuration file to your project # .swiftpm @@ -81,24 +147,29 @@ playground.xcworkspace .build/ # CocoaPods +# # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# # Pods/ +# # Add this line if you want to avoid checking in source code from the Xcode workspace # *.xcworkspace # Carthage +# # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build/ -# Add this lines if you are using Accio dependency management (Deprecated since Xcode 12) -# Dependencies/ -# .accio/ +# Accio dependency management +Dependencies/ +.accio/ # fastlane +# # It is recommended to not store the screenshots in the git repo. # Instead, use fastlane to re-generate the screenshots whenever they are needed. # For more information about the recommended setup visit: @@ -110,26 +181,26 @@ fastlane/screenshots/**/*.png fastlane/test_output # Code Injection +# # After new code Injection tools there's a generated folder /iOSInjectionProject # https://github.com/johnno1962/injectionforxcode iOSInjectionProject/ -### Xcode ### -# Xcode -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - - -## Gcc Patch -/*.gcno +########################## +### Visual Studio Code ### +########################## +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets -### Xcode Patch ### -*.xcodeproj/* -!*.xcodeproj/project.pbxproj -!*.xcodeproj/xcshareddata/ -!*.xcworkspace/contents.xcworkspacedata -**/xcshareddata/WorkspaceSettings.xcsettings +# Local History for Visual Studio Code +.history/ -# End of https://www.toptal.com/developers/gitignore/api/macos,swift,xcode +# Built Visual Studio Code Extensions +*.vsix diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..15a2799 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.3.0 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a9ecf5d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "editorconfig.editorconfig", + "github.vscode-github-actions", + "github.vscode-pull-request-github", + "jebbs.plantuml", + "redhat.vscode-yaml", + "shopify.ruby-lsp", + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0cb676c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "develop" + ], + "rubyLsp.rubyVersionManager": "rbenv", +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..658952a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,35 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "アプリバージョン更新", + "type": "shell", + "command": "ruby", + "args": [ + "scripts/set-version.rb", + "${input:versionMajor}", + "${input:versionMinor}", + "${input:versionPatch}", + ] + } + ], + "inputs": [ + { + "id": "versionMajor", + "type": "promptString", + "description": "バージョン情報: major" + }, + { + "id": "versionMinor", + "type": "promptString", + "description": "バージョン情報: minor" + }, + { + "id": "versionPatch", + "type": "promptString", + "description": "バージョン情報: patch" + } + ] +} \ No newline at end of file diff --git a/Build.xcconfig b/Build.xcconfig new file mode 100644 index 0000000..8f96c14 --- /dev/null +++ b/Build.xcconfig @@ -0,0 +1,5 @@ +// アプリバージョンの整理番号 +APP_VERSION_CODE = 1 + +// アプリバージョンの文字表記 +APP_VERSION_NAME = 1.0 diff --git a/README.md b/README.md index 7ebf0f5..f8261f4 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,67 @@ -# 株式会社ゆめみ iOS エンジニアコードチェック課題 +# GitHub リポジトリ検索アプリ(お題作成: 株式会社ゆめみさん) +## はじめに +* **本リポジトリは[yumemi-inc/ios-engineer-codecheck] をベースに、アレンジを加えたものとなります** +* アプリ改良のマイルストーン + * [完了](https://github.com/tshion/yumemi-inc_ios-engineer-codecheck/milestones?direction=asc&sort=title&state=closed) + * [進行中](https://github.com/tshion/yumemi-inc_ios-engineer-codecheck/milestones?direction=asc&sort=title&state=open) -## 概要 +
+※個人的な勉強が目的のため、状況設定を追加しました -本プロジェクトは株式会社ゆめみ(以下弊社)が、弊社に iOS エンジニアを希望する方に出す課題のベースプロジェクトです。本課題が与えられた方は、下記の説明を詳しく読んだ上で課題を取り組んでください。 +* アプリは他のIT 企業によってリリースされているが、大人の事情で、私が所属する企業がアプリを引き継ぐことになった +* アプリの発注元はプロダクト改良に積極的で、技術面の改良は我々に一任されており、さらに予算もついている + * 補足: もし消極的だった場合、予算と睨めっこしながらバグフィックスをこなす話となってしまうので、本リポジトリではその制限を設けない +* 前述の条件のため、アプリの改良はチームを組んで対応することになったので、タスク管理を行う必要がある +
-新卒/未経験者エンジニアの場合、本リファクタリングの通常課題の代わりに、[新規アプリ作成の特別課題](https://yumemi-ios-junior-engineer-codecheck.app.swift.cloud)も選択できますので、ご自身が得意と感じる方を選んでください。特別課題を選んだ場合、通常課題の取り組みは不要です。新規アプリ作成の課題の説明を詳しく読んだ上で課題を取り組んでください。 -## アプリ仕様 -本アプリは GitHub のリポジトリーを検索するアプリです。 +## アプリについて +GitHub リポジトリを検索できるiOS アプリ。 -![動作イメージ](README_Images/app.gif) +| 1.0.x | +| :---: | +| | -### 環境 +※アプリを試したい場合は、`released` ブランチのものをローカルでビルドしてください -- IDE:基本最新の安定版(本概要更新時点では Xcode 15.2) -- Swift:基本最新の安定版(本概要更新時点では Swift 5.9) -- 開発ターゲット:基本最新の安定版(本概要更新時点では iOS 17.2) -- サードパーティーライブラリーの利用:オープンソースのものに限り制限しない -### 動作 -1. 何かしらのキーワードを入力 -2. GitHub API(`search/repositories`)でリポジトリーを検索し、結果一覧を概要(リポジトリ名)で表示 -3. 特定の結果を選択したら、該当リポジトリの詳細(リポジトリ名、オーナーアイコン、プロジェクト言語、Star 数、Watcher 数、Fork 数、Issue 数)を表示 +## もしアプリ開発をやってみたくなったら +下記を参照してください。 -## 課題取り組み方法 +* [CONTRIBUTING](./docs/CONTRIBUTING.md) + * 開発環境について + * 開発作業の流れ + * レビュー方針 + * リリースの流れ + * 備考 +* [先方からの要求事項](https://github.com/tshion/yumemi-inc_android-engineer-codecheck/blob/develop/docs/Requirements.md) (※別サイト) + * アプリの使い方 + * システム関連 +* [仕様メモ](https://github.com/tshion/yumemi-inc_android-engineer-codecheck/blob/develop/docs/SpecNotes.md) (※別サイト) + * アプリ関連 + * 画面構成とデザイン + * データの取り扱い方針 + * バージョニング + * ログの取り扱い方針 + * 外部システム関連 + * GitHub REST API + * クラッシュ分析ツール + * 備考 + * データセーフティ +* 設計メモ + * TODO +* 各パッケージのREADME + * TODO -Issues を確認した上、本プロジェクトを [**Duplicate** してください](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/duplicating-a-repository)(Fork しないようにしてください。必要ならプライベートリポジトリーにしても大丈夫です)。今後のコミットは全てご自身のリポジトリーで行ってください。 -コードチェックの課題 Issue は全て [`課題`](https://github.com/yumemi/ios-engineer-codecheck/milestone/1) Milestone がついており、難易度に応じて Label が [`初級`](https://github.com/yumemi/ios-engineer-codecheck/issues?q=is%3Aopen+is%3Aissue+label%3A初級+milestone%3A課題)、[`中級`](https://github.com/yumemi/ios-engineer-codecheck/issues?q=is%3Aopen+is%3Aissue+label%3A中級+milestone%3A課題+) と [`ボーナス`](https://github.com/yumemi/ios-engineer-codecheck/issues?q=is%3Aopen+is%3Aissue+label%3Aボーナス+milestone%3A課題+) に分けられています。課題の必須/選択は下記の表とします: -| | 初級 | 中級 | ボーナス -|--:|:--:|:--:|:--:| -| 新卒/未経験者 | 必須 | 選択 | 選択 | -| 中途/経験者 | 必須 | 必須 | 選択 | +## 関連リンク +* 複製元リポジトリ: [yumemi-inc/ios-engineer-codecheck] + * [複製時点のREADME](./docs/README.original.md) +* [Android 版の開発リポジトリ](https://github.com/tshion/yumemi-inc_android-engineer-codecheck) -課題 Issueをご自身のリポジトリーにコピーするGitHub Actionsをご用意しております。 -[こちらのWorkflow](./.github/workflows/copy-issues.yml)を[手動でトリガーする](https://docs.github.com/ja/actions/managing-workflow-runs/manually-running-a-workflow)ことでコピーできますのでご活用下さい。 -課題が完成したら、リポジトリーのアドレスを教えてください。 - -## 参考情報 - -提出された課題の評価ポイントについても詳しく書かれてありますので、ぜひご覧ください。 - -- [私が(iOS エンジニアの)採用でコードチェックする時何を見ているのか](https://qiita.com/lovee/items/d76c68341ec3e7beb611) -- [CocoaPods の利用手引き](https://qiita.com/ykws/items/b951a2e24ca85013e722) -- [ChatGPT (Model: GPT-4) でコードリファクタリングをやってみる](https://qiita.com/mitsuharu_e/items/213491c668ab75924cfd) - -ChatGPTなどAIサービスの利用は禁止しておりません。 -利用にあたって工夫したプロンプトやソースコメント等をご提出頂くと加点評価する場合がございます。 (減点評価はありません) +[yumemi-inc/ios-engineer-codecheck]: https://github.com/yumemi-inc/ios-engineer-codecheck/commit/121f618f0b82eac3318621dd46bc13382e8c31b7 diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..3bf05cc --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,142 @@ +## Let's contributing! +これからいろいろ書いていきますが、一番大事なのは気軽にやってみることです。 +皆さんのチャレンジを、首を長くしてお待ちしております:bow: + + + +## 開発環境について +下記のツールをセットアップ後に、 +Xcode で[iOSEngineerCodeCheck.xcodeproj](./iOSEngineerCodeCheck.xcodeproj) を開くことで、 +開発作業に取り掛かれるようになります。 + +もし何か分からないことが出てきたら、声をかけてください。 + +* macOS +* GitHub +* Xcode 15.2 + +### 任意 +下記のツールは無くても開発できますが、あると便利なので、興味に応じて試してみてください。 + +* [rbenv](https://github.com/rbenv/rbenv) +* [Visual Studio Code](https://code.visualstudio.com/) + * .gitignore の記述 + * GitHub Actions の構築 + * Git クライアント + Pull Request 等の確認 + * Markdown の記述 + * [OpenAPI](https://www.openapis.org/) の記述 + * [PlantUML](https://plantuml.com/) の記述 + * Ruby の記述 + + + +## 開発作業の流れ +### 基本 +1. タスクはGitHub Issue で管理されているので、その中からやってみたいものを探す +1. やりたいものが見つかったらIssue のAssignees に自分を設定する +1. 最新の`develop` ブランチからGit ブランチを切る + * 名前は`feature/???` という形式で、`???` の部分を良い感じに設定してください +1. 開発する +1. 1日の終わりに出来たところまでをDraft Pull Request として作成する + * 特に理由が無ければ`develop` ブランチに対してPull Request を作ってください + * 進捗管理の都合上、どこまで出来ているかを見たいので、対応してくれるととても助かります +1. 作成したPull Request の`Development` に関連のGitHub Issue を紐づける + * Pull Request のマージ + 条件を満たすとIssue もクローズしてくれるようになります +1. 作業が完了したら、Draft 状態を解除し、レビュー担当者に連絡してください + +### 緊急対応すべきと宣言されたバグフィックス +「緊急」とあるように、綿密な進捗管理が必要となるものなので、適宜状況共有してくれると助かります。 + +1. 最新の`released` ブランチからGit ブランチを切る + * 名前は`hotfix/???` という形式で、`???` の部分を良い感じに設定してください +1. バグ修正をする +1. アプリバージョンを更新する + * 後述する「リリース作業の流れ」にあるアプリバージョンを更新するGitHub Actions も利用できます +1. 作業が完了したら下記ブランチそれぞれに対してPull Request を作成する + * `released` ブランチ -> 例: [Android PR #51](https://github.com/tshion/yumemi-inc_android-engineer-codecheck/pull/51) + * `develop` ブランチ -> 例: [Android PR #52](https://github.com/tshion/yumemi-inc_android-engineer-codecheck/pull/52) +1. レビュー担当者に連絡してください + + + +## レビュー方針 +* レビューする際、PR 単位で確認します + * コミット毎ではないので、ある程度は雑で大丈夫です + * (Revert するケースを考えるとコミットが綺麗だと嬉しいですが、開発スピードを優先したいので、ここは後回しにします) +* API の誤用と思われる場合は差し戻します +* マージコンフリクトした場合は、下記の順で判定します + 1. 実装の都合 + 1. アルファベット順 + + + +## リリース作業の流れ +1. リリース対象Pull Request が`develop` ブランチに全てマージされていることを確認する +1. https://github.com/tshion/yumemi-inc_ios-engineer-codecheck/actions/workflows/update-app-version.yml に移動し、GitHub Actions を実行する + * アプリバージョンを更新するPull Request が作成されます + * ローカルの場合は、Ruby の実行環境を整備した上で、下記を実行し、Pull Request を作成してください + * VSCode タスク「アプリバージョンの更新」を実行する + * プロジェクトルートで `ruby scripts/set-version.rb x y z` を実行する +1. 前の手順で作成したPull Request に問題がなければマージする +1. `released` ブランチへのマージPull Request が作成されるはずなので、しばらく待つ + * 手動実行する場合は、下記に移動してください + * https://github.com/tshion/yumemi-inc_ios-engineer-codecheck/actions/workflows/create-merge-pr.yml +1. 前の手順で作成したPull Request に問題がなければマージする +1. GitHub Releases が自動生成されるので、様子を見る + +※`hotfix` ブランチの場合は、`released` ブランチに対してPull Request を作成するので、それをマージすればリリース処理が走ります + + + +## 備考 +### Git ブランチの役割について +ブランチ名 | 役割 +--- | --- +develop | 開発作業のメインブランチ +feature/??? | 各Issue の作業ブランチ +hotfix/??? | 緊急で対応しないといけないバグフィックスの作業ブランチ +released | リリースの記録ブランチ + +### GitHub のLabels について +どのLabel にするかは各自で判断が別れやすいところなので、下記以外は何もつけなくて大丈夫です。 + +* `bug` -> hotfix なものに付与する + * 作業進行で慎重に扱わないといけないため +* `duplicate` -> 重複しているものに付与し、他のところで取り扱うことを宣言する +* `github` -> GitHub 機能を利用しているものに付与する + * 利用サービスによって変動するので、別プロジェクトとの差分を視覚化するためにマーキングする + +### GitHub のMilestones について +* 基本的にはGitHub のIssue を紐づけます +* もしGitHub のPull Request のみしか存在しない場合は、それを紐づけます + * 例: ドキュメント更新のPull Request + +### 開発の心得 +* クラスやメソッドは、なるべく統治しやすい単位で切ること + * ユニットテストを書きやすいかどうかが一つの目安になります + * 今後の保守で機能が無くなったり、実装の書き方が古すぎる場合、この単位で削除や差し替えのための再実装が容易であるとサイコーです:laughing: +* 参考にした資料などの記録を、Issue やPR に忘れずに記載してください +* 変更はなるべく小さくすること +* メソッド名は基本的に```(動詞) + (名詞)``` で付けていくこと
+ * 何をどうしたいかがパッと見でわかると超クールw + +### メモを残したくなったら +本リポジトリでは下記を用意しているので、よさげなところがあればそこに追記してください。 + +それ以外に何かあれば、`docs/` 配下で作業し、Pull Request を出してください。 + +### ルールオブスリー(3度目の法則) +作業を進めていくと似たようなコードを見つけてしまい、ついつい共通化とか考えたくなるとは思いますが、一旦心を落ち着けて、下記を意識してもらえると嬉しいです。 + +> 最初は、単純に作業を行います。 +> 2度目は以前と似たようなことをしていると気づいた場合には、重複や無駄を意識しつつも、とにかく作業を続けてかまいません。 +> そして3度目に同じようなことをしていると気づいたならば、そこでリファクタリングをするのです。 + +引用: Martin Fowler (2014) 「新装版 リファクタリング 既存のコードを安全に改善する」 児玉公信・友野晶夫・平澤章・梅澤真史訳、オーム社 + + + +## 参考文献 +* CONTRIBUTING の内容の参考 + * https://github.com/DroidKaigi/conference-app-2023/blob/main/CONTRIBUTING.ja.md + * https://github.com/tshion/XAppRecipe/blob/develop/CONTRIBUTING.md diff --git a/docs/README.original.md b/docs/README.original.md new file mode 100644 index 0000000..33c65a9 --- /dev/null +++ b/docs/README.original.md @@ -0,0 +1,54 @@ +# 株式会社ゆめみ iOS エンジニアコードチェック課題 + +## 概要 + +本プロジェクトは株式会社ゆめみ(以下弊社)が、弊社に iOS エンジニアを希望する方に出す課題のベースプロジェクトです。本課題が与えられた方は、下記の説明を詳しく読んだ上で課題を取り組んでください。 + +新卒/未経験者エンジニアの場合、本リファクタリングの通常課題の代わりに、[新規アプリ作成の特別課題](https://yumemi-ios-junior-engineer-codecheck.app.swift.cloud)も選択できますので、ご自身が得意と感じる方を選んでください。特別課題を選んだ場合、通常課題の取り組みは不要です。新規アプリ作成の課題の説明を詳しく読んだ上で課題を取り組んでください。 + +## アプリ仕様 + +本アプリは GitHub のリポジトリーを検索するアプリです。 + +![動作イメージ](app.gif) + +### 環境 + +- IDE:基本最新の安定版(本概要更新時点では Xcode 15.2) +- Swift:基本最新の安定版(本概要更新時点では Swift 5.9) +- 開発ターゲット:基本最新の安定版(本概要更新時点では iOS 17.2) +- サードパーティーライブラリーの利用:オープンソースのものに限り制限しない + +### 動作 + +1. 何かしらのキーワードを入力 +2. GitHub API(`search/repositories`)でリポジトリーを検索し、結果一覧を概要(リポジトリ名)で表示 +3. 特定の結果を選択したら、該当リポジトリの詳細(リポジトリ名、オーナーアイコン、プロジェクト言語、Star 数、Watcher 数、Fork 数、Issue 数)を表示 + +## 課題取り組み方法 + +Issues を確認した上、本プロジェクトを [**Duplicate** してください](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/duplicating-a-repository)(Fork しないようにしてください。必要ならプライベートリポジトリーにしても大丈夫です)。今後のコミットは全てご自身のリポジトリーで行ってください。 + +コードチェックの課題 Issue は全て [`課題`](https://github.com/yumemi/ios-engineer-codecheck/milestone/1) Milestone がついており、難易度に応じて Label が [`初級`](https://github.com/yumemi/ios-engineer-codecheck/issues?q=is%3Aopen+is%3Aissue+label%3A初級+milestone%3A課題)、[`中級`](https://github.com/yumemi/ios-engineer-codecheck/issues?q=is%3Aopen+is%3Aissue+label%3A中級+milestone%3A課題+) と [`ボーナス`](https://github.com/yumemi/ios-engineer-codecheck/issues?q=is%3Aopen+is%3Aissue+label%3Aボーナス+milestone%3A課題+) に分けられています。課題の必須/選択は下記の表とします: + +| | 初級 | 中級 | ボーナス +|--:|:--:|:--:|:--:| +| 新卒/未経験者 | 必須 | 選択 | 選択 | +| 中途/経験者 | 必須 | 必須 | 選択 | + + +課題 Issueをご自身のリポジトリーにコピーするGitHub Actionsをご用意しております。 +[こちらのWorkflow](./.github/workflows/copy-issues.yml)を[手動でトリガーする](https://docs.github.com/ja/actions/managing-workflow-runs/manually-running-a-workflow)ことでコピーできますのでご活用下さい。 + +課題が完成したら、リポジトリーのアドレスを教えてください。 + +## 参考情報 + +提出された課題の評価ポイントについても詳しく書かれてありますので、ぜひご覧ください。 + +- [私が(iOS エンジニアの)採用でコードチェックする時何を見ているのか](https://qiita.com/lovee/items/d76c68341ec3e7beb611) +- [CocoaPods の利用手引き](https://qiita.com/ykws/items/b951a2e24ca85013e722) +- [ChatGPT (Model: GPT-4) でコードリファクタリングをやってみる](https://qiita.com/mitsuharu_e/items/213491c668ab75924cfd) + +ChatGPTなどAIサービスの利用は禁止しておりません。 +利用にあたって工夫したプロンプトやソースコメント等をご提出頂くと加点評価する場合がございます。 (減点評価はありません) diff --git a/README_Images/app.gif b/docs/app.gif similarity index 100% rename from README_Images/app.gif rename to docs/app.gif diff --git a/iOSEngineerCodeCheck.xcodeproj/project.pbxproj b/iOSEngineerCodeCheck.xcodeproj/project.pbxproj index 933f9df..2d93f21 100644 --- a/iOSEngineerCodeCheck.xcodeproj/project.pbxproj +++ b/iOSEngineerCodeCheck.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 050D42562B8734DA00138A40 /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; BF0A658C244F2A3B00280FA6 /* ViewController2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController2.swift; sourceTree = ""; }; BFD945DB244DC5E80012785A /* iOSEngineerCodeCheck.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSEngineerCodeCheck.app; sourceTree = BUILT_PRODUCTS_DIR; }; BFD945DE244DC5E80012785A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -81,6 +82,7 @@ BFD945D2244DC5E80012785A = { isa = PBXGroup; children = ( + 050D42562B8734DA00138A40 /* Build.xcconfig */, BFD945DD244DC5E80012785A /* iOSEngineerCodeCheck */, BFD945F4244DC5EB0012785A /* iOSEngineerCodeCheckTests */, BFD945FF244DC5EB0012785A /* iOSEngineerCodeCheckUITests */, @@ -323,6 +325,7 @@ /* Begin XCBuildConfiguration section */ BFD94603244DC5EC0012785A /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 050D42562B8734DA00138A40 /* Build.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -385,6 +388,7 @@ }; BFD94604244DC5EC0012785A /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 050D42562B8734DA00138A40 /* Build.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/iOSEngineerCodeCheck/Info.plist b/iOSEngineerCodeCheck/Info.plist index 2a3483c..74ed3ae 100644 --- a/iOSEngineerCodeCheck/Info.plist +++ b/iOSEngineerCodeCheck/Info.plist @@ -15,9 +15,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.0 + $(APP_VERSION_NAME) CFBundleVersion - 1 + $(APP_VERSION_CODE) LSRequiresIPhoneOS UIApplicationSceneManifest diff --git a/scripts/pick-version-name.rb b/scripts/pick-version-name.rb new file mode 100644 index 0000000..c2b0265 --- /dev/null +++ b/scripts/pick-version-name.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +# アプリバージョン文字列の抽出 +# +# 注意事項 +# * ".ruby-version" に記載されているバージョンで実行してください + + +require 'pathname' + + +# 作業対象ファイルの設定と検証 +PATH = Pathname.new(__dir__).join("../Build.xcconfig") +unless FileTest.exist?(PATH) then + puts("#{PATH} にファイルが存在しません") + exit 1 +end + + +# ファイル読み込み +text = "" +File.open(PATH, "r") { |file| + text = file.read +} + + +# アプリバージョン文字列の抽出 +VERSION_NAME = text.scan(/^APP_VERSION_NAME = (\d[\d\.]{0,}\d)$/) + +# 終了表示 +puts(VERSION_NAME) diff --git a/scripts/set-version.rb b/scripts/set-version.rb new file mode 100644 index 0000000..e0b62d5 --- /dev/null +++ b/scripts/set-version.rb @@ -0,0 +1,63 @@ +#!/usr/bin/env ruby + +# アプリバージョンの更新 +# +# 注意事項 +# * ".ruby-version" に記載されているバージョンで実行してください + + +require 'pathname' + + +# 作業対象ファイルの設定と検証 +PATH = Pathname.new(__dir__).join("../Build.xcconfig") +unless FileTest.exist?(PATH) then + puts("#{PATH} にファイルが存在しません") + exit 1 +end + + +# コマンドライン引数の検証 +unless ARGV.length == 3 then + puts("引数を3つ指定してください") + exit 1 +end + +MAJOR = ARGV[0] +unless /^\d+$/.match?(MAJOR) then + puts("major には正整数を指定してください") + exit 1 +end + +MINOR = ARGV[1] +unless /^\d{1,2}$/.match?(MINOR) then + puts("minor には1 ~ 2桁の正整数を指定してください") + exit 1 +end + +PATCH = ARGV[2] +unless /^\d{1,2}$/.match?(PATCH) then + puts("patch には1 ~ 2桁の正整数を指定してください") + exit 1 +end + + +# バージョン情報の算出 +VERSION_CODE = MAJOR.to_i * 10000 + MINOR.to_i * 100 + PATCH.to_i +VERSION_NAME = "#{MAJOR}.#{MINOR}.#{PATCH}" + + +# ファイル出力 +text = "" +File.open(PATH, "r") { |file| + text = file.read +} +text = text.gsub(/^(APP_VERSION_CODE = )(\d+)$/) { "#{$1}#{VERSION_CODE}" } +text = text.gsub(/^(APP_VERSION_NAME = )(\d[\d\.]{0,}\d)$/) { "#{$1}#{VERSION_NAME}" } +File.open(PATH, "w") { |file| + file.write(text) +} + + +# 終了表示 +puts("Set code: #{VERSION_CODE}, name: #{VERSION_NAME}")