Section 4/181 menit

4. Code Quality: SwiftLint & SwiftFormat

4. Code Quality: SwiftLint & SwiftFormat

SwiftLint: Enforce Code Style

swift
# Install
brew install swiftlint

# Atau via SPM (untuk integrasi di project)
# Package.swift:
.package(url: "https://github.com/realm/SwiftLint", from: "0.57.0")
swift
# .swiftlint.yml — letakkan di root project

# Rules yang diaktifkan
opt_in_rules:
  - closure_end_indentation
  - closure_spacing
  - collection_alignment
  - contains_over_filter_count
  - contains_over_filter_is_empty
  - discouraged_object_literal
  - empty_collection_literal
  - empty_string
  - enum_case_associated_values_count
  - explicit_init
  - fallthrough
  - fatal_error_message
  - file_header
  - first_where
  - flatmap_over_map_reduce
  - force_unwrapping                  # PENTING: larang ! di production code
  - implicitly_unwrapped_optional
  - last_where
  - literal_expression_end_indentation
  - multiline_arguments
  - multiline_function_chains
  - operator_usage_whitespace
  - overridden_super_call
  - prefer_self_type_over_type_of_self
  - reduce_into
  - redundant_nil_coalescing
  - sorted_first_last
  - unneeded_parentheses_in_closure_argument
  - vertical_parameter_alignment_on_call
  - yoda_condition

# Rules yang dinonaktifkan
disabled_rules:
  - trailing_whitespace    # handled by SwiftFormat
  - line_length            # too strict for complex generics

# Konfigurasi per-rule
line_length:
  warning: 120
  error: 200
  ignores_comments: true
  ignores_urls: true

function_body_length:
  warning: 40
  error: 80

type_body_length:
  warning: 200
  error: 400

file_length:
  warning: 400
  error: 800

identifier_name:
  min_length: 2
  max_length: 50
  excluded:
    - id
    - x
    - y
    - z

# Folder yang di-exclude
excluded:
  - Pods
  - .build
  - DerivedData
  - "${PODS_ROOT}"
  - Packages          # SPM dependencies
swift
# Integrasi di Xcode Build Phase
# Target → Build Phases → + → New Run Script Phase

if which swiftlint > /dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

# Untuk fix otomatis (jalankan manual, bukan di Build Phase):
swiftlint --fix

# Analisis lebih dalam (perlu compile)
swiftlint analyze --compiler-log-path /tmp/xcodebuild.log

SwiftFormat: Auto-formatting

swift
# Install
brew install swiftformat

# Atau SPM plugin (Xcode 14+)
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.0")
swift
# .swiftformat — letakkan di root project

# Indentation
--indent 4
--indentcase false
--tabwidth 4

# Braces & spacing
--allman false
--wraparguments before-first
--wrapparameters before-first
--wrapcollections before-first
--closingparen balanced
--funcattributes prev-line
--typeattributes prev-line
--varattributes same-line
--maxwidth 120

# Import sorting
--importgrouping testable-bottom

# Self
--self init-only
--selfrequired 

# Trailing commas
--commas always

# Semicolons
--semicolons never

# Empty lines
--emptybraces no-space
--linebreaks lf

# Rules yang diaktifkan
--enable isEmpty
--enable sortedImports
--enable unusedArguments
--enable andOperator
--enable consecutiveBlankLines
--enable consecutiveSpaces
--enable duplicateImports
--enable elseOnSameLine
--enable hoistTry
--enable leadingDelimiters
--enable numberFormatting
--enable preferKeyPath
--enable redundantBackticks
--enable redundantBreak
--enable redundantExtensionACL
--enable redundantFileprivate
--enable redundantGet
--enable redundantInit
--enable redundantLet
--enable redundantNilInit
--enable redundantObjc
--enable redundantParens
--enable redundantPattern
--enable redundantRawValues
--enable redundantReturn
--enable redundantSelf
--enable redundantType
--enable redundantVoidReturnType
--enable semicolons
--enable sortedSwitchCases
--enable spaceAroundComments
--enable spaceAroundOperators
--enable spaceAroundParens
--enable spaceInsideBrackets
--enable spaceInsideComments
--enable spaceInsideGenerics
--enable spaceInsideParens
--enable todos
--enable trailingClosures
--enable trailingCommas
--enable trailingSpace
--enable typeSugar
--enable void
--enable wrapAttributes
--enable yodaConditions

# Exclude
--exclude Pods,.build,DerivedData,Packages
swift
# Jalankan SwiftFormat
swiftformat .

# Dry run (lihat perubahan tanpa apply)
swiftformat . --dryrun

# Lint mode (gunakan di CI — fail jika ada yang tidak sesuai format)
swiftformat . --lint

# Format satu file
swiftformat Sources/MyApp/ContentView.swift

Gabungkan SwiftLint + SwiftFormat di Makefile

swift
# Makefile — letakkan di root project

.PHONY: lint format check

lint:
	swiftlint --strict

format:
	swiftformat .

check: format lint
	@echo "✓ Code quality checks passed"

# Usage:
# make lint    → check only
# make format  → auto-fix formatting
# make check   → format + lint (untuk pre-push)