├── .gitignore ├── README.md ├── VIPERGenerator ├── main.go └── templates ├── java ├── Activity.java ├── Interactor.java ├── InteractorInput.java ├── InteractorOutput.java ├── Module.java ├── Presenter.java ├── PresenterInput.java └── PresenterOutput.java ├── javav2 ├── Activity.java ├── Interactor.java ├── InteractorInput.java ├── InteractorOutput.java ├── Module.java ├── Presenter.java ├── PresenterInput.java └── PresenterOutput.java └── swift ├── Interactor.swift ├── Presenter.swift ├── Protocols.swift ├── ViewController.swift └── Wireframe.swift /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /output 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Description 2 | This is a code generator for [Clean Architecture](https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html), [VIPER](https://www.objc.io/issues/13-architecture/viper/) 3 | 4 | #USAGE 5 | 6 | ./VIPERGenerator 7 | 8 | - Enter Template(Swift, Java, JavaV2) 9 | - Enter modulename 10 | - For Java enter packagename 11 | 12 | #Templates 13 | 14 | You can use own templates, just provide your code templates in a subdirectory of templates. 15 | 16 | Placeholders: 17 | - `##MODULENAME##` will be replaced 18 | - `##PACKAGENAME##` for java code, the package name of your module 19 | - `##USERNAME##` will be replaced with your terminal username 20 | - `##DATE##` will be replaced by current date with format: dd.MM.YYYY 21 | -------------------------------------------------------------------------------- /VIPERGenerator: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Botz/VIPERGenerator/5c6a194796ad39d439c2e97350a12a2486fd20a9/VIPERGenerator -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "strings" 7 | "bytes" 8 | "os/user" 9 | "time" 10 | "fmt" 11 | "os" 12 | "bufio" 13 | "github.com/kardianos/osext" 14 | ) 15 | 16 | var moduleName string 17 | var moduleNamePackage string 18 | var packageName string 19 | var templateDirectory string 20 | var outputDir string 21 | 22 | func main() { 23 | getConsoleInput() 24 | executableDirectory, _ := osext.ExecutableFolder() 25 | var directory = executableDirectory + "/templates/" + templateDirectory + "/" 26 | var fileInfos, err = ioutil.ReadDir(directory) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | if (templateDirectory != "swift") { 32 | outputDir = outputDir + "/" + moduleNamePackage 33 | } else { 34 | outputDir = outputDir + "/" + moduleName 35 | } 36 | 37 | os.Mkdir(outputDir, 0777) 38 | 39 | for _,fileInfo := range fileInfos { 40 | printFile(directory, fileInfo.Name()) 41 | } 42 | } 43 | 44 | func printFile(directory string, fileName string) { 45 | var data, err = ioutil.ReadFile(directory + "/" + fileName) 46 | 47 | if (err != nil) { 48 | log.Fatal(err) 49 | } 50 | 51 | r := strings.NewReplacer("##MODULENAME##", moduleName, "##MODULENAME_PACKAGE##", moduleNamePackage, "##MODULENAME_UPPERCASE##", strings.ToUpper(moduleName), "##PACKAGENAME##", packageName, "##USERNAME##", getUsername(), "##DATE##", getDate()) 52 | newString := r.Replace(string(data)) 53 | 54 | ioutil.WriteFile(outputDir + "/" + moduleName + fileName, []byte(newString), 0777) 55 | } 56 | 57 | func getUsername() string { 58 | var currentUser, err = user.Current() 59 | 60 | if err != nil { 61 | return "Unnamed" 62 | } 63 | 64 | return currentUser.Name 65 | } 66 | 67 | func getDate() string { 68 | var t = time.Now() 69 | return fmt.Sprintf("%v.%d.%v", t.Day(), t.Month(), t.Year()) 70 | } 71 | 72 | func getConsoleInput() { 73 | reader := bufio.NewReader(os.Stdin) 74 | 75 | for true { 76 | fmt.Print("Enter template (JAVA, JAVAV2, SWIFT): ") 77 | templateDirectory, _ = reader.ReadString('\n') 78 | templateDirectory = strings.ToLower(strings.TrimRight(templateDirectory, "\n")) 79 | 80 | if (templateDirectory != "java" && templateDirectory != "javav2" && templateDirectory != "swift") { 81 | continue 82 | } else { 83 | break 84 | } 85 | } 86 | 87 | fmt.Print("Enter module name (e.g. BasketList): ") 88 | moduleName, _ = reader.ReadString('\n') 89 | moduleName = strings.TrimRight(moduleName, "\n") 90 | moduleNamePackage = makeFirstLowerCase(moduleName) 91 | 92 | if (templateDirectory != "swift") { 93 | fmt.Print("Enter Java PackageName (e.g. com.company.mylittleProject): ") 94 | packageName, _ = reader.ReadString('\n') 95 | packageName = strings.TrimRight(packageName, "\n") 96 | } 97 | 98 | fmt.Print("Enter absolute output path: ") 99 | outputDir, _ = reader.ReadString('\n') 100 | outputDir = strings.TrimRight(outputDir, "\n") 101 | } 102 | 103 | func makeFirstLowerCase(s string) string { 104 | 105 | if len(s) < 2 { 106 | return strings.ToLower(s) 107 | } 108 | 109 | bts := []byte(s) 110 | 111 | lc := bytes.ToLower([]byte{bts[0]}) 112 | rest := bts[1:] 113 | 114 | return string(bytes.Join([][]byte{lc, rest}, nil)) 115 | } 116 | -------------------------------------------------------------------------------- /templates/java/Activity.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBar; 5 | import android.support.v7.widget.Toolbar; 6 | import android.view.MenuItem; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | import javax.inject.Inject; 12 | 13 | import butterknife.ButterKnife; 14 | import butterknife.InjectView; 15 | import de.jochen_schweizer.jsnow.common.baseui.BaseDaggerActivity; 16 | 17 | /** 18 | * Created by ##USERNAME## on ##DATE##. 19 | */ 20 | public class ##MODULENAME##Activity extends BaseDaggerActivity implements ##MODULENAME##PresenterOutput { 21 | @Inject ##MODULENAME##PresenterInput mPresenter; 22 | 23 | @Override 24 | protected void onInjected(Bundle savedInstanceState) { 25 | ButterKnife.inject(this); 26 | } 27 | 28 | @Override 29 | protected List getActivityModules() { 30 | return Arrays.asList(new ##MODULENAME##Module(this)); 31 | } 32 | 33 | @Override 34 | protected void customizeActionBar(ActionBar actionBar) { 35 | super.customizeActionBar(actionBar); 36 | actionBar.setDisplayHomeAsUpEnabled(true); 37 | } 38 | 39 | 40 | @Override 41 | protected void customizeToolbar(Toolbar toolbar) { 42 | super.customizeToolbar(toolbar); 43 | toolbar.setNavigationIcon(R.drawable.ico_navi_back); 44 | toolbar.setTitle(R.string.activity_checkout_title); 45 | } 46 | 47 | @Override 48 | public boolean onOptionsItemSelected(MenuItem item) { 49 | switch (item.getItemId()) { 50 | case android.R.id.home: 51 | finish(); 52 | return true; 53 | default: 54 | return super.onOptionsItemSelected(item); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /templates/java/Interactor.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public class ##MODULENAME##Interactor implements ##MODULENAME##InteractorInput { 7 | 8 | private ##MODULENAME##InteractorOutput mOutput; 9 | 10 | public ##MODULENAME##Interactor() { 11 | } 12 | 13 | @Override 14 | public void setInteractorOutput(##MODULENAME##InteractorOutput presenter) { 15 | mOutput = presenter; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /templates/java/InteractorInput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##InteractorInput { 7 | void setInteractorOutput(##MODULENAME##InteractorOutput presenter); 8 | } 9 | -------------------------------------------------------------------------------- /templates/java/InteractorOutput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##InteractorOutput { 7 | } 8 | -------------------------------------------------------------------------------- /templates/java/Module.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | import javax.inject.Singleton; 4 | 5 | import dagger.Module; 6 | import dagger.Provides; 7 | import de.jochen_schweizer.jsnow.application.JSNowModule; 8 | 9 | /** 10 | * Created by ##USERNAME## on ##DATE##. 11 | */ 12 | @Module( 13 | injects = ##MODULENAME##Activity.class, 14 | addsTo = JSNowModule.class, 15 | complete = false 16 | ) 17 | public class ##MODULENAME##Module { 18 | 19 | private ##MODULENAME##PresenterOutput mOutput; 20 | 21 | public ##MODULENAME##Module(##MODULENAME##PresenterOutput output) { 22 | mOutput = output; 23 | } 24 | 25 | @Provides 26 | @Singleton 27 | public ##MODULENAME##InteractorInput provide##MODULENAME##InteractorInput() { 28 | return new ##MODULENAME##Interactor(); 29 | } 30 | 31 | @Provides @Singleton public ##MODULENAME##PresenterInput provide##MODULENAME##PresenterInput(##MODULENAME##InteractorInput interactor) { 32 | ##MODULENAME##Presenter presenter = new ##MODULENAME##Presenter(mOutput, interactor); 33 | interactor.setInteractorOutput(presenter); 34 | return presenter; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /templates/java/Presenter.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | 4 | /** 5 | * Created by ##USERNAME## on ##DATE##. 6 | */ 7 | public class ##MODULENAME##Presenter implements ##MODULENAME##PresenterInput, ##MODULENAME##InteractorOutput{ 8 | private final ##MODULENAME##InteractorInput mInteractor; 9 | private final ##MODULENAME##PresenterOutput mOutput; 10 | 11 | public ##MODULENAME##Presenter(##MODULENAME##PresenterOutput output, ##MODULENAME##InteractorInput interactor) { 12 | mOutput = output; 13 | mInteractor = interactor; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /templates/java/PresenterInput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##PresenterInput { 7 | } 8 | -------------------------------------------------------------------------------- /templates/java/PresenterOutput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##PresenterOutput { 7 | } 8 | -------------------------------------------------------------------------------- /templates/javav2/Activity.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.ActionBar; 5 | import android.support.v7.widget.Toolbar; 6 | import android.view.MenuItem; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | import javax.inject.Inject; 12 | 13 | import butterknife.ButterKnife; 14 | import butterknife.InjectView; 15 | import de.jochen_schweizer.jsnow.common.baseui.BaseDaggerActivity; 16 | 17 | /** 18 | * Created by ##USERNAME## on ##DATE##. 19 | */ 20 | public class ##MODULENAME##Activity extends BaseDaggerActivity implements ##MODULENAME##PresenterOutput { 21 | @Inject ##MODULENAME##PresenterInput presenter; 22 | 23 | @Override 24 | protected void onInjected(Bundle savedInstanceState) { 25 | presenter.setPresenterOutput(this); 26 | ButterKnife.inject(this); 27 | } 28 | 29 | @Override 30 | protected List getActivityModules() { 31 | return Arrays.asList(new ##MODULENAME##Module()); 32 | } 33 | 34 | @Override 35 | protected void onDestroyDaggerInjector() { 36 | super.onDestroyDaggerInjector(); 37 | presenter.onDestroy(); 38 | } 39 | 40 | @Override 41 | protected void customizeActionBar(ActionBar actionBar) { 42 | super.customizeActionBar(actionBar); 43 | actionBar.setDisplayHomeAsUpEnabled(true); 44 | } 45 | 46 | 47 | @Override 48 | protected void customizeToolbar(Toolbar toolbar) { 49 | super.customizeToolbar(toolbar); 50 | toolbar.setNavigationIcon(R.drawable.ico_navi_back); 51 | toolbar.setTitle(R.string.activity_checkout_title); 52 | } 53 | 54 | @Override 55 | public boolean onOptionsItemSelected(MenuItem item) { 56 | switch (item.getItemId()) { 57 | case android.R.id.home: 58 | finish(); 59 | return true; 60 | default: 61 | return super.onOptionsItemSelected(item); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /templates/javav2/Interactor.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public class ##MODULENAME##Interactor implements ##MODULENAME##InteractorInput { 7 | 8 | private ##MODULENAME##InteractorOutput presenter; 9 | 10 | public ##MODULENAME##Interactor() { 11 | } 12 | 13 | @Override 14 | public void setInteractorOutput(##MODULENAME##InteractorOutput presenter) { 15 | this.presenter = presenter; 16 | } 17 | 18 | @Override 19 | public void onDestroy() { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /templates/javav2/InteractorInput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##InteractorInput { 7 | void setInteractorOutput(##MODULENAME##InteractorOutput presenter); 8 | void onDestroy(); 9 | } 10 | -------------------------------------------------------------------------------- /templates/javav2/InteractorOutput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##InteractorOutput { 7 | } 8 | -------------------------------------------------------------------------------- /templates/javav2/Module.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | import javax.inject.Singleton; 4 | 5 | import dagger.Module; 6 | import dagger.Provides; 7 | import de.jochen_schweizer.jsnow.application.JSNowModule; 8 | 9 | /** 10 | * Created by ##USERNAME## on ##DATE##. 11 | */ 12 | @Module( 13 | injects = ##MODULENAME##Activity.class, 14 | addsTo = JSNowModule.class, 15 | complete = false 16 | ) 17 | public class ##MODULENAME##Module { 18 | 19 | public ##MODULENAME##Module() { 20 | 21 | } 22 | 23 | @Provides @Singleton public ##MODULENAME##InteractorInput provide##MODULENAME##InteractorInput() { 24 | return new ##MODULENAME##Interactor(); 25 | } 26 | 27 | @Provides @Singleton public ##MODULENAME##PresenterInput provide##MODULENAME##PresenterInput(##MODULENAME##InteractorInput interactor) { 28 | ##MODULENAME##Presenter presenter = new ##MODULENAME##Presenter(interactor); 29 | interactor.setInteractorOutput(presenter); 30 | return presenter; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /templates/javav2/Presenter.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | 4 | /** 5 | * Created by ##USERNAME## on ##DATE##. 6 | */ 7 | public class ##MODULENAME##Presenter implements ##MODULENAME##PresenterInput, ##MODULENAME##InteractorOutput { 8 | private final ##MODULENAME##InteractorInput interactor; 9 | private ##MODULENAME##PresenterOutput view; 10 | 11 | public ##MODULENAME##Presenter(##MODULENAME##InteractorInput interactor) { 12 | this.interactor = interactor; 13 | } 14 | 15 | @Override 16 | public void setPresenterOutput(##MODULENAME##PresenterOutput view) { 17 | this.view = view; 18 | } 19 | 20 | @Override 21 | public void onDestroy() { 22 | interactor.onDestroy(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/javav2/PresenterInput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##PresenterInput { 7 | void setPresenterOutput(##MODULENAME##PresenterOutput view); 8 | void onDestroy(); 9 | } 10 | -------------------------------------------------------------------------------- /templates/javav2/PresenterOutput.java: -------------------------------------------------------------------------------- 1 | package ##PACKAGENAME##.##MODULENAME_PACKAGE##; 2 | 3 | /** 4 | * Created by ##USERNAME## on ##DATE##. 5 | */ 6 | public interface ##MODULENAME##PresenterOutput { 7 | } 8 | -------------------------------------------------------------------------------- /templates/swift/Interactor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ##MODULENAME##Interactor.swift 3 | // JSNow 4 | // 5 | // Created by ##USERNAME## on ##DATE##. 6 | // Copyright © 2015 Jochen Schweizer GmbH. All rights reserved. 7 | // 8 | 9 | import XCGLogger 10 | 11 | class ##MODULENAME##Interactor: NSObject { 12 | 13 | weak var output: ##MODULENAME##InteractorOutput! 14 | 15 | } 16 | 17 | // MARK: ##MODULENAME##InteractorInput 18 | 19 | extension ##MODULENAME##Interactor: ##MODULENAME##InteractorInput { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /templates/swift/Presenter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ##MODULENAME##Presenter.swift 3 | // JSNow 4 | // 5 | // Created by ##USERNAME## on ##DATE##. 6 | // Copyright © 2015 Jochen Schweizer GmbH. All rights reserved. 7 | // 8 | 9 | import XCGLogger 10 | 11 | class ##MODULENAME##Presenter: NSObject { 12 | 13 | var wireframe: ##MODULENAME##Wireframe! 14 | weak var userInterface: ##MODULENAME##ViewInterface? 15 | var interactor: ##MODULENAME##Interactor! 16 | 17 | } 18 | 19 | // MARK: ##MODULENAME##ModuleInterface 20 | 21 | extension ##MODULENAME##Presenter: ##MODULENAME##ModuleInterface { 22 | 23 | } 24 | 25 | // MARK: ##MODULENAME##InteractorOutput 26 | 27 | extension ##MODULENAME##Presenter: ##MODULENAME##InteractorOutput { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /templates/swift/Protocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ##MODULENAME##Protocols.swift 3 | // JSNow 4 | // 5 | // Created by ##USERNAME## on ##DATE##. 6 | // Copyright © 2015 Jochen Schweizer GmbH. All rights reserved. 7 | // 8 | 9 | protocol ##MODULENAME##ViewInterface: class { 10 | 11 | } 12 | 13 | protocol ##MODULENAME##ModuleInterface: class { 14 | 15 | } 16 | 17 | protocol ##MODULENAME##InteractorInput: class { 18 | 19 | } 20 | 21 | protocol ##MODULENAME##InteractorOutput: class { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /templates/swift/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ##MODULENAME##ViewController.swift 3 | // JSNow 4 | // 5 | // Created by ##USERNAME## on ##DATE##. 6 | // Copyright © 2015 Jochen Schweizer GmbH. All rights reserved. 7 | // 8 | 9 | import XCGLogger 10 | 11 | class ##MODULENAME##ViewController: JSViewController { 12 | 13 | var eventHandler: ##MODULENAME##ModuleInterface! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | title = JSUtils.LocalizedString("##MODULENAME_UPPERCASE##") 18 | 19 | } 20 | 21 | override func viewWillAppear(animated: Bool) { 22 | super.viewWillAppear(animated) 23 | // screenName = SCREEN_##MODULENAME_UPPERCASE## 24 | trackScreen() 25 | } 26 | 27 | override func shouldSetupMenuBarItem() -> Bool { 28 | return false 29 | } 30 | } 31 | 32 | // MARK: ##MODULENAME##ViewInterface 33 | 34 | extension ##MODULENAME##ViewController: ##MODULENAME##ViewInterface { 35 | 36 | } 37 | -------------------------------------------------------------------------------- /templates/swift/Wireframe.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ##MODULENAME##Wireframe.swift 3 | // JSNow 4 | // 5 | // Created by ##USERNAME## on ##DATE##. 6 | // Copyright © 2015 Jochen Schweizer GmbH. All rights reserved. 7 | // 8 | 9 | class ##MODULENAME##Wireframe: NSObject { 10 | 11 | func present##MODULENAME##Interface() { 12 | let vc = ##MODULENAME##ViewController() 13 | let presenter = ##MODULENAME##Presenter() 14 | vc.eventHandler = presenter 15 | presenter.wireframe = self 16 | let interactor = ##MODULENAME##Interactor() 17 | presenter.interactor = interactor 18 | presenter.userInterface = vc 19 | interactor.output = presenter 20 | Navigator.sharedInstance.pushViewController(vc, animated: true) 21 | } 22 | } 23 | --------------------------------------------------------------------------------