Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step4 carracing #5541

Merged
merged 21 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
42287c7
step1 squash
rkaehdaos Apr 17, 2024
3351eca
step2 squash
rkaehdaos Apr 17, 2024
d059c8e
step3 squash
rkaehdaos Apr 17, 2024
51b02c6
docs(README): STEP4 README.md 작성
rkaehdaos Apr 17, 2024
5ca13e3
feat(car): Move, getDistance 구현
rkaehdaos Apr 17, 2024
37c02f1
feat(car): name 필드
rkaehdaos Apr 17, 2024
9dd8bb2
feat(car): Car 구현 완료 및 정리
rkaehdaos Apr 17, 2024
64c8765
feat(Race): Race 생성자 및 getter 처리
rkaehdaos Apr 17, 2024
ed667b4
feat(Race): Race runRound
rkaehdaos Apr 17, 2024
cac66cb
feat(Input): Input 구현
rkaehdaos Apr 17, 2024
cc64200
feat(result): 자동차 이름과 함께 움직임 출력
rkaehdaos Apr 17, 2024
fb6ca7d
feat(result): 최종 우승자 출력: 1명 이상 일 수 있음
rkaehdaos Apr 17, 2024
01771dc
feat(result): result 구현 완료
rkaehdaos Apr 17, 2024
3641b3f
check: UI를 InputView, ResultView로 분리
rkaehdaos Apr 17, 2024
82312d2
메서드가 15라인을 넘어가지 않도록 구현
rkaehdaos Apr 17, 2024
96082e8
Step4 - 단일 책임원칙 확인
rkaehdaos Apr 17, 2024
04ab98c
Merge remote-tracking branch 'origin/step4_carracing' into step4_carr…
rkaehdaos Apr 17, 2024
d655ebe
Merge branch 'rkaehdaos' into step4_carracing
rkaehdaos Apr 17, 2024
8f9e43a
Merge branch 'rkaehdaos' into step4_carracing
rkaehdaos Apr 17, 2024
6ab6e1b
Merge remote-tracking branch 'origin/step4_carracing' into step4_carr…
rkaehdaos Apr 17, 2024
3a88c8d
conflict 해결 및 전략 패턴 적용 (#4)
rkaehdaos Apr 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/pmd/ruleset.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<ruleset name="Custom ruleset"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
메서드 길이를 15줄로 제한하는 custom ruleset
</description>

<!-- https://docs.pmd-code.org/latest/pmd_rules_java_design.html#ncsscount-->
<rule ref="category/java/design.xml/NcssCount">
<properties>
<property name="methodReportLevel" value="15"/> <!-- 기본값 60 -->
<property name="classReportLevel" value="1500"/> <!--default-->
</properties>
</rule>

</ruleset>
113 changes: 113 additions & 0 deletions .github/workflows/PR-mytest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: Gradle PR test On GitHub Action
on:
pull_request:
types: [opened,reopened,synchronize]

jobs:
onPRTest:
runs-on: ubuntu-latest
steps:
- name: '소스 checkout'
uses: actions/checkout@master

- name: 'graalvm jdk21 setup'
uses: graalvm/setup-graalvm@v1
with:
java-version: '21'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
native-image-job-reports: 'true'
cache: 'gradle'

- name: 'gradle 빌드'
run: gradle build --no-daemon --parallel

- name: '커버리지 정보 및 요약'
run: |
echo 'CSV 파일에서 커버리지 정보 추출';
awk -F',' 'NR > 1 {instructions_covered += $5; instructions_missed += $4; branches_covered += $7; branches_missed += $6} END {print instructions_covered, instructions_missed, branches_covered, branches_missed}' build/reports/jacoco/test/jacocoTestReport.csv > coverage.txt
read instructions_covered instructions_missed branches_covered branches_missed < coverage.txt
echo '커버리지 계산';
total_instructions=$((instructions_covered + instructions_missed))
total_branches=$((branches_covered + branches_missed))
instruction_coverage=$(echo "scale=2; $instructions_covered / $total_instructions * 100" | bc)
echo '분모가 0일 경우, 커버리지를 'N/A'로 설정';
if [ "$total_instructions" -eq 0 ]; then
instruction_coverage="N/A"
else
instruction_coverage=$(echo "scale=2; $instructions_covered / $total_instructions * 100" | bc)%
fi
if [ "$total_branches" -eq 0 ]; then
branch_coverage="N/A"
else
branch_coverage=$(echo "scale=2; $branches_covered / $total_branches * 100" | bc)%
fi
echo '# GitHub Action Summary' >> PR_summary.md
echo 'GITHUB_STEP_SUMMARY에 커버리지 정보 추가';
echo "## JaCoCo 커버리지 요약" >> PR_summary.md
echo "- Instruction Coverage: $instruction_coverage" >> PR_summary.md
echo "- Branch Coverage: $branch_coverage" >> PR_summary.md

- name: 'PMD 리포트 요약'
run: |
echo 'PMD 파일에서 정보 추출: XML 구조에 의존적이므로 구조가 변경되면 스크립트도 업데이트가 필요';
echo 'xml이 매우 크면 성능에 문제가 생길 수 있으므로 더 효율적인 파싱 방법의 고려가 필요';
echo "## PMD Code Analysis" >> PR_summary.md
total_violations=$(grep -c '<violation' build/reports/pmd/main.xml||true)
if [ "$total_violations" -eq 0 ]; then
echo "### 문제 없음" >> PR_summary.md
else
echo "### Total Violations: $total_violations" >> PR_summary.md
echo '각 file 태그를 찾아 파일 경로를 추출하고, 내부의 violation 정보를 처리'
awk '/<file name=/,/<\/file>/' build/reports/pmd/main.xml | awk '
/<file name="/ {
filename=gensub(/.*<file name="([^"]+).*/, "\\1", "g");
print "### File: " filename;
print "### File: " filename >> "PR_summary.md";
next;
}
/<violation/,/<\/violation>/ {
if ($0 ~ /<violation/) {
line=gensub(/.*beginline="([^"]+).*/, "\\1", "g");
url=gensub(/.*externalInfoUrl="([^"]+).*/, "\\1", "g");
capturing = 1;
content = "";
} else if ($0 ~ /<\/violation>/) {
print "- Line " line ": [" content "](" url ")";
print "- Line " line ": [" content "](" url ")" >> "PR_summary.md";
capturing = 0;
} else if (capturing) {
content = content $0;
}
}
'
fi
cat PR_summary.md >> $GITHUB_STEP_SUMMARY

- name: 'PR Comment에 SUMMARY Report 작성'
if: github.repository == 'rkaehdaos/java-racingcar'
uses: peter-evans/create-or-update-comment@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
body-path: 'PR_summary.md'

- name: '실패 시 보고서 업로드'
uses: actions/upload-artifact@v4
if: failure()
with:
name: report-jacoco
path: |
build/reports/jacoco/test/html
build/reports/pmd/*.html

- name: 'slack 알림'
uses: 8398a7/action-slack@v3
if: github.repository == 'rkaehdaos/java-racingcar'
with:
status: ${{ job.status }}
author_name: my workflow bot
fields: repo,message,commit,author,eventName,ref,workflow,job,took,
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
73 changes: 55 additions & 18 deletions .github/workflows/push-test.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
name: Gradle test On GitHub Action
on:
push:
branches-ignore: [ 'main','master','rkaehdaos' ]
branches-ignore: ['main','master']

jobs:
onPushTest:
if: github.event.pull_request.opened == false
runs-on: ubuntu-latest
steps:
- name: Checkout source code
- name: '소스 checkout'
uses: actions/checkout@master

- name: setup-java-21
- name: 'jdk21 setup'
uses: actions/setup-java@v4
with:
distribution: 'zulu' # See 'Supported distributions' for available options
java-version: '11'
distribution: 'zulu'
java-version: '21'
cache: 'gradle'

- name: test
- name: 'gradle test'
run: |
echo "Available processors: $(nproc)"
gradle test jacocoTestCoverageVerification --no-daemon --parallel
gradle test --no-daemon --parallel

- name: Extract coverage info and update step summary
- name: '커버리지 정보 및 요약'
run: |
echo 'CSV 파일에서 커버리지 정보 추출';
awk -F',' 'NR > 1 {instructions_covered += $5; instructions_missed += $4; branches_covered += $7; branches_missed += $6} END {print instructions_covered, instructions_missed, branches_covered, branches_missed}' build/reports/jacoco/test/jacocoTestReport.csv > coverage.txt
Expand All @@ -43,25 +42,63 @@ jobs:
else
branch_coverage=$(echo "scale=2; $branches_covered / $total_branches * 100" | bc)%
fi
echo '# GitHub Action Summary' >> PUSH_summary.md
echo 'GITHUB_STEP_SUMMARY에 커버리지 정보 추가';
echo "JaCoCo 커버리지 요약" >> $GITHUB_STEP_SUMMARY
echo "Instruction Coverage: $instruction_coverage" >> $GITHUB_STEP_SUMMARY
echo "Branch Coverage: $branch_coverage" >> $GITHUB_STEP_SUMMARY
echo "## JaCoCo 커버리지 요약" >> PUSH_summary.md
echo "- Instruction Coverage: $instruction_coverage" >> PUSH_summary.md
echo "- Branch Coverage: $branch_coverage" >> PUSH_summary.md

- name: Upload JaCoCo coverage report
- name: 'PMD 리포트 요약'
run: |
echo 'PMD 파일에서 정보 추출: XML 구조에 의존적이므로 구조가 변경되면 스크립트도 업데이트가 필요';
echo 'xml이 매우 크면 성능에 문제가 생길 수 있으므로 더 효율적인 파싱 방법의 고려가 필요';
echo "## PMD Code Analysis" >> PUSH_summary.md
total_violations=$(grep -c '<violation' build/reports/pmd/main.xml||true)
if [ "$total_violations" -eq 0 ]; then
echo "### 문제 없음" >> PUSH_summary.md
else
echo "### Total Violations: $total_violations" >> PUSH_summary.md
echo '각 file 태그를 찾아 파일 경로를 추출하고, 내부의 violation 정보를 처리'
awk '/<file name=/,/<\/file>/' build/reports/pmd/main.xml | awk '
/<file name="/ {
filename=gensub(/.*<file name="([^"]+).*/, "\\1", "g");
print "### File: " filename;
print "### File: " filename >> "PUSH_summary.md";
next;
}
/<violation/,/<\/violation>/ {
if ($0 ~ /<violation/) {
line=gensub(/.*beginline="([^"]+).*/, "\\1", "g");
url=gensub(/.*externalInfoUrl="([^"]+).*/, "\\1", "g");
capturing = 1;
content = "";
} else if ($0 ~ /<\/violation>/) {
print "- Line " line ": [" content "](" url ")";
print "- Line " line ": [" content "](" url ")" >> "PUSH_summary.md";
capturing = 0;
} else if (capturing) {
content = content $0;
}
}
'
fi
cat PUSH_summary.md >> $GITHUB_STEP_SUMMARY

- name: '실패 시 보고서 업로드'
uses: actions/upload-artifact@v4
if: failure()
with:
name: jacoco-report
path: build/reports/jacoco/test/html
name: report-jacoco
path: |
build/reports/jacoco/test/html
build/reports/pmd/*.html

- name: Notification
- name: 'slack 알림'
uses: 8398a7/action-slack@v3
if: always()
with:
status: ${{ job.status }}
author_name: GeunChang Ahn
job_name: onPushTest
author_name: my workflow bot
fields: repo,message,commit,author,eventName,ref,workflow,job,took,
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
52 changes: 32 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
# 자동차 경주 게임
## 진행 방법
* 자동차 경주 게임 요구사항을 파악한다.
* 요구사항에 대한 구현을 완료한 후 자신의 github 아이디에 해당하는 브랜치에 Pull Request(이하 PR)를 통해 코드 리뷰 요청을 한다.
* 코드 리뷰 피드백에 대한 개선 작업을 하고 다시 PUSH한다.
* 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다.
# 🚀 4단계 - 자동차 경주(우승자)

## 온라인 코드 리뷰 과정
* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview)
- 구현할 기능 목록 단위 추가
- commit 단위는 정리한 기능 목록 단위로 추가할 것!!

UI 로직을 InputView, ResultView와 같은 클래스를 추가해 분리한다.
## 기능 요구사항
- [x] 기능을 구현하기 전에 README.md 파일에 구현할 기능 목록을 정리해 추가
- [x] Car 구현
- [x] move 구현: random4이상시 움직임
- [x] getDistance: 차의 움직인 거리 getter
- [x] 이름: 5자 제한, 생성할때 부여, getter 필요, Lombok `@getter` 처리
- [] Race 구현
- [x] Race 생성자 : 자동차들 list 준비,
- [x] 자동차 리스트 가져오기: `@getter` 처리
- [x] Race runRound

- [x] Input 구현
- [x] 자동차 이름 입력
- [x] : validate: 5자 : 이미 Car 생성자에서 구현

## 기능 목록 및 commit 로그 요구사항
- commit message 종류 구분
```text
feat (feature)
fix (bug fix)
docs (documentation)
style (formatting, missing semi colons, …)
refactor
test (when adding missing tests)
chore (maintain)
```
- [x] result 구현
- [x] 자동차 이름과 함께 움직임 출력
- [x] 최종 우승자 출력: 1명 이상 일 수 있음

## Check 사항
- [ ] 들여쓰기 1까지인지 확인
- [x] 메서드가 15라인을 넘어가지 않도록 구현
- [x] ~~pmd 15 line 적용 시도~~
- https://github.com/pmd/pmd/issues/2127#issue-527718378
- Enforcing length limits with LoC("lines of code") is not very meaningful, could even be called a bad practice
- **LoC로 길이 제한을 적용하는 것은 그다지 의미가 없으며, 심지어 나쁜 관행이라고 할 수도 있습니다**
- [x] NCSS 15 라인 설정 - PMD Custom Rule apply

- [x] 단일 책임 원칙으로 메서드가 되어 있는지 확인
- [ ] 모든 로직에 단위 테스트 구현 - UI 제외
- [x] UI를 `InputView`, `ResultView`로 분리
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요구사항 및 체크사항 좋습니다 💯

39 changes: 37 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'java'
id 'jacoco'
id 'pmd'
}

version '1.0'
Expand All @@ -19,14 +20,45 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
}

// java
java {
toolchain {
languageVersion = JavaLanguageVersion.of(11)
languageVersion = JavaLanguageVersion.of(21)
}
}

tasks.named('compileJava') {
dependsOn clean
}

tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation"
}

// pmd
pmd {
toolVersion = "7.0.0"
consoleOutput = true
ignoreFailures = true
incrementalAnalysis = true
ruleSets = []
ruleSetFiles = files(rootProject.file(".github/pmd/ruleset.xml") as Object)
}

tasks.named('pmdMain') {
// excludes =['**/*',]
includes = ['**/step4_winner/*',]
// ruleSetFiles = files(rootProject.file(".github/pmd/ruleset.xml") as Object)
}

tasks.named('pmdTest') {
excludes =['**/*',]
// includes = ['**/step4_winner/*',]
}

tasks.named('test') {
useJUnitPlatform() // Junit5 사용: 테스트 종속성에 JUnit Jupiter API와 JUnit Jupiter Engine을 포함해야 함.
dependsOn pmdMain
useJUnitPlatform()
maxParallelForks = Runtime.runtime.availableProcessors()
finalizedBy jacocoTestCoverageVerification
}
Expand All @@ -35,4 +67,7 @@ jacocoTestReport {
}
jacocoTestCoverageVerification {
dependsOn jacocoTestReport
violationRules {
rule { limit { minimum = 0.8 } }
}
}
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists
Loading
Loading