Skip to content

Commit

Permalink
feat : spotless 체크 (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
jifrozen0110 committed Dec 22, 2023
1 parent 886e5ae commit 474ab59
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 116 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ assignees: ''
## 🚨 버그 내용

## ⚠ 버그 재현 방법

1.
2.
3.
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/pr-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ assignees: ''

---

- [ ] ✅ PR 제목의 형식을 잘 작성했나요? e.g. `feat: PR을 등록한다.`
- [ ] ✅ PR 제목의 형식을 잘 작성했나요? e.g. `feat: PR을 등록한다.`
- [ ] ✅ 테스트는 잘 통과했나요?
- [ ] ✅ 빌드는 성공했나요?
- [ ] ✅ 불필요한 코드는 제거했나요?
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/create-issue-branch.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Create Issue Branch
on:
issues:
types: [assigned]
types: [ assigned ]

jobs:
create_issue_branch_job:
Expand Down
211 changes: 124 additions & 87 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,145 +1,182 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'jacoco'
id "org.sonarqube" version "4.4.1.3373"
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'com.diffplug.spotless' version '6.11.0'
id 'jacoco'
id "org.sonarqube" version "4.4.1.3373"
}

group = 'com.compono'
version = '0.0.1-SNAPSHOT'

java {
sourceCompatibility = '17'
sourceCompatibility = '17'
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
mavenCentral()
}

ext {
set('snippetsDir', file("build/generated-snippets"))
set('snippetsDir', file("build/generated-snippets"))
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

developmentOnly 'org.springframework.boot:spring-boot-devtools'
developmentOnly 'org.springframework.boot:spring-boot-devtools'

runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.h2database:h2'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
testImplementation 'org.springframework.security:spring-security-test'
}

tasks.named('test') {
useJUnitPlatform()
finalizedBy 'jacocoTestReport'
test{
useJUnitPlatform()
finalizedBy 'jacocoTestReport'
}

tasks.named('asciidoctor') {
inputs.dir snippetsDir
dependsOn test
inputs.dir snippetsDir
dependsOn test
}

def jacocoDir = layout.buildDirectory.dir("reports/")
//queryDSL 제외
def QDomains = []
for (qPattern in '*.QA'..'*.QZ') { // qPattern = '*.QA', '*.QB', ... '*.QZ'
QDomains.add(qPattern + '*')
QDomains.add(qPattern + '*')
}
private excludedClassFilesForReport(classDirectories) {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, exclude: [
"**/Q*",
"**/*DTO*",
"**/*Code*",
"**/*Exception*",
"**/*Develop*",
"**/*Application*",
"**/*Config*"
])
})
)
}

def jacocoExcludePatterns = [
// 테스트 커버리지 제외 파일
"**/*Application*",
"**/*Config*",
"**/*Exception*",
"**/*Request*",
"**/*Response*",
"**/*Dto*",
"**/*Interceptor*",
"**/*Filter*",
"**/*Resolver*",
"**/*Entity*",
"**/*Error*/**",
"**/test/**",
"**/resources/**",
"**/error/**",
"**/config/**"
// 테스트 커버리지 제외 파일
"**/*Application*",
"**/*Config*",
"**/*Exception*",
"**/*Request*",
"**/*Response*",
"**/*DTO*",
"**/*Interceptor*",
"**/*Filter*",
"**/*Resolver*",
"**/*Entity*",
"**/*Error*/**",
"**/test/**",
"**/dto/**",
"**/resources/**",
"**/error/**",
"**/config/**",
"com/compono/ibackend/common/dto/error/response/ErrorDTO**",
"com/compono/ibackend/common/exception/CustomException**",
"com/compono/ibackend/common/enumType/ErrorCode**",
"com/compono/ibackend/IbackendApplication**",
"com/compono/ibackend/develop/controller/DevelopController**",
"com/compono/ibackend/common/handler/CustomExceptionHandler**"
]

sonar {
properties {
property "sonar.projectKey", "Compono-Team_I-backend"
property "sonar.organization", "compono-team"
property "sonar.host.url", "https://sonarcloud.io"
property 'sonar.sources', 'src'
property 'sonar.language', 'java'
property 'sonar.sourceEncoding', 'UTF-8'
property 'sonar.test.exclusions', jacocoExcludePatterns.join(',')
property 'sonar.test.inclusions', '**/*Test.java'
property 'sonar.java.coveragePlugin', 'jacoco'
property 'sonar.coverage.jacoco.xmlReportPaths', jacocoDir.get().file("jacoco/index.xml").asFile
}
properties {
property "sonar.projectKey", "Compono-Team_I-backend"
property "sonar.organization", "compono-team"
property "sonar.host.url", "https://sonarcloud.io"
property 'sonar.sources', 'src'
property 'sonar.language', 'java'
property 'sonar.sourceEncoding', 'UTF-8'
property 'sonar.test.exclusions', classDirectories.join(',')
property 'sonar.test.inclusions', '**/*Test.java'
property 'sonar.java.coveragePlugin', 'jacoco'
property 'sonar.coverage.jacoco.xmlReportPaths', jacocoDir.get().file("jacoco/index.xml").asFile
}
}

jacoco {
toolVersion = "0.8.8"
toolVersion = "0.8.8"
}

jacocoTestReport {
dependsOn test
reports {
html.required.set(true)
xml.required.set(true)
csv.required.set(true)
html.destination jacocoDir.get().file("jacoco/index.html").asFile
xml.destination jacocoDir.get().file("jacoco/index.xml").asFile
csv.destination jacocoDir.get().file("jacoco/index.csv").asFile
}

afterEvaluate {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, excludes: jacocoExcludePatterns + QDomains) // Querydsl 관련 제거
})
)
}
finalizedBy jacocoTestCoverageVerification
dependsOn test
reports {
html.required.set(true)
xml.required.set(true)
csv.required.set(true)
html.destination jacocoDir.get().file("jacoco/index.html").asFile
xml.destination jacocoDir.get().file("jacoco/index.xml").asFile
csv.destination jacocoDir.get().file("jacoco/index.csv").asFile
}

excludedClassFilesForReport(classDirectories)

finalizedBy 'jacocoTestCoverageVerification'
}

jacocoTestCoverageVerification {
excludedClassFilesForReport(classDirectories)

violationRules {
rule {
// rule 활성화
enabled = true
violationRules {
rule {
// rule 활성화
enabled = true

// 클래스 단위로 룰 체크
element = 'CLASS'
// 클래스 단위로 룰 체크
element = 'CLASS'

// 라인 커버리지를 최소 70% 만족
// 라인 커버리지를 최소 70% 만족
limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.70
}

excludes = jacocoExcludePatterns + QDomains
}
}
// excludes = jacocoExcludePatterns
}
}
}

spotless {
java {
target("**/*.java")
importOrder() // import 순서 정의
removeUnusedImports() // 사용하지 않는 import 제거
trimTrailingWhitespace() // 공백 제거
endWithNewline() // 끝부분 NewLine 처리
googleJavaFormat().aosp() // google java format
}
}

// pre-commit spotless check script
tasks.register('updateGitHooks', Copy) {
from './scripts/pre-commit'
into './.git/hooks'
fileMode 0775
}
compileJava.dependsOn updateGitHooks
9 changes: 9 additions & 0 deletions scripts/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
echo "Running spotless check"
./gradlew spotlessCheck
if [ \$? -eq 0 ]
then
echo "Spotless check succeed"
else
echo "Spotless check failed" >&2
exit 1
fi
7 changes: 3 additions & 4 deletions src/main/java/com/compono/ibackend/IbackendApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
@SpringBootApplication
public class IbackendApplication {

public static void main(String[] args) {
SpringApplication.run(IbackendApplication.class, args);
}

public static void main(String[] args) {
SpringApplication.run(IbackendApplication.class, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ public record ErrorDTO(int code, String msg) {
public static ResponseEntity<ErrorDTO> toResponseEntity(CustomException ex) {
ErrorCode errorType = ex.getErrorCode();

return ResponseEntity
.status(ex.getStatus())
.body(ErrorDTO.builder()
.code(errorType.getCode())
.msg(errorType.getMsg())
.build());
return ResponseEntity.status(ex.getStatus())
.body(ErrorDTO.builder().code(errorType.getCode()).msg(errorType.getMsg()).build());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

@Getter
public class CustomException extends RuntimeException {

private final HttpStatus status;
private final ErrorCode errorCode;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ public class CustomExceptionHandler {
@ExceptionHandler(CustomException.class)
protected ResponseEntity<ErrorDTO> handleCustom400Exception(CustomException ex) {
ErrorCode errorCode = ex.getErrorCode();
log.warn(String.format("http-status={%d} code={%d} msg={%s}", ex.getStatus().value(), errorCode.getCode(),
errorCode.getMsg()));
log.warn(
String.format(
"http-status={%d} code={%d} msg={%s}",
ex.getStatus().value(), errorCode.getCode(), errorCode.getMsg()));

return ErrorDTO.toResponseEntity(ex);
}
Expand Down
22 changes: 12 additions & 10 deletions src/main/java/com/compono/ibackend/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@
@Configuration
public class SecurityConfig {

private static final String[] DEFAULT_WHITELIST = {
"/status", "/images/**", "/error/**"
};
private static final String[] DEFAULT_WHITELIST = {"/status", "/images/**", "/error/**"};

private static final String[] DEVELOP_TEST_PATH = {
"api/develop/**",
"api/develop/**",
};

@Bean
protected SecurityFilterChain config(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(request -> request
.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll()
.requestMatchers(DEFAULT_WHITELIST).permitAll()
.requestMatchers(DEVELOP_TEST_PATH).permitAll()
.anyRequest().authenticated()
);
http.authorizeHttpRequests(
request ->
request.dispatcherTypeMatchers(DispatcherType.FORWARD)
.permitAll()
.requestMatchers(DEFAULT_WHITELIST)
.permitAll()
.requestMatchers(DEVELOP_TEST_PATH)
.permitAll()
.anyRequest()
.authenticated());
return http.build();
}
}
Loading

0 comments on commit 474ab59

Please sign in to comment.