Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/bundler/rexml-3.2.8
Browse files Browse the repository at this point in the history
  • Loading branch information
rogerluan authored Jun 13, 2024
2 parents 9c06df7 + 08b61f5 commit bde602b
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 31 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Generate & Upload Code Coverage
on:
push:
branches:
- main
jobs:
test:
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: head
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- uses: paambaati/[email protected]
with:
coverageCommand: bundle exec rake
debug: true
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest]
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
ruby: ['2.7', '3.0', '3.1', head]
ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', head]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest]
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
ruby: ['2.7', '3.0', '3.1', head]
ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', head]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- uses: paambaati/[email protected]
with:
coverageCommand: bundle exec rake
debug: true
- name: Run tests
run: bundle exec rake
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
arkana (2.0.0)
arkana (2.1.0)
dotenv (~> 2.7)
rainbow (~> 3.1.1)
yaml (~> 0.2)
Expand Down
73 changes: 64 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,77 @@ Alternatively, you can install it in your entire system instead (not recommended
gem install arkana
```

# Usage
# Basic Usage

Arkana requires the declaration of a YAML config file. Although you can name it whatever, the convention is to name it `.arkana.yml`. See [template.yml](/template.yml) for practical examples.
Arkana requires the declaration of a YAML config file. Although you can name it whatever, the convention is to name it `.arkana.yml`. See [template.yml](/template.yml) for complete options.

Once you have create your config file, you can run Arkana:
Once you have created your config file, you can run Arkana:

```sh
Usage: arkana [options]
-c /path/to/your/.arkana.yml, Path to your config file. Defaults to '.arkana.yml'
--config-filepath
-e /path/to/your/.env, Path to your dotenv file. Defaults to '.env' if one exists.
--dotenv-filepath
-f, --flavor FrostedFlakes Flavors are useful, for instance, when generating secrets for white-label projects. See the README for more information
-i debug,release, Optionally pass the environments that you want Arkana to generate secrets for. Useful if you only want to build a certain environment, e.g. just Debug in local machines, while only building Staging and Release in CI. Separate the keys using a comma, without spaces. When omitted, Arkana generate secrets for all environments.
--include-environments
-l, --lang kotlin Language to produce keys for, e.g. kotlin, swift. Defaults to 'swift'. See the README for more information
-l kotlin Language to produce keys for, e.g. kotlin, swift. Defaults to 'swift'.
```
> [!NOTE]
> For the complete set of args, look at the [options](#options) section.
### Config File
The `arkana.yml` would typically contain 3 important sections:
- **Environments**: This is typically where you specify `debug`, `release` or other environments which you wish to create.
- **Environment Secrets**: This is where you declare the keys which will be ultimately exposed to your app, like `apiKey`.
- **Global Secrets**: Here you'd declare keys which are the same across all environments.
### Environment File
The environment (`.env`) file contains the actual secrets for each environment. While config file declares the keys, they are assigned encrypted values from this file.
This file is optional, but quite handy in local development. `.env` files shouldn't be committed as they contain your secrets. Instead, they should be stored in a secure location, like your CI/CD server as environment variables (all CI/CD servers have a way to store secrets securely). See [Continuous Integration](#continuous-integration) for more information.
#### Sample
A config file as shown below:
```yaml
environments:
- Release
- Debug
environment_secrets:
- apiKey
global_secrets:
- clientId
```
Coupled with an env file:
```properties
apiKeyDebug = "your_debug_api_key"
apiKeyRelease = "your_release_api_key"
clientId = "your_client_id"
```
Would generate the following accessors:
```swift
// Swift
public extension ArkanaKeys {
struct Global: ArkanaKeysGlobalProtocol {
public let clientId: String = {<decrypted accessor>}
}
}
public extension ArkanaKeys {
struct Release: ArkanaKeysEnvironmentProtocol {
public let apiKey: String = {<decrypted accessor>}
}
}
public extension ArkanaKeys {
struct Debug: ArkanaKeysEnvironmentProtocol {
public let apiKey: String = {<decrypted accessor>}
}
}
```
Note that you have to prepend `bundle exec` before `arkana` if you manage your dependencies via bundler, as recommended.
Expand Down
2 changes: 1 addition & 1 deletion docs/demo-used-to-gen-image.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object MySecrets {
val decoded = encoded.mapIndexed { index, item ->
(item xor cipher[(index % cipher.size)]).toByte()
}.toByteArray()
return decoded.toString(Charsets.UTF_8)
return decoded.decodeToString()
}

internal fun decodeInt(encoded: List<Int>, cipher: List<Int>): Int {
Expand Down
Binary file modified docs/kotlin-demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 10 additions & 5 deletions lib/arkana/kotlin_code_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,27 @@ module KotlinCodeGenerator
# Generates Kotlin code and test files for the given template arguments.
def self.generate(template_arguments:, config:)
kotlin_module_dir = config.result_path
kotlin_sources_dir = File.join(kotlin_module_dir, "src", "main", config.kotlin_sources_path, config.kotlin_package_name.split("."))
kotlin_tests_dir = File.join(kotlin_module_dir, "src", "test", config.kotlin_sources_path, config.kotlin_package_name.split("."))

source_set = config.is_kotlin_multiplatform_module ? "commonMain" : "main"
test_set = config.is_kotlin_multiplatform_module ? "commonTest" : "test"

kotlin_sources_dir = File.join(kotlin_module_dir, "src", source_set, config.kotlin_sources_path, config.kotlin_package_name.split("."))
kotlin_tests_dir = File.join(kotlin_module_dir, "src", test_set, config.kotlin_sources_path, config.kotlin_package_name.split("."))

if config.should_generate_gradle_build_file
set_up_kotlin_module(kotlin_module_dir, template_arguments)
set_up_kotlin_module(kotlin_module_dir, template_arguments, config)
end

set_up_kotlin_interfaces(kotlin_sources_dir, template_arguments, config)
set_up_kotlin_classes(kotlin_sources_dir, kotlin_tests_dir, template_arguments, config)
end

def self.set_up_kotlin_module(path, template_arguments)
def self.set_up_kotlin_module(path, template_arguments, config)
dirname = File.dirname(__FILE__)
sources_dir = path
readme_template = File.read("#{dirname}/templates/readme.erb")
source_template = File.read("#{dirname}/templates/kotlin/build.gradle.kts.erb")
gradle_template_file = config.is_kotlin_multiplatform_module ? "build_kmp.gradle.kts.erb" : "build.gradle.kts.erb"
source_template = File.read("#{dirname}/templates/kotlin/#{gradle_template_file}")
FileUtils.mkdir_p(path)
render(readme_template, template_arguments, File.join(path, "README.md"))
render(source_template, template_arguments, File.join(sources_dir, "build.gradle.kts"))
Expand Down
4 changes: 4 additions & 0 deletions lib/arkana/models/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class Config
attr_reader :should_generate_gradle_build_file
# @returns [int]
attr_reader :kotlin_jvm_toolchain_version
# @returns [boolean]
attr_reader :is_kotlin_multiplatform_module

# @returns [string]
attr_accessor :current_flavor
Expand Down Expand Up @@ -64,6 +66,8 @@ def initialize(yaml)
@should_generate_gradle_build_file = yaml["should_generate_gradle_build_file"]
@should_generate_gradle_build_file = true if @should_generate_gradle_build_file.nil?
@kotlin_jvm_toolchain_version = yaml["kotlin_jvm_toolchain_version"] || 11
@is_kotlin_multiplatform_module = yaml["is_kotlin_multiplatform_module"]
@is_kotlin_multiplatform_module = false if @should_generate_gradle_build_file.nil?
end
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity

Expand Down
2 changes: 1 addition & 1 deletion lib/arkana/templates/kotlin/arkana.kt.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object <%= @namespace %> {
val decoded = encoded.mapIndexed { index, item ->
(item xor cipher[(index % cipher.size)]).toByte()
}.toByteArray()
return decoded.toString(Charsets.UTF_8)
return decoded.decodeToString()
}
internal fun decodeInt(encoded: List<Int>, cipher: List<Int>): Int {
Expand Down
28 changes: 28 additions & 0 deletions lib/arkana/templates/kotlin/build_kmp.gradle.kts.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// DO NOT MODIFY
// Automatically generated by Arkana (https://github.com/rogerluan/arkana)

plugins {
id("org.jetbrains.kotlin.multiplatform")
}

kotlin {
jvm()
iosX64()
iosArm64()
iosSimulatorArm64()
linuxX64()
js {
browser()
nodejs()
}

sourceSets {
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
}

jvmToolchain(<%= @kotlin_jvm_toolchain_version %>)
}
2 changes: 1 addition & 1 deletion lib/arkana/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Arkana
VERSION = "2.0.0"
VERSION = "2.1.0"
end
42 changes: 35 additions & 7 deletions spec/kotlin_code_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,45 @@
let(:kotlin_sources_dir) { File.join(kotlin_module_dir, "src", "main", config.kotlin_sources_path, config.kotlin_package_name.split(".")) }
let(:kotlin_tests_dir) { File.join(kotlin_module_dir, "src", "test", config.kotlin_sources_path, config.kotlin_package_name.split(".")) }

let(:kmp_sources_dir) { File.join(kotlin_module_dir, "src", "commonMain", config.kotlin_sources_path, config.kotlin_package_name.split(".")) }
let(:kmp_tests_dir) { File.join(kotlin_module_dir, "src", "commonTest", config.kotlin_sources_path, config.kotlin_package_name.split(".")) }

def path(...)
Pathname.new(File.join(...))
end

it "generates all necessary directories and files" do
described_class.generate(template_arguments: template_arguments, config: config)
expect(Pathname.new(config.result_path)).to be_directory
expect(path(kotlin_module_dir, "README.md")).to be_file
expect(path(kotlin_module_dir, "build.gradle.kts")).to be_file
expect(path(kotlin_sources_dir, "#{config.namespace}Environment.kt")).to be_file
expect(path(kotlin_sources_dir, "#{config.namespace}.kt")).to be_file
context "when 'config.is_kotlin_multiplatform_module'" do
context "when is 'false'" do
before do
allow(config).to receive(:is_kotlin_multiplatform_module).and_return(false)
described_class.generate(template_arguments: template_arguments, config: config)
end

it "generates all necessary directories and files" do
described_class.generate(template_arguments: template_arguments, config: config)
expect(Pathname.new(config.result_path)).to be_directory
expect(path(kotlin_module_dir, "README.md")).to be_file
expect(path(kotlin_module_dir, "build.gradle.kts")).to be_file
expect(path(kotlin_sources_dir, "#{config.namespace}Environment.kt")).to be_file
expect(path(kotlin_sources_dir, "#{config.namespace}.kt")).to be_file
end
end

context "when is 'true'" do
before do
allow(config).to receive(:is_kotlin_multiplatform_module).and_return(true)
described_class.generate(template_arguments: template_arguments, config: config)
end

it "generates all necessary directories and files" do
described_class.generate(template_arguments: template_arguments, config: config)
expect(Pathname.new(config.result_path)).to be_directory
expect(path(kotlin_module_dir, "README.md")).to be_file
expect(path(kotlin_module_dir, "build.gradle.kts")).to be_file
expect(path(kmp_sources_dir, "#{config.namespace}Environment.kt")).to be_file
expect(path(kmp_sources_dir, "#{config.namespace}.kt")).to be_file
end
end
end

context "when 'config.should_generate_gradle_build_file'" do
Expand Down
1 change: 1 addition & 0 deletions template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package_manager: cocoapods # Optional. This setting defines which type of depend
kotlin_package_name: 'com.arkanakeys' # Optional. The package name of the generated Kotlin module. Defaults to com.arkanakeys.
kotlin_sources_path: 'java' # Optional. The path for the generated Kotlin classes. Defaults to kotlin.
should_generate_gradle_build_file: true # Optional. Whether a build.gradle file should be generated, when running the Kotlin generator. One of: true, false. Defaults to true.
is_kotlin_multiplatform_module: true # Optional. Whether the generated Kotlin module is a multiplatform module. One of: true, false. Defaults to false.
kotlin_jvm_toolchain_version: 11 # Optional. The kotlin JVM toolchain JDK version to be used in the generated build.gradle file. Defaults to 11.
environments: # Optional. List of environments that will be used to generate secret keys when you have keys that are different between environments (e.g. debug/staging/prod). Defaults to empty.
- Debug
Expand Down

0 comments on commit bde602b

Please sign in to comment.