From 5b7711bf110328a810090dd5273324ee72ffb351 Mon Sep 17 00:00:00 2001 From: MoonSeonghun Date: Thu, 18 Jan 2024 17:38:04 +0900 Subject: [PATCH 1/6] =?UTF-8?q?=EA=B9=83=20=EC=A0=84=EB=9E=B5=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: dev 브랜치 pr시 테스트 자동 수행 추가 * docs: 깃 전략 변경에 따른 기여 문서 수정 --- .github/workflows/on-pr-main.yml | 1 + documentation/CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/on-pr-main.yml b/.github/workflows/on-pr-main.yml index 0d1029e..58ac411 100644 --- a/.github/workflows/on-pr-main.yml +++ b/.github/workflows/on-pr-main.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - main + - dev permissions: pull-requests: write diff --git a/documentation/CONTRIBUTING.md b/documentation/CONTRIBUTING.md index d5bbf86..b368e6f 100644 --- a/documentation/CONTRIBUTING.md +++ b/documentation/CONTRIBUTING.md @@ -12,7 +12,7 @@ 풀 리퀘스트를 보내실 때, 아래의 사항들을 유의해주세요: -- `main` 브랜치를 기준으로 하여 풀 리퀘스트를 보내주세요. +- `dev` 브랜치를 기준으로 하여 풀 리퀘스트를 보내주세요. - 변경사항에 대한 명확하고 간결한 설명을 포함해주세요. - 변경된 코드에 대한 적절한 테스트가 수행되었는지 확인해주세요. From 21a2539c2212d988c6ad77a9f31db1b6ec6fffa0 Mon Sep 17 00:00:00 2001 From: MoonSeonghun Date: Thu, 18 Jan 2024 17:41:07 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20=EC=9C=88=EB=8F=84=EC=9A=B0=20?= =?UTF-8?q?=ED=8C=8C=EC=9B=8C=EC=89=98=20=ED=99=98=EA=B2=BD=EC=97=90?= =?UTF-8?q?=EC=84=9C=20idea=EA=B0=80=20=EC=BC=9C=EC=A7=80=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0=20?= =?UTF-8?q?(#13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #13 #15 --- src/main/java/kr/huni/BojStarter.java | 2 +- .../java/kr/huni/code_runner/CodeOpenCommand.java | 8 -------- .../java/kr/huni/code_runner/CodeOpenManager.java | 3 ++- .../java/kr/huni/code_runner/IdeaCodeOpenManager.java | 11 ++++------- 4 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 src/main/java/kr/huni/code_runner/CodeOpenCommand.java diff --git a/src/main/java/kr/huni/BojStarter.java b/src/main/java/kr/huni/BojStarter.java index f3ef617..3d5420c 100644 --- a/src/main/java/kr/huni/BojStarter.java +++ b/src/main/java/kr/huni/BojStarter.java @@ -37,7 +37,7 @@ private void openSourceCodeWithIde(Problem problem) { IntelliJ IDEA의 idea 명령어가 설치되어 있지 않습니다. 직접 IntelliJ IDEA를 실행해서 프로젝트를 열어주세요. 생성된 프로젝트 경로 : {} - %n + 상세 오류 : """, problem.getSourceRootDirectory(), e); } } diff --git a/src/main/java/kr/huni/code_runner/CodeOpenCommand.java b/src/main/java/kr/huni/code_runner/CodeOpenCommand.java deleted file mode 100644 index 722f436..0000000 --- a/src/main/java/kr/huni/code_runner/CodeOpenCommand.java +++ /dev/null @@ -1,8 +0,0 @@ -package kr.huni.code_runner; - -public record CodeOpenCommand( - String ideExistedCommand, - String executeCommand -) { - -} diff --git a/src/main/java/kr/huni/code_runner/CodeOpenManager.java b/src/main/java/kr/huni/code_runner/CodeOpenManager.java index e74aa9f..c9b97ff 100644 --- a/src/main/java/kr/huni/code_runner/CodeOpenManager.java +++ b/src/main/java/kr/huni/code_runner/CodeOpenManager.java @@ -10,6 +10,7 @@ public interface CodeOpenManager { * @throws IOException 실행 실패 * @implSpec 주어진 codePath를 IDE로 열어준다 */ - void run(String codePath, OperatingSystem operatingSystem) throws IOException; + void run(String codePath, OperatingSystem operatingSystem) + throws IOException; } diff --git a/src/main/java/kr/huni/code_runner/IdeaCodeOpenManager.java b/src/main/java/kr/huni/code_runner/IdeaCodeOpenManager.java index 91a7751..ea461b0 100644 --- a/src/main/java/kr/huni/code_runner/IdeaCodeOpenManager.java +++ b/src/main/java/kr/huni/code_runner/IdeaCodeOpenManager.java @@ -6,14 +6,11 @@ public class IdeaCodeOpenManager implements CodeOpenManager { public void run(String codePath, OperatingSystem os) throws IOException { - CodeOpenCommand command = switch (os) { - case WINDOWS -> new CodeOpenCommand("where idea", "idea"); - case LINUX, MAC -> new CodeOpenCommand("which idea", "idea"); + String command = switch (os) { + case WINDOWS -> "idea.bat"; + case LINUX, MAC -> "idea"; }; - boolean ideaExist = Runtime.getRuntime().exec(command.ideExistedCommand()).exitValue() == 0; - if (ideaExist) { - Runtime.getRuntime().exec(command.executeCommand() + " " + codePath); - } + Runtime.getRuntime().exec(command + " " + codePath); } } From a343e44edaa8fa2e35aa991e50eb88d995f650c8 Mon Sep 17 00:00:00 2001 From: MoonSeonghun Date: Fri, 19 Jan 2024 17:37:20 +0900 Subject: [PATCH 3/6] =?UTF-8?q?Fix:=20=EB=B2=84=EC=A0=84=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=EC=97=90=20=EB=94=B0=EB=A5=B8=20con?= =?UTF-8?q?fig.json=EA=B0=80=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(#17)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user_configuration/UserConfiguration.java | 5 --- .../UserConfigurationLoader.java | 7 +++- .../kr/huni/Integration/IntegrationTests.java | 4 +-- src/test/java/kr/huni/TestCleaner.java | 23 +++++++++---- .../JavaSourceCodeFileTests.java | 4 +-- .../UserConfigurationLoaderTest.java | 34 +++++++++++++++++++ .../UserConfigurationTest.java | 17 ---------- 7 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/main/java/kr/huni/user_configuration/UserConfiguration.java b/src/main/java/kr/huni/user_configuration/UserConfiguration.java index 77d92be..5eec6cb 100644 --- a/src/main/java/kr/huni/user_configuration/UserConfiguration.java +++ b/src/main/java/kr/huni/user_configuration/UserConfiguration.java @@ -42,9 +42,4 @@ void printValue() { protected UserConfiguration() { } - - public void merge(UserConfiguration userConfiguration) { - this.srcDirPrefix.setValue(userConfiguration.srcDirPrefix.getValue()); - this.mainCodeTemplate.setValue(userConfiguration.mainCodeTemplate.getValue()); - } } diff --git a/src/main/java/kr/huni/user_configuration/UserConfigurationLoader.java b/src/main/java/kr/huni/user_configuration/UserConfigurationLoader.java index 91c8ec2..006886a 100644 --- a/src/main/java/kr/huni/user_configuration/UserConfigurationLoader.java +++ b/src/main/java/kr/huni/user_configuration/UserConfigurationLoader.java @@ -37,7 +37,12 @@ private static UserConfiguration loadProperties() { log.info("설정 파일을 읽어옵니다."); ObjectMapper objectMapper = new ObjectMapper(); - configuration.merge(objectMapper.readValue(configFile, UserConfiguration.class)); + // read only exist field + configuration = objectMapper.readerForUpdating(configuration).readValue(configFile); + + // and rewrite all fields + String jsonString = objectMapper.writeValueAsString(configuration); + writeStringToFile(jsonString); } else { log.info("설정 파일이 존재하지 않습니다. 설정 파일을 새로 생성합니다."); createDefaultConfigurationFile(); diff --git a/src/test/java/kr/huni/Integration/IntegrationTests.java b/src/test/java/kr/huni/Integration/IntegrationTests.java index 0f6283f..fc49ceb 100644 --- a/src/test/java/kr/huni/Integration/IntegrationTests.java +++ b/src/test/java/kr/huni/Integration/IntegrationTests.java @@ -20,12 +20,12 @@ class IntegrationTests { @BeforeEach - void setUp() throws IOException { + void setUp() throws IOException, NoSuchFieldException, IllegalAccessException { TestCleaner.clean(); } @AfterEach - void tearDown() throws IOException { + void tearDown() throws IOException, NoSuchFieldException, IllegalAccessException { TestCleaner.clean(); } diff --git a/src/test/java/kr/huni/TestCleaner.java b/src/test/java/kr/huni/TestCleaner.java index 48ba9ad..e66c934 100644 --- a/src/test/java/kr/huni/TestCleaner.java +++ b/src/test/java/kr/huni/TestCleaner.java @@ -4,20 +4,18 @@ import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; +import kr.huni.user_configuration.UserConfigurationLoader; public class TestCleaner { - static public void clean() throws IOException { + static public void clean() throws IOException, NoSuchFieldException, IllegalAccessException { System.out.println("Clean up..."); // 설정 파일 삭제 - File configFile = new File(CONFIGURATION_FILE_NAME); - if (configFile.exists()) { - Files.deleteIfExists(Path.of(CONFIGURATION_FILE_NAME)); - assert !new File(CONFIGURATION_FILE_NAME).exists(); - } + clearConfigurationFile(); // 생성된 파일 삭제 Files.deleteIfExists(Path.of("p1000/src/Main.java")); @@ -29,4 +27,17 @@ static public void clean() throws IOException { assert !new File("p1000").exists(); } + private static void clearConfigurationFile() + throws IOException, NoSuchFieldException, IllegalAccessException { + File configFile = new File(CONFIGURATION_FILE_NAME); + if (configFile.exists()) { + Files.deleteIfExists(Path.of(CONFIGURATION_FILE_NAME)); + assert !new File(CONFIGURATION_FILE_NAME).exists(); + } + + Field instance = UserConfigurationLoader.class.getDeclaredField("config"); + instance.setAccessible(true); + instance.set(null, null); + } + } diff --git a/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java b/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java index 11412e3..4d65628 100644 --- a/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java +++ b/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java @@ -14,12 +14,12 @@ class JavaSourceCodeFileTests { @BeforeEach - void setUp() throws IOException { + void setUp() throws IOException, NoSuchFieldException, IllegalAccessException { TestCleaner.clean(); } @AfterEach - void tearDown() throws IOException { + void tearDown() throws IOException, NoSuchFieldException, IllegalAccessException { TestCleaner.clean(); } diff --git a/src/test/java/kr/huni/user_configuration/UserConfigurationLoaderTest.java b/src/test/java/kr/huni/user_configuration/UserConfigurationLoaderTest.java index 32e7ec4..598fa4a 100644 --- a/src/test/java/kr/huni/user_configuration/UserConfigurationLoaderTest.java +++ b/src/test/java/kr/huni/user_configuration/UserConfigurationLoaderTest.java @@ -1,12 +1,28 @@ package kr.huni.user_configuration; +import static kr.huni.user_configuration.UserConfigurationLoader.CONFIGURATION_FILE_NAME; import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import kr.huni.TestCleaner; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class UserConfigurationLoaderTest { + @BeforeEach + void setUp() throws IOException, NoSuchFieldException, IllegalAccessException { + TestCleaner.clean(); + } + @Test @DisplayName("ConfigurationLoader 인스턴스를 두 번 생성하면 같은 인스턴스를 반환한다.") void singleton_test() { @@ -17,4 +33,22 @@ void singleton_test() { // when & then assertSame(firstInstance, secondInstance); } + + @Test + @DisplayName("getInstance 호출시 설정 파일에 없는 필드는 기본 값으로 덮어 씌워진다.") + void config_overwrite_work() throws IOException { + // given + Map configMap = new HashMap<>(); + configMap.put("srcDirPrefix", Collections.singletonMap("value", "p")); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.writeValue(new File(CONFIGURATION_FILE_NAME), configMap); + + // when + UserConfigurationLoader.getInstance(); + + // then + File file = new File(CONFIGURATION_FILE_NAME); + String content = new String(Files.readAllBytes(file.toPath())); + assertTrue(content.contains("mainCodeTemplate")); + } } \ No newline at end of file diff --git a/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java b/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java index 8c8562f..22495ab 100644 --- a/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java +++ b/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java @@ -21,23 +21,6 @@ void defaultConfiguration() { UserConfiguration.defaultConfiguration().srcDirPrefix.getValue()); } - @Test - @DisplayName("merge() 메서드는 인자로 받은 Configuration 객체의 value 값을 병합한다.") - void merge() { - // given - UserConfiguration userConfiguration = UserConfiguration.defaultConfiguration(); - UserConfiguration userConfiguration2 = UserConfiguration.defaultConfiguration(); - userConfiguration.srcDirPrefix.setValue("1"); - userConfiguration2.srcDirPrefix.setValue("2"); - - // when - userConfiguration.merge(userConfiguration2); - - // then - Assertions.assertSame("2", userConfiguration.srcDirPrefix.getValue()); - - } - @Test @DisplayName("설정 객체에서 defaultValue는 직렬화 되지 않는다.") void defaultValue_json_ignore() throws JsonProcessingException { From afa2e4f1c41b89c7b719ff07f1d20e46f29fd3b6 Mon Sep 17 00:00:00 2001 From: MoonSeonghun Date: Fri, 19 Jan 2024 21:47:49 +0900 Subject: [PATCH 4/6] =?UTF-8?q?Feat:=20=EB=AC=B8=EC=A0=9C=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EA=B0=80=20=EC=A0=81=ED=9E=8C=20README.md=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EA=B8=B0=EB=8A=A5=20=EA=B0=9C=EB=B0=9C=20(#18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #18 --- documentation/DOCUMENTATION.md | 27 ++++++++++++++- src/main/java/kr/huni/BojStarter.java | 14 +++++--- .../kr/huni/code_generator/CodeGenerator.java | 8 ----- .../code_generator/FileContentGenerator.java | 10 ++++++ ...Template.java => FileContentTemplate.java} | 19 +++++++++-- .../code_generator/JavaCodeGenerator.java | 13 ++++++-- ...odeTemplateImpl.java => JavaTemplate.java} | 22 ++++++++++++- .../file_generator/JavaSourceCodeFile.java | 10 +++++- .../huni/file_generator/SourceCodeFile.java | 19 ++++++----- .../problem_parser/BaekjoonProblemParser.java | 17 +++++++--- .../huni/problem_parser/JsoupWebParser.java | 8 +++-- .../java/kr/huni/problem_parser/Problem.java | 10 +++++- .../kr/huni/problem_parser/WebParser.java | 5 +-- .../user_configuration/UserConfiguration.java | 33 +++++++++++++++---- .../kr/huni/Integration/IntegrationTests.java | 17 ++++++++++ src/test/java/kr/huni/TestCleaner.java | 1 + .../code_generator/CodeGeneratorTests.java | 5 +-- .../code_generator/FakeCodeGenerator.java | 11 +++++-- .../SourceCodeTemplateTests.java | 12 +++---- .../JavaSourceCodeFileTests.java | 4 +-- .../kr/huni/problem_parser/ProblemTests.java | 3 +- .../kr/huni/problem_parser/WebParserStub.java | 2 +- .../UserConfigurationTest.java | 13 +++++--- 23 files changed, 220 insertions(+), 63 deletions(-) delete mode 100644 src/main/java/kr/huni/code_generator/CodeGenerator.java create mode 100644 src/main/java/kr/huni/code_generator/FileContentGenerator.java rename src/main/java/kr/huni/code_generator/{SourceCodeTemplate.java => FileContentTemplate.java} (72%) rename src/main/java/kr/huni/code_generator/{SourceCodeTemplateImpl.java => JavaTemplate.java} (65%) diff --git a/documentation/DOCUMENTATION.md b/documentation/DOCUMENTATION.md index 43e2a6f..f699254 100644 --- a/documentation/DOCUMENTATION.md +++ b/documentation/DOCUMENTATION.md @@ -42,7 +42,7 @@ config.json의 `srcDirPrefix.value`을 수정하여, 생성되는 소스코드 import java.util.Scanner; /* - BAEKJOON {{number}} {{title}} + BAEKJOON {{number}}번 {{title}} https://www.acmicpc.net/problem/{{number}} */ @@ -94,3 +94,28 @@ public class Main { } } ``` + +### 생성되는 README.md 파일의 템플릿 변경하기 + +`config.json`의 `markdownTemplate.value`을 수정하여, 생성되는 README.md의 파일 내용을 변경할 수 있습니다. +기본 설정 값은 아래와 같습니다. + +```markdown +# {{title}} + +> 문제 번호 : {{number}} \s +> 출처 : {{url}} + +## 문제 설명 + +{{description}} +``` + +#### 예악어 + +해당 기능에선 네가지 예약어를 지원합니다. + +- `{{title}}`: 문제 제목 +- `{{number}}`: 문제 번호 +- `{{url}}`: 문제 출처 URL +- `{{description}}`: 문제 설명 (html 태그 포함) diff --git a/src/main/java/kr/huni/BojStarter.java b/src/main/java/kr/huni/BojStarter.java index 3d5420c..14174b0 100644 --- a/src/main/java/kr/huni/BojStarter.java +++ b/src/main/java/kr/huni/BojStarter.java @@ -1,13 +1,14 @@ package kr.huni; import java.io.IOException; -import kr.huni.code_generator.CodeGenerator; +import kr.huni.code_generator.FileContentGenerator; import kr.huni.code_generator.GeneratedCode; import kr.huni.code_runner.CodeOpenManager; import kr.huni.file_generator.JavaSourceCodeFile; import kr.huni.os.OperatingSystem; import kr.huni.problem_parser.BaekjoonProblemParser; import kr.huni.problem_parser.Problem; +import kr.huni.user_configuration.UserConfigurationLoader; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,12 +18,16 @@ public class BojStarter { private final CodeOpenManager codeOpenManager; private final JavaSourceCodeFile fileUtil; - private final CodeGenerator codeGenerator; + private final FileContentGenerator codeGenerator; private final BaekjoonProblemParser problemParser; public void run(final int problemNumber) { Problem problem = problemParser.parse(problemNumber); - GeneratedCode generatedCode = codeGenerator.generate(problem); + if (!problem.isExist()) { + log.error("문제를 찾을 수 없습니다."); + return; + } + GeneratedCode generatedCode = codeGenerator.generateCode(problem); createSrcFile(problem, generatedCode); openSourceCodeWithIde(problem); @@ -45,7 +50,8 @@ private void openSourceCodeWithIde(Problem problem) { private void createSrcFile(Problem problem, GeneratedCode generatedCode) { try { fileUtil.write(problem.getSourceRootDirectory(), generatedCode.mainCode(), - generatedCode.testCode()); + generatedCode.testCode(), codeGenerator.generateMarkdown(problem), + UserConfigurationLoader.getInstance().enableReadme()); } catch (IOException e) { log.error("소스코드 파일 또는 디렉토리 생성에 실패했습니다.", e); } diff --git a/src/main/java/kr/huni/code_generator/CodeGenerator.java b/src/main/java/kr/huni/code_generator/CodeGenerator.java deleted file mode 100644 index c7bec65..0000000 --- a/src/main/java/kr/huni/code_generator/CodeGenerator.java +++ /dev/null @@ -1,8 +0,0 @@ -package kr.huni.code_generator; - -import kr.huni.problem_parser.Problem; - -public interface CodeGenerator { - - GeneratedCode generate(Problem problem); -} diff --git a/src/main/java/kr/huni/code_generator/FileContentGenerator.java b/src/main/java/kr/huni/code_generator/FileContentGenerator.java new file mode 100644 index 0000000..e7c4a93 --- /dev/null +++ b/src/main/java/kr/huni/code_generator/FileContentGenerator.java @@ -0,0 +1,10 @@ +package kr.huni.code_generator; + +import kr.huni.problem_parser.Problem; + +public interface FileContentGenerator { + + GeneratedCode generateCode(Problem problem); + + String generateMarkdown(Problem problem); +} diff --git a/src/main/java/kr/huni/code_generator/SourceCodeTemplate.java b/src/main/java/kr/huni/code_generator/FileContentTemplate.java similarity index 72% rename from src/main/java/kr/huni/code_generator/SourceCodeTemplate.java rename to src/main/java/kr/huni/code_generator/FileContentTemplate.java index 569c4cb..6a2f0b5 100644 --- a/src/main/java/kr/huni/code_generator/SourceCodeTemplate.java +++ b/src/main/java/kr/huni/code_generator/FileContentTemplate.java @@ -4,18 +4,20 @@ import java.util.List; import kr.huni.problem_parser.TestCase; -public interface SourceCodeTemplate { +public interface FileContentTemplate { String TEST_JAVA_FILE = "code_sample/TestHelper.java"; String NO_TEST_JAVA_FILE = "code_sample/NoTestHelper.java"; String REPLACED_NUMBER = "{{number}}"; String REPLACED_TITLE = "{{title}}"; + String REPLACED_DESCRIPTION = "{{description}}"; + String REPLACED_URL = "{{url}}"; String REPLACED_TEST_CASES = "// {{test_case}}"; String DEFAULT_MAIN_CODE_TEMPLATE = """ import java.util.Scanner; /* - BAEKJOON {{number}} {{title}} + BAEKJOON {{number}}번 {{title}} https://www.acmicpc.net/problem/{{number}} */ @@ -27,6 +29,17 @@ public static void main(String[] args) { } } """; + String DEFAULT_MARKDOWN_TEMPLATE = """ + # {{title}} + + > 문제 번호 : {{number}} \s + > 출처 : {{url}} + + ## 문제 설명 + + {{description}} + + """; /** * Main.java 소스코드 문자를 생성하고 반환합니다. @@ -45,4 +58,6 @@ public static void main(String[] args) { */ String getTestCode(List testCases) throws IOException; + String getMarkdownContent(int number, String title, String description); + } diff --git a/src/main/java/kr/huni/code_generator/JavaCodeGenerator.java b/src/main/java/kr/huni/code_generator/JavaCodeGenerator.java index 5075c85..a30e5b2 100644 --- a/src/main/java/kr/huni/code_generator/JavaCodeGenerator.java +++ b/src/main/java/kr/huni/code_generator/JavaCodeGenerator.java @@ -5,16 +5,16 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class JavaCodeGenerator implements CodeGenerator { +public class JavaCodeGenerator implements FileContentGenerator { @Override - public GeneratedCode generate(Problem problem) { + public GeneratedCode generateCode(Problem problem) { if (problem.getTestCases() == null) { throw new IllegalArgumentException("테스트는 null이 될 수 없습니다."); } try { - SourceCodeTemplateImpl sourceCodeTemplate = new SourceCodeTemplateImpl(); + JavaTemplate sourceCodeTemplate = new JavaTemplate(); String mainCode = sourceCodeTemplate.getMainCode(problem.getNumber(), problem.getTitle()); String testCode = sourceCodeTemplate.getTestCode(problem.getTestCases()); @@ -25,4 +25,11 @@ public GeneratedCode generate(Problem problem) { } } + @Override + public String generateMarkdown(Problem problem) { + JavaTemplate markdownTemplate = new JavaTemplate(); + return markdownTemplate.getMarkdownContent(problem.getNumber(), problem.getTitle(), + problem.getDescription()); + } + } diff --git a/src/main/java/kr/huni/code_generator/SourceCodeTemplateImpl.java b/src/main/java/kr/huni/code_generator/JavaTemplate.java similarity index 65% rename from src/main/java/kr/huni/code_generator/SourceCodeTemplateImpl.java rename to src/main/java/kr/huni/code_generator/JavaTemplate.java index be10ae2..5d658fb 100644 --- a/src/main/java/kr/huni/code_generator/SourceCodeTemplateImpl.java +++ b/src/main/java/kr/huni/code_generator/JavaTemplate.java @@ -1,5 +1,7 @@ package kr.huni.code_generator; +import static kr.huni.problem_parser.BaekjoonProblemParser.PROBLEM_URL; + import java.io.IOException; import java.util.List; import kr.huni.file_generator.SourceCodeFile; @@ -7,7 +9,7 @@ import kr.huni.user_configuration.UserConfigurationField; import kr.huni.user_configuration.UserConfigurationLoader; -public class SourceCodeTemplateImpl implements SourceCodeTemplate { +public class JavaTemplate implements FileContentTemplate { public String getMainCode(int number, String title) { String template = DEFAULT_MAIN_CODE_TEMPLATE; @@ -47,4 +49,22 @@ public String getTestCode(List testCases) throws IOException { String template = SourceCodeFile.readFileFromResource(TEST_JAVA_FILE); return template.replace(REPLACED_TEST_CASES, testCaseCode.toString()); } + + @Override + public String getMarkdownContent(int number, String title, String description) { + String template = DEFAULT_MARKDOWN_TEMPLATE; + UserConfigurationField markdownTemplate = + UserConfigurationLoader.getInstance().markdownTemplate; + boolean useCustomTemplate = markdownTemplate.getValue() != null; + + if (useCustomTemplate) { + template = markdownTemplate.getValue(); + } + + return template + .replace(REPLACED_NUMBER, String.valueOf(number)) + .replace(REPLACED_TITLE, title) + .replace(REPLACED_DESCRIPTION, description) + .replace(REPLACED_URL, PROBLEM_URL + number); + } } diff --git a/src/main/java/kr/huni/file_generator/JavaSourceCodeFile.java b/src/main/java/kr/huni/file_generator/JavaSourceCodeFile.java index 3e92209..a270b09 100644 --- a/src/main/java/kr/huni/file_generator/JavaSourceCodeFile.java +++ b/src/main/java/kr/huni/file_generator/JavaSourceCodeFile.java @@ -8,7 +8,8 @@ public class JavaSourceCodeFile implements SourceCodeFile { @Override - public void write(String sourceRootDirectory, String sourceCode, String testCode) + public void write(String sourceRootDirectory, String sourceCode, String testCode, String readme, + boolean enableReadme) throws IOException { File srcDir = new File(sourceRootDirectory, "src"); @@ -18,6 +19,13 @@ public void write(String sourceRootDirectory, String sourceCode, String testCode log.info("소스코드 디렉토리 생성 완료"); writeToFile(srcDir, "Main.java", sourceCode); writeToFile(srcDir, "TestHelper.java", testCode); + log.info("소스코드 파일 생성 완료"); + + if (enableReadme) { + writeToFile(srcDir, "README.md", readme); + log.info("README.md 파일 생성 완료"); + } } + } diff --git a/src/main/java/kr/huni/file_generator/SourceCodeFile.java b/src/main/java/kr/huni/file_generator/SourceCodeFile.java index 115ac55..703c9e6 100644 --- a/src/main/java/kr/huni/file_generator/SourceCodeFile.java +++ b/src/main/java/kr/huni/file_generator/SourceCodeFile.java @@ -8,7 +8,7 @@ import java.io.InputStreamReader; import java.util.Objects; import java.util.Scanner; -import kr.huni.code_generator.SourceCodeTemplateImpl; +import kr.huni.code_generator.JavaTemplate; /** * 소스코드 파일을 생성하고, 내용을 채워주기 위한 인터페이스 @@ -25,16 +25,18 @@ public interface SourceCodeFile { * @implSpec 해당 메서드안에서 필요한 하위 폴더를 생성하고, {@link #writeToFile(File, String, String)}를 통해 알고리즘을 구현할 * 소스코드 파일과 테스트 코드 파일을 생성해야합니다. */ - void write(String directory, String sourceCode, String testCode) throws IOException; + void write(String directory, String sourceCode, String testCode, String readme, + boolean enableReadme) + throws IOException; /** * 파일을 생성하고, 내용을 채웁니다. * - * @param srcDir 소스코드를 저장할 위치가 담긴 객체 - * @param fileName 파일 이름 - * @param sourceCode 파일 내용 + * @param srcDir 소스코드를 저장할 위치가 담긴 객체 + * @param fileName 파일 이름 + * @param content 파일 내용 */ - default void writeToFile(File srcDir, String fileName, String sourceCode) { + default void writeToFile(File srcDir, String fileName, String content) { File file = new File(srcDir, fileName); if (file.exists()) { System.out.printf("%s/%s가 이미 존재합니다. 새롭게 덮어 씌우시겠습니까? (y, n): ", srcDir.getAbsoluteFile(), @@ -50,7 +52,7 @@ default void writeToFile(File srcDir, String fileName, String sourceCode) { } try (FileWriter fileWriter = new FileWriter(file)) { - fileWriter.write(sourceCode); + fileWriter.write(content); } catch (IOException e) { System.out.println("파일 생성 실패. 프로그램을 종료합니다."); throw new RuntimeException(e); @@ -66,7 +68,7 @@ default void writeToFile(File srcDir, String fileName, String sourceCode) { */ static String readFileFromResource(String filePath) throws IOException { StringBuilder sourceCode = new StringBuilder(); - try (InputStream inputStream = SourceCodeTemplateImpl.class.getClassLoader() + try (InputStream inputStream = JavaTemplate.class.getClassLoader() .getResourceAsStream(filePath); InputStreamReader inputStreamReader = new InputStreamReader( Objects.requireNonNull(inputStream)); @@ -80,5 +82,4 @@ static String readFileFromResource(String filePath) throws IOException { } return sourceCode.toString(); } - } diff --git a/src/main/java/kr/huni/problem_parser/BaekjoonProblemParser.java b/src/main/java/kr/huni/problem_parser/BaekjoonProblemParser.java index f0162d6..b3e75cd 100644 --- a/src/main/java/kr/huni/problem_parser/BaekjoonProblemParser.java +++ b/src/main/java/kr/huni/problem_parser/BaekjoonProblemParser.java @@ -7,10 +7,11 @@ */ public class BaekjoonProblemParser { - static final String PROBLEM_URL = "https://www.acmicpc.net/problem/"; + public static final String PROBLEM_URL = "https://www.acmicpc.net/problem/"; static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"; static final String PROBLEM_TITLE_SELECTOR = "span#problem_title"; + static final String PROBLEM_DESCRIPTION_SELECTOR = "div#problem_description"; static final String PROBLEM_INPUT_SELECTOR = "pre[id^=sample-input]"; static final String PROBLEM_OUTPUT_SELECTOR = "pre[id^=sample-output]"; private final WebParser webParser; @@ -31,18 +32,24 @@ public BaekjoonProblemParser(WebParser webParser) { * @return Problem 객체 */ public Problem parse(int problemNumber) { - String title = webParser.parse(PROBLEM_TITLE_SELECTOR)[0]; + String title = webParser.parse(PROBLEM_TITLE_SELECTOR, false)[0]; + String description = webParser.parse(PROBLEM_DESCRIPTION_SELECTOR, true)[0]; final ArrayList testCases = new ArrayList<>(); - String[] inputs = webParser.parse(PROBLEM_INPUT_SELECTOR); - String[] outputs = webParser.parse(PROBLEM_OUTPUT_SELECTOR); + String[] inputs = webParser.parse(PROBLEM_INPUT_SELECTOR, false); + String[] outputs = webParser.parse(PROBLEM_OUTPUT_SELECTOR, false); assert inputs.length == outputs.length; for (int i = 0; i < inputs.length; i++) { testCases.add(new TestCase(inputs[i], outputs[i])); } - return new Problem(problemNumber, title, testCases); + return Problem.builder() + .title(title) + .description(description) + .number(problemNumber) + .testCases(testCases) + .build(); } } diff --git a/src/main/java/kr/huni/problem_parser/JsoupWebParser.java b/src/main/java/kr/huni/problem_parser/JsoupWebParser.java index afd77ac..6edf1a8 100644 --- a/src/main/java/kr/huni/problem_parser/JsoupWebParser.java +++ b/src/main/java/kr/huni/problem_parser/JsoupWebParser.java @@ -29,12 +29,16 @@ public JsoupWebParser(int problemNumber) { } @Override - public String[] parse(String selector) { + public String[] parse(String selector, boolean includeHtml) { Elements result = this.document.select(selector); String[] arr = new String[result.size()]; for (int i = 0; i < result.size(); i++) { - arr[i] = result.get(i).text(); + if (includeHtml) { + arr[i] = result.get(i).html(); + } else { + arr[i] = result.get(i).text(); + } } return arr; diff --git a/src/main/java/kr/huni/problem_parser/Problem.java b/src/main/java/kr/huni/problem_parser/Problem.java index de13896..fd72066 100644 --- a/src/main/java/kr/huni/problem_parser/Problem.java +++ b/src/main/java/kr/huni/problem_parser/Problem.java @@ -3,6 +3,7 @@ import java.util.List; import kr.huni.user_configuration.UserConfiguration; import kr.huni.user_configuration.UserConfigurationLoader; +import lombok.Builder; import lombok.Getter; @Getter @@ -10,16 +11,23 @@ public class Problem { private final int number; private final String title; + private final String description; private final String sourceRootDirectory; private final List testCases; - public Problem(int number, String title, List testCases) { + @Builder + public Problem(int number, String title, String description, List testCases) { UserConfiguration configuration = UserConfigurationLoader.getInstance(); this.number = number; this.title = title; this.sourceRootDirectory = configuration.srcDirPrefix.getValue() + number; + this.description = description; this.testCases = testCases; } + public boolean isExist() { + return (this.number != 0 && this.title != null); + } + } diff --git a/src/main/java/kr/huni/problem_parser/WebParser.java b/src/main/java/kr/huni/problem_parser/WebParser.java index 01da8fb..ad34579 100644 --- a/src/main/java/kr/huni/problem_parser/WebParser.java +++ b/src/main/java/kr/huni/problem_parser/WebParser.java @@ -3,10 +3,11 @@ public interface WebParser { /** - * @param selector 파싱할 selector + * @param selector 파싱할 selector + * @param includeHtml html 태그를 포함할지 여부 * @return 파싱된 String[] * @implSpec 주어진 selector를 파싱하여 String[]로 반환한다 */ - String[] parse(String selector); + String[] parse(String selector, boolean includeHtml); } diff --git a/src/main/java/kr/huni/user_configuration/UserConfiguration.java b/src/main/java/kr/huni/user_configuration/UserConfiguration.java index 5eec6cb..0792744 100644 --- a/src/main/java/kr/huni/user_configuration/UserConfiguration.java +++ b/src/main/java/kr/huni/user_configuration/UserConfiguration.java @@ -1,6 +1,6 @@ package kr.huni.user_configuration; -import kr.huni.code_generator.SourceCodeTemplateImpl; +import kr.huni.code_generator.JavaTemplate; import lombok.extern.slf4j.Slf4j; /** @@ -22,7 +22,21 @@ public class UserConfiguration { .description(""" Main.java 파일의 템플릿입니다. 예악어 {{number}}와 {{title}}을 사용하면 문제번호와 문제제목으로 자동 치환됩니다. """) - .defaultValue(SourceCodeTemplateImpl.DEFAULT_MAIN_CODE_TEMPLATE) + .defaultValue(JavaTemplate.DEFAULT_MAIN_CODE_TEMPLATE) + .build(); + public final UserConfigurationField markdownTemplate = + UserConfigurationField.builder() + .description(""" + 문제 설명을 저장할 마크다운 파일의 템플릿입니다. 예악어 {{title}}, {{problem_number}}, {{description}}, {{source}}를 사용하면 문제제목, 문제번호, 문제설명, 출처로 자동 치환됩니다. + """) + .defaultValue(JavaTemplate.DEFAULT_MARKDOWN_TEMPLATE) + .build(); + private final UserConfigurationField enableReadme = + UserConfigurationField.builder() + .description(""" + README.md 파일을 생성할지 여부를 결정합니다. + """) + .defaultValue("true") .build(); public static UserConfiguration defaultConfiguration() { @@ -34,12 +48,19 @@ public static UserConfiguration defaultConfiguration() { */ void printValue() { log.info(""" - 설정 정보를 출력합니다. - srcDirPrefix : {} - srcCommentFormat : {} - """, srcDirPrefix.getValue(), mainCodeTemplate.getValue()); + 설정 정보를 출력합니다. + srcDirPrefix : {} + mainCodeTemplate : {} + markdownTemplate : {} + enableReadme : {} + """, srcDirPrefix.getValue(), mainCodeTemplate.getValue(), markdownTemplate.getValue(), + enableReadme.getValue()); } protected UserConfiguration() { } + + public boolean enableReadme() { + return enableReadme.getValue().equals("true"); + } } diff --git a/src/test/java/kr/huni/Integration/IntegrationTests.java b/src/test/java/kr/huni/Integration/IntegrationTests.java index fc49ceb..d24d08e 100644 --- a/src/test/java/kr/huni/Integration/IntegrationTests.java +++ b/src/test/java/kr/huni/Integration/IntegrationTests.java @@ -45,4 +45,21 @@ void applicationTest() { // then assertTrue(new File("p1000/src/Main.java").exists()); } + + @Test + @DisplayName("프로그램에서 README.md 파일이 잘 생성된다.") + void Readme_generate_well() { + // given + BojStarter program = new BojStarter( + new FakeCodeOpen(), + new JavaSourceCodeFile(), + new JavaCodeGenerator(), + new BaekjoonProblemParser(new JsoupWebParser(1000))); + + // when + program.run(1000); + + // then + assertTrue(new File("p1000/src/README.md").exists()); + } } diff --git a/src/test/java/kr/huni/TestCleaner.java b/src/test/java/kr/huni/TestCleaner.java index e66c934..9fac4d7 100644 --- a/src/test/java/kr/huni/TestCleaner.java +++ b/src/test/java/kr/huni/TestCleaner.java @@ -21,6 +21,7 @@ static public void clean() throws IOException, NoSuchFieldException, IllegalAcce Files.deleteIfExists(Path.of("p1000/src/Main.java")); Files.deleteIfExists(Path.of("p1000/src/TestHelper.java")); Files.deleteIfExists(Path.of("p1000/src/NoTestHelper.java")); + Files.deleteIfExists(Path.of("p1000/src/README.md")); Files.deleteIfExists(Path.of("p1000/src")); Files.deleteIfExists(Path.of("p1000")); diff --git a/src/test/java/kr/huni/code_generator/CodeGeneratorTests.java b/src/test/java/kr/huni/code_generator/CodeGeneratorTests.java index a8708c7..f7f0423 100644 --- a/src/test/java/kr/huni/code_generator/CodeGeneratorTests.java +++ b/src/test/java/kr/huni/code_generator/CodeGeneratorTests.java @@ -14,10 +14,11 @@ class CodeGeneratorTests { void javaCodeGenerator_return_code() { // given JavaCodeGenerator javaCodeGenerator = new JavaCodeGenerator(); - Problem problem = new Problem(-1, "A+B", new ArrayList<>()); + Problem problem = new Problem(-1, "A+B", "두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.", + new ArrayList<>()); // when - GeneratedCode generatedCode = javaCodeGenerator.generate(problem); + GeneratedCode generatedCode = javaCodeGenerator.generateCode(problem); // then Assertions.assertAll( diff --git a/src/test/java/kr/huni/code_generator/FakeCodeGenerator.java b/src/test/java/kr/huni/code_generator/FakeCodeGenerator.java index e89a84e..4e5db0d 100644 --- a/src/test/java/kr/huni/code_generator/FakeCodeGenerator.java +++ b/src/test/java/kr/huni/code_generator/FakeCodeGenerator.java @@ -2,10 +2,17 @@ import kr.huni.problem_parser.Problem; -public class FakeCodeGenerator implements CodeGenerator { +public class FakeCodeGenerator implements FileContentGenerator { @Override - public GeneratedCode generate(Problem problem) { + public GeneratedCode generateCode(Problem problem) { return new GeneratedCode("mainCode", "testCode"); } + + @Override + public String generateMarkdown(Problem problem) { + return """ + # 1. A+B + """; + } } diff --git a/src/test/java/kr/huni/code_generator/SourceCodeTemplateTests.java b/src/test/java/kr/huni/code_generator/SourceCodeTemplateTests.java index 8edeb8d..bbcf2ab 100644 --- a/src/test/java/kr/huni/code_generator/SourceCodeTemplateTests.java +++ b/src/test/java/kr/huni/code_generator/SourceCodeTemplateTests.java @@ -16,7 +16,7 @@ class SourceCodeTemplateTests { @DisplayName("생성되는 기본 Main.java 기본 템플릿은 문법적으로 오류가 없다.") void main_syntax_fine() throws IOException { // given - SourceCodeTemplateImpl sourceCodeTemplate = new SourceCodeTemplateImpl(); + JavaTemplate sourceCodeTemplate = new JavaTemplate(); String mainSourceCode = sourceCodeTemplate.getMainCode(1000, "A+B"); // when @@ -33,7 +33,7 @@ void test_syntax_fine() throws IOException { ArrayList testCases = new ArrayList<>(); testCases.add(new TestCase("1 2", "3")); - SourceCodeTemplateImpl sourceCodeTemplate = new SourceCodeTemplateImpl(); + JavaTemplate sourceCodeTemplate = new JavaTemplate(); String testCode = sourceCodeTemplate.getTestCode(testCases); testCode += """ class Main { @@ -54,7 +54,7 @@ public static void main(String[] args) { @DisplayName("테스트 케이스가 없을때 생성된 NoTestHelper.java는 문법적으로 오류가 없다.") void test_syntax_fine_with_no_case() throws IOException { // given - SourceCodeTemplateImpl sourceCodeTemplate = new SourceCodeTemplateImpl(); + JavaTemplate sourceCodeTemplate = new JavaTemplate(); String testCode = sourceCodeTemplate.getTestCode(new ArrayList<>()); // when @@ -68,7 +68,7 @@ void test_syntax_fine_with_no_case() throws IOException { @DisplayName("테스트케이스가 없을때 생성된 NoTestHelper.java 는 고정된 코드 문자를 반환한다.") void noTestHelper_load_well() throws IOException { // given - SourceCodeTemplateImpl sourceCodeTemplate = new SourceCodeTemplateImpl(); + JavaTemplate sourceCodeTemplate = new JavaTemplate(); String noTestHelperCode = sourceCodeTemplate.getTestCode(new ArrayList<>()); // when & then @@ -89,8 +89,8 @@ public static void main() { @DisplayName("TestHelper.java 코드 템플릿에 치환 문자가 존재 한다.") void test_replace_text_exist() throws IOException { // given - String codePath = SourceCodeTemplateImpl.TEST_JAVA_FILE; - String replacedTestCaseSymbol = SourceCodeTemplateImpl.REPLACED_TEST_CASES; + String codePath = JavaTemplate.TEST_JAVA_FILE; + String replacedTestCaseSymbol = JavaTemplate.REPLACED_TEST_CASES; // when String sourceCode = SourceCodeFile.readFileFromResource(codePath); diff --git a/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java b/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java index 4d65628..e7ab5ad 100644 --- a/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java +++ b/src/test/java/kr/huni/file_generator/JavaSourceCodeFileTests.java @@ -24,7 +24,7 @@ void tearDown() throws IOException, NoSuchFieldException, IllegalAccessException } @Test - @DisplayName("이미 존재하는 파일을 생성하려고 할때 y 입력시 파일이 덮어씌워진다.") + @DisplayName("이미 존재하는 소스코드 파일을 생성하려고 할때 y 입력시 파일이 덮어씌워진다.") void writeToFile() throws IOException { // given String sourceRootDirectory = "p1000"; @@ -32,7 +32,7 @@ void writeToFile() throws IOException { String overWrittenSourceCode = "over written source code"; JavaSourceCodeFile javaSourceCodeFile = new JavaSourceCodeFile(); - javaSourceCodeFile.write(sourceRootDirectory, fileName, overWrittenSourceCode); + javaSourceCodeFile.write(sourceRootDirectory, fileName, overWrittenSourceCode, "", false); File srcDir = new File(sourceRootDirectory, "src"); // when diff --git a/src/test/java/kr/huni/problem_parser/ProblemTests.java b/src/test/java/kr/huni/problem_parser/ProblemTests.java index 5de40fb..25a0907 100644 --- a/src/test/java/kr/huni/problem_parser/ProblemTests.java +++ b/src/test/java/kr/huni/problem_parser/ProblemTests.java @@ -13,7 +13,8 @@ class ProblemTests { void problem_dir_prefix_test() { // given & when int problemId = 1000; - Problem problem = new Problem(problemId, "A+B", null); + Problem problem = new Problem(problemId, "A+B", "두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.", + null); String srcDirPrefix = UserConfigurationLoader.getInstance().srcDirPrefix.getValue(); String expected = srcDirPrefix + problemId; diff --git a/src/test/java/kr/huni/problem_parser/WebParserStub.java b/src/test/java/kr/huni/problem_parser/WebParserStub.java index ae52396..5908df1 100644 --- a/src/test/java/kr/huni/problem_parser/WebParserStub.java +++ b/src/test/java/kr/huni/problem_parser/WebParserStub.java @@ -3,7 +3,7 @@ public class WebParserStub implements WebParser { @Override - public String[] parse(String selector) { + public String[] parse(String selector, boolean includeHtml) { return new String[]{"String1", "String2"}; } diff --git a/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java b/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java index 22495ab..2031841 100644 --- a/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java +++ b/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java @@ -15,10 +15,15 @@ void defaultConfiguration() { UserConfiguration defaultConfiguration = UserConfiguration.defaultConfiguration(); // then - Assertions.assertSame(defaultConfiguration.mainCodeTemplate.getDefaultValue(), - UserConfiguration.defaultConfiguration().mainCodeTemplate.getValue()); - Assertions.assertSame(defaultConfiguration.srcDirPrefix.getDefaultValue(), - UserConfiguration.defaultConfiguration().srcDirPrefix.getValue()); + Assertions.assertAll( + () -> Assertions.assertSame(defaultConfiguration.mainCodeTemplate.getDefaultValue(), + UserConfiguration.defaultConfiguration().mainCodeTemplate.getValue()), + () -> Assertions.assertSame(defaultConfiguration.srcDirPrefix.getDefaultValue(), + UserConfiguration.defaultConfiguration().srcDirPrefix.getValue()), + () -> Assertions.assertSame(defaultConfiguration.markdownTemplate.getDefaultValue(), + UserConfiguration.defaultConfiguration().markdownTemplate.getValue()), + () -> Assertions.assertSame(true, defaultConfiguration.enableReadme()) + ); } @Test From a1712cfb70c05704a42df8b678b08535c9c7130d Mon Sep 17 00:00:00 2001 From: MoonSeonghun Date: Fri, 19 Jan 2024 22:17:27 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20README.md=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EC=98=B5=EC=85=98=EC=9D=B4=20=EB=8F=99=EC=9E=91?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(#19)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/kr/huni/BojStarter.java | 2 +- .../java/kr/huni/user_configuration/UserConfiguration.java | 6 +----- .../kr/huni/user_configuration/UserConfigurationTest.java | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/kr/huni/BojStarter.java b/src/main/java/kr/huni/BojStarter.java index 14174b0..dd1d3d6 100644 --- a/src/main/java/kr/huni/BojStarter.java +++ b/src/main/java/kr/huni/BojStarter.java @@ -51,7 +51,7 @@ private void createSrcFile(Problem problem, GeneratedCode generatedCode) { try { fileUtil.write(problem.getSourceRootDirectory(), generatedCode.mainCode(), generatedCode.testCode(), codeGenerator.generateMarkdown(problem), - UserConfigurationLoader.getInstance().enableReadme()); + UserConfigurationLoader.getInstance().enableReadme.getValue().equals("true")); } catch (IOException e) { log.error("소스코드 파일 또는 디렉토리 생성에 실패했습니다.", e); } diff --git a/src/main/java/kr/huni/user_configuration/UserConfiguration.java b/src/main/java/kr/huni/user_configuration/UserConfiguration.java index 0792744..3d331e2 100644 --- a/src/main/java/kr/huni/user_configuration/UserConfiguration.java +++ b/src/main/java/kr/huni/user_configuration/UserConfiguration.java @@ -31,7 +31,7 @@ public class UserConfiguration { """) .defaultValue(JavaTemplate.DEFAULT_MARKDOWN_TEMPLATE) .build(); - private final UserConfigurationField enableReadme = + public final UserConfigurationField enableReadme = UserConfigurationField.builder() .description(""" README.md 파일을 생성할지 여부를 결정합니다. @@ -59,8 +59,4 @@ void printValue() { protected UserConfiguration() { } - - public boolean enableReadme() { - return enableReadme.getValue().equals("true"); - } } diff --git a/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java b/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java index 2031841..f067b1e 100644 --- a/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java +++ b/src/test/java/kr/huni/user_configuration/UserConfigurationTest.java @@ -22,7 +22,7 @@ void defaultConfiguration() { UserConfiguration.defaultConfiguration().srcDirPrefix.getValue()), () -> Assertions.assertSame(defaultConfiguration.markdownTemplate.getDefaultValue(), UserConfiguration.defaultConfiguration().markdownTemplate.getValue()), - () -> Assertions.assertSame(true, defaultConfiguration.enableReadme()) + () -> Assertions.assertSame("true", defaultConfiguration.enableReadme.getValue()) ); } From b7a268162198e351ca0fc65a2bea03b60d803109 Mon Sep 17 00:00:00 2001 From: MoonSeonghun Date: Fri, 19 Jan 2024 22:17:42 +0900 Subject: [PATCH 6/6] =?UTF-8?q?docs:=20README.md=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=97=90=20=EB=8C=80=ED=95=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=ED=99=94=20=EA=B0=95=ED=99=94=20(#20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- documentation/DOCUMENTATION.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/documentation/DOCUMENTATION.md b/documentation/DOCUMENTATION.md index f699254..4e09840 100644 --- a/documentation/DOCUMENTATION.md +++ b/documentation/DOCUMENTATION.md @@ -9,7 +9,7 @@ ### 생성되는 소스코드 폴더명 변경하기 -config.json의 `srcDirPrefix.value`을 수정하여, 생성되는 소스코드 폴더명의 prefix를 변경할 수 있습니다. +`config.json`의 `srcDirPrefix.value`을 수정하여, 생성되는 소스코드 폴더명의 `prefix`를 변경할 수 있습니다. 예시로 1000번 문제에서 `srcDirPrefix.value`을 `BOJ_`로 설정하면, `BOJ_1000` 폴더가 생성됩니다. 기본 설정 값은 `p`입니다. ```json @@ -97,13 +97,13 @@ public class Main { ### 생성되는 README.md 파일의 템플릿 변경하기 -`config.json`의 `markdownTemplate.value`을 수정하여, 생성되는 README.md의 파일 내용을 변경할 수 있습니다. +`config.json`의 `markdownTemplate.value`을 수정하여, 생성되는 `README.md`의 파일 내용을 변경할 수 있습니다. 기본 설정 값은 아래와 같습니다. ```markdown # {{title}} -> 문제 번호 : {{number}} \s +> 문제 번호 : {{number}}
> 출처 : {{url}} ## 문제 설명 @@ -118,4 +118,19 @@ public class Main { - `{{title}}`: 문제 제목 - `{{number}}`: 문제 번호 - `{{url}}`: 문제 출처 URL -- `{{description}}`: 문제 설명 (html 태그 포함) +- `{{description}}`: 문제 설명 *(html 태그 포함)* + +#### 비활성화 방법 + +`config.json`의 `enableReadme.value`를 `"true"` 대신 `"false"`로 수정하면, README.md 파일이 생성되지 않습니다. boolean +형태가 아닌 `"`로 감싸진 문자열로 입력해야 합니다. + +```json +{ + ... + "enableReadme": { + "value": "false" + }, + ... +} +```