#generator #multi-platform #configuration #kotlin #mobile #template #projects

kmmp-generator

kmmp-generator allows one to automate the setup of Kotlin Multiplatform Mobile (KMM) projects. Simplify the creation of KMM projects by generating project structures, managing configurations, handling dependencies, and providing customizable code templates.

1 unstable release

Uses old Rust 2015

0.1.0 Jun 18, 2023

#531 in Configuration

MIT license

22KB
91 lines

kmmp-generator

Kotlin Multiplatform Project Generator allows one to automate the setup of Kotlin Multiplatform Mobile (KMM) projects. Simplify the creation of KMM projects by generating project structures, managing configurations, handling dependencies, and providing customizable code templates.

Todo REMOVE THIS BELOW AND MOVE TO RUST DOCS IN KMMP-STRUCTURE REPO

Project Generation

mod generator;

use generator::gradle;

use generator::module::Module;

use gradle::gradle_file::{Target,TargetInfo,Gradle};

use gradle::block;
use block::dependency::{Dependencies,Dependency,DependencyType};
use block::metadata::Metadata;
use block::plugin::{Plugins,Plugin};
use block::android_manifest::AndroidManifest;

use generator::create::Create;


use generator::project::Project;

fn createModuleInstance(moduleName : &str) -> Module {
    let plugins = Plugins(vec![
        Plugin {
            isStandardLibrarySupported: true,
            name: "plugin1",
            apply: Some(false),
        },
        Plugin {
            isStandardLibrarySupported: false,
            name: "plugin2",
            apply: Some(true),
        },
    ]);
 
    let metadata = Metadata {
        module : moduleName,
        namespace: "com.deathsdoor.test",
        version: "1.0.0",
        javaVersion: "11",
        iosDeploymentTarget: "14.0",
        minSdk: 21,
        maxSdk: 30,
    };
 
    let targets = vec![
        TargetInfo {
            name: "android",
            includeTest: false,
            target : Target::Android,
            dependencies: Dependencies(vec![
                Dependency {
                    dependencyType: DependencyType::Implementation,
                    name: "example1",
                    version: Some("1.0"),
                },
                Dependency {
                    dependencyType: DependencyType::Api,
                    name: "example2",
                    version: None,
                },
            ]),
        },
    ];
 
    let gradle = Gradle {
        plugins : plugins,
        metadata : metadata,
        commonDependencies : Dependencies(vec![
            Dependency {
                dependencyType: DependencyType::Implementation,
                name: "example1",
                version: Some("1.0"),
            },
            Dependency {
                dependencyType: DependencyType::Api,
                name: "example2",
                version: None,
            },
        ]),
        targets : targets,
    };

    let manifest = AndroidManifest {
        permissions : vec![
            "READ_EXTERNAL_STORAGE",
        ],
        namespace : "com.deathsdoor.test"
    };

    Module {
        gradle : gradle,
        manifest : Some(manifest)
    }
}

fn main() {
    let modules = vec![
        createModuleInstance("android"),
        createModuleInstance("web"),
        createModuleInstance("desktop"),
    ];

    let project = Project {
        modules : modules,
        androidSdkDirectory : "SOME\\PATH",
        properites : vec!["property1", "property2"],
        dependencyRepositories: vec!["repo1", "repo2"],
        pluginRepositories: vec!["plugin_repo1", "plugin_repo2"],
        plugins : Plugins(vec![
            Plugin {
                isStandardLibrarySupported: true,
                name: "plugin1",
                apply: Some(false),
            },
            Plugin {
                isStandardLibrarySupported: false,
                name: "plugin2",
                apply: Some(true),
            },
        ])

    };

    project.create(r"C:\Users\%USERNAME%\Desktop");
}

Module Generation

Android Only Module

mod generator;

use generator::gradle;

use generator::module::Module;

use gradle::gradle_file::{Target,TargetInfo,Gradle};

use gradle::block;
use block::dependency::{Dependencies,Dependency,DependencyType};
use block::metadata::Metadata;
use block::plugin::{Plugins,Plugin};
use block::android_manifest::AndroidManifest;

use generator::create::Create;

fn main() {
    let plugins = Plugins(vec![
        Plugin {
            isStandardLibrarySupported: true,
            name: "plugin1",
            apply: Some(false),
        },
        Plugin {
            isStandardLibrarySupported: false,
            name: "plugin2",
            apply: Some(true),
        },
    ]);
 
    let metadata = Metadata {
        module : "module",
        namespace: "com.deathsdoor.test",
        version: "1.0.0",
        javaVersion: "11",
        iosDeploymentTarget: "14.0",
        minSdk: 21,
        maxSdk: 30,
    };
 
    let targets = vec![
        TargetInfo {
            name: "android",
            includeTest: false,
            target : Target::Android,
            dependencies: Dependencies(vec![
                Dependency {
                    dependencyType: DependencyType::Implementation,
                    name: "example1",
                    version: Some("1.0"),
                },
                Dependency {
                    dependencyType: DependencyType::Api,
                    name: "example2",
                    version: None,
                },
            ]),
        },
    ];
 
    let gradle = Gradle {
        plugins : plugins,
        metadata : metadata,
        commonDependencies : Dependencies(vec![
            Dependency {
                dependencyType: DependencyType::Implementation,
                name: "example1",
                version: Some("1.0"),
            },
            Dependency {
                dependencyType: DependencyType::Api,
                name: "example2",
                version: None,
            },
        ]),
        targets : targets,
    };

    let manifest = AndroidManifest {
        permissions : vec![
            "READ_EXTERNAL_STORAGE",
        ],
        namespace : "com.deathsdoor.test"
    };

    let module = Module {
        gradle : gradle,
        manifest : Some(manifest)
    };

    module.create(r"C:\Users\Aarav Aditya Shah\Desktop"); // File will be outputed here with correct android module structure
}

Multiple Target Module

mod generator;

use generator::gradle;

use generator::module::Module;

use gradle::gradle_file::{Target,TargetInfo,Gradle};

use gradle::block;
use block::dependency::{Dependencies,Dependency,DependencyType};
use block::metadata::Metadata;
use block::plugin::{Plugins,Plugin};
use block::android_manifest::AndroidManifest;

use generator::create::Create;

fn main() {
    let plugins = Plugins(vec![
        Plugin {
            isStandardLibrarySupported: true,
            name: "plugin1",
            apply: Some(false),
        },
        Plugin {
            isStandardLibrarySupported: false,
            name: "plugin2",
            apply: Some(true),
        },
    ]);
 
    let metadata = Metadata {
        module : "module",
        namespace: "com.deathsdoor.test",
        version: "1.0.0",
        javaVersion: "11",
        iosDeploymentTarget: "14.0",
        minSdk: 21,
        maxSdk: 30,
    };
 
    let targets = vec![
        TargetInfo {
            name: "android",
            includeTest: false,
            target : Target::Android,
            dependencies: Dependencies(vec![
                Dependency {
                    dependencyType: DependencyType::Implementation,
                    name: "example1",
                    version: Some("1.0"),
                },
                Dependency {
                    dependencyType: DependencyType::Api,
                    name: "example2",
                    version: None,
                },
            ]),
        },
        TargetInfo {
            name: "desktop",
            target : Target::Desktop,
            includeTest: false,
            dependencies: Dependencies(vec![
                Dependency {
                    dependencyType: DependencyType::Implementation,
                    name: "example1",
                    version: Some("1.0"),
                },
                Dependency {
                    dependencyType: DependencyType::Api,
                    name: "example2",
                    version: None,
                },
            ]),
        },
    ];
 
    let gradle = Gradle {
        plugins : plugins,
        metadata : metadata,
        commonDependencies : Dependencies(vec![
            Dependency {
                dependencyType: DependencyType::Implementation,
                name: "example1",
                version: Some("1.0"),
            },
            Dependency {
                dependencyType: DependencyType::Api,
                name: "example2",
                version: None,
            },
        ]),
        targets : targets,
    };

    let manifest = AndroidManifest {
        permissions : vec![
            "READ_EXTERNAL_STORAGE",
        ],
        namespace : "com.deathsdoor.test"
    };

    let module = Module {
        gradle : gradle,
        manifest : Some(manifest)
    };

    module.create(r"C:\Users\Aarav Aditya Shah\Desktop"); // File will be outputed here
}

File Generation Usage

mod generator;
use gradle::gradle_file::Gradle;
//Create is there for each struct that can is a file itself
use generator::create::Create;

fn main() { 
    gradle.create("C:\\Users\\Output"); // File will be outputed here
}

Methods Usage

Metadata Generation

use crate::gradle::metadata

fn main() {
    let metadata = Metadata::new(
        "com.deathsdoor",
        "1.0.0",
        "1.8",
        "14.0",
        21,
        30,
    );

    println!("{}", metadata.to_string());
}

Output

object Metadata {
    const val namespace = "com.deathsdoor"
    const val version = "1.0.0"
    
    val asJavaVersionEnum = JavaVersion.values().find { it.name.endsWith(javaVersion) }
    
    const val javaVersion = "11"
    const val iosDeploymentTarget = "14.0"
    
    const val minSdk = 21
    const val minSdk = 30
}

Dependencies Generation

use crate::gradle::dependency;

fn main(){
    let dependencies = Dependencies(vec![
         Dependency {
            dependencyType: DependencyType::Implementation,
            name: "example1",
            version: Some("1.0"),
        },
        Dependency {
            dependencyType: DependencyType::Api,
            name: "example2",
            version: None,
        },
        Dependency {
            dependencyType: DependencyType::Implementation,
            name: "example3",
            version: Some("2.0"),
        },
        Dependency {
            dependencyType: DependencyType::Api,
            name: "example4",
            version: None,
        },
    ]);

    println!("{}", metadata.to_string());
}

Output

dependencies {
    implemenation("example1:1.0")
    api(project(":example2"))
    implemenation("example3:2.0")
    api(project(":example4"))
}

Plugin Generation

fn main() {
   let plugins_with_apply = Plugins(vec![
       Plugin {
           name: "plugin1",
           isStandardLibrarySupported: true,
           apply: Some(true),
       },
       Plugin {
           name: "plugin2",
           isStandardLibrarySupported: false,
           apply: Some(false),
       },
   ]);

   let plugins_without_apply = Plugins(vec![
       Plugin {
           name: "plugin3",
           isStandardLibrarySupported: true,
           apply: None,
       },
       Plugin {
           name: "plugin4",
           isStandardLibrarySupported: false,
           apply: None,
       },
   ]);

   println!("Plugins with apply:\n{}", plugins_with_apply);
   println!("Plugins without apply:\n{}", plugins_without_apply);
}

Output

//Plugins with apply:
plugin {
   kotlin("plugin1") apply true
   id("plugin2") apply false
}

//Plugins without apply:
plugin {
   kotlin("plugin3")
   id("plugin4")
}

Gradle

Shared

mod generator;

use generator::gradle;

use gradle::gradle_file::{Targets,Gradle};

use gradle::block;
use block::dependency::{Dependencies,Dependency,DependencyType};
use block::metadata::Metadata;
use block::plugin::{Plugins,Plugin};

fn main() {
   let plugins = Plugins(vec![
       Plugin {
           isStandardLibrarySupported: true,
           name: "plugin1",
           apply: Some(false),
       },
       Plugin {
           isStandardLibrarySupported: false,
           name: "plugin2",
           apply: Some(true),
       },
   ]);

   let metadata = Metadata {
       namespace: "com.deathsdoor",
       version: "1.0.0",
       javaVersion: "11",
       iosDeploymentTarget: "14.0",
       minSdk: 21,
       maxSdk: 30,
   };

   let targets = vec![
       Targets::Android(Dependencies(vec![
           Dependency {
               dependencyType: DependencyType::Implementation,
               name: "example1",
               version: Some("1.0"),
           },
           Dependency {
               dependencyType: DependencyType::Api,
               name: "example2",
               version: None,
           },
       ])),
       Targets::Desktop(Dependencies(vec![
           Dependency {
               dependencyType: DependencyType::Implementation,
               name: "example1",
               version: Some("1.0"),
           },
           Dependency {
               dependencyType: DependencyType::Api,
               name: "example2",
               version: None,
           },
       ])),
   ];

   let gradle = Gradle {
       plugins : plugins,
       metadata : metadata,
       commonDependencies : Dependencies(vec![
           Dependency {
               dependencyType: DependencyType::Implementation,
               name: "example1",
               version: Some("1.0"),
           },
           Dependency {
               dependencyType: DependencyType::Api,
               name: "example2",
               version: None,
           },
       ]),
       targets : targets,
   };
   println!("{}",gradle.to_string());
}

Output

plugin {
    kotlin("plugin1") apply false
    id("plugin2") apply true
}

object Metadata {
    const val namespace = "com.deathsdoor"
    const val version = "1.0.0"

    const val javaVersion = "11"
    val asJavaVersionEnum  = JavaVersion.values().find { it.name.endsWith(javaVersion) }
    const val iosDeploymentTarget = "14.0"

    const val minSDK = 21
    const val maxSDK = 30
}

kotlin {

    android {
        compilations.all {
            kotlinOptions {
                jvmTarget = Metadata.javaVersion
            }
        }
    }

    js(IR) {
        browser()
        nodejs()
        binaries.executable()
    }

    jvm("desktop") {
        compilations.all {
            kotlinOptions {
                jvmTarget = Metadata.javaVersion
            }
        }
    }

    iosX64()
    iosArm64()
    iosSimulatorArm64()
    sourceSets {
    }
}

Dependencies

~0.5–1MB
~25K SLoC