8000 Update code for Inko 0.15.0 · yorickpeterse/clogs@2c3896e · GitHub
[go: up one dir, main page]

Skip to content

Commit

Permalink
Update code for Inko 0.15.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yorickpeterse committed Jun 4, 2024
1 parent 99f81d4 commit 2c3896e
Show file tree
Hide file tree
Showing 14 changed files with 529 additions and 528 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ changelog.

## Requirements

- Inko 0.14.0 or newer
- Inko 0.15.0 or newer
- Git

Generating changelogs comes with the following workflow requirements:
Expand All @@ -122,7 +122,6 @@ Generating changelogs comes with the following workflow requirements:
To build from source:

```
inko pkg sync
inko build -o build/clogs
```

Expand Down
1 change: 0 additions & 1 deletion inko.pkg

This file was deleted.

79 changes: 37 additions & 42 deletions src/clogs/changelog.inko
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import clogs.config.Config
import clogs.git.Commit
import clogs.version.Version
import std.fs.file.(ReadOnlyFile, WriteOnlyFile)
import std.fs.path.Path
import std.io.Error
import std.string.(StringBuffer, ToString)
import std.time.DateTime
import clogs.config (Config)
import clogs.git (Commit)
import clogs.version (Version)
import std.fs.file (ReadOnlyFile, WriteOnlyFile)
import std.fs.path (Path)
import std.io (Error)
import std.string (StringBuffer, ToString)
import std.time (DateTime)

let LF = 10

let DEFAULT_CHANGELOG = '<!-- This changelog is managed by \
https://github.com/yorickpeterse/clogs -->
let DEFAULT_CHANGELOG = '<!-- This changelog is managed by https://github.com/yorickpeterse/clogs -->
# Changelog'

fn format_date(date: ref DateTime) -> String {
"{date.year}-{date.month.to_string.pad_start('0', chars: 2)}\
-{date.day.to_string.pad_start('0', chars: 2)}"
'${date.year}-${date.month.to_string.pad_start('0', chars: 2)}-${date.day.to_string.pad_start('0', chars: 2)}'
}

class Release {
Expand All @@ -31,13 +28,13 @@ class Release {
previous_version: Option[Version],
date: DateTime,
) -> Release {
Release {
@config = config,
@version = version,
@previous_version = previous_version,
@date = date,
@commits = Map.new,
}
Release(
config: config,
version: version,
previous_version: previous_version,
date: date,
commits: Map.new,
)
}

fn mut add(commit: Commit) {
Expand All @@ -50,29 +47,30 @@ class Release {

impl ToString for Release {
fn pub to_string -> String {
let markdown =
StringBuffer.from_array(["## {@version} ({format_date(@date)})"])
let markdown = StringBuffer.from_array(
['## ${@version} (${format_date(@date)})'],
)

if @commits.size == 0 {
markdown.push("\n\nNo changes.")
markdown.push('\n\nNo changes.')
return markdown.into_string
}

@config.categories.iter.each fn (pair) {
@config.categories.iter.each(fn (pair) {
let commits = match @commits.opt(pair.key) {
case Some(v) if v.size > 0 -> v
case _ -> return
}

markdown.push("\n\n### {pair.value}\n")
markdown.push('\n\n### ${pair.value}\n')

commits.iter.each fn (c) {
commits.iter.each(fn (c) {
let url = @config.url.replace('%s', c.id)
let short = c.id.slice(start: 0, size: 7)

markdown.push("\n- [{short}]({url}): {c.subject}")
}
}
markdown.push('\n- [${short}](${url}): ${c.subject}')
})
})

markdown.into_string
}
Expand All @@ -86,27 +84,26 @@ class Changelog {
let data = if path.file? {
let buf = ByteArray.new

try ReadOnlyFile.new(path.clone).then fn (f) { f.read_all(buf) }
try ReadOnlyFile.new(path.clone).then(fn (f) { f.read_all(buf) })
buf.into_string
} else {
DEFAULT_CHANGELOG
}

Result.Ok(Changelog { @path = path.clone, @data = data })
Result.Ok(Changelog(path: path.clone, data: data))
}

fn pub mut add(release: ref Release) {
let prev_idx = match release.previous_version {
case Some(v) -> @data
.byte_index(of: "## {v} (", starting_at: 0)
.unwrap_or(-1)
case Some(v) -> @data.byte_index(of: '## ${v} (', starting_at: 0).or(-1)
case _ -> -1
}

@data = if prev_idx >= 0 {
let new = @data.slice(start: 0, size: prev_idx - 1)

if new.size > 0 { new.push(LF) }

new.append(release.to_string.to_byte_array)
new.push(LF)
new.push(LF)
Expand All @@ -115,22 +112,20 @@ class Changelog {
} else {
let sep = if @data.empty? {
''
} else if @data.ends_with?("\n") {
"\n"
} else if @data.ends_with?('\n') {
'\n'
} else {
"\n\n"
'\n\n'
}

StringBuffer
.from_array([@data, sep, release.to_string, "\n"])
.into_string
StringBuffer.from_array([@data, sep, release.to_string, '\n']).into_string
}
}

fn pub mut save -> Result[Nil, Error] {
WriteOnlyFile.new(@path.clone).then fn (f) {
WriteOnlyFile.new(@path.clone).then(fn (f) {
try f.write_string(@data)
Result.Ok(nil)
}
})
}
}
108 changes: 53 additions & 55 deletions src/clogs/cli.inko
D7AE
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import clogs.changelog.(Changelog, Release)
import clogs.config.(CONFIG_FILE, Config)
import clogs.git.(Commit, Repository)
import clogs.version.Version
import optparse.(Help, Matches, Options)
import std.fs.file.(ReadOnlyFile, WriteOnlyFile)
import std.fs.path.Path
import std.io.Write
import std.set.Set
import std.string.StringBuffer
import std.sys.(exit)
import std.time.DateTime
import clogs.changelog (Changelog, Release)
import clogs.config (CONFIG_FILE, Config)
import clogs.git (Commit, Repository)
import clogs.version (Version)
import std.fs.file (ReadOnlyFile, WriteOnlyFile)
import std.fs.path (Path)
import std.io (Write)
import std.optparse (Help, Matches, Options)
import std.set (Set)
import std.string (StringBuffer)
import std.sys (exit)
import std.time (DateTime)

let VERSION = '0.3.0'

Expand All @@ -19,19 +19,15 @@ fn show_help(options: ref Options, output: mut Write) {
.usage('[OPTIONS] [VERSION | COMMAND]')
.section('Examples')
.line(
'clogs 1.2.3 Generate a changelog for version 1.2.3'
)
.line(
'clogs 1.2.3 --config foo.json Use a custom configuration file'
)
.line(
'clogs init Generate a new configuration file'
'clogs 1.2.3 Generate a changelog for version 1.2.3',
)
.line('clogs 1.2.3 --config foo.json Use a custom configuration file')
.line('clogs init Generate a new configuration file')
.section('Options')
.options(options)
.to_string

output.write_string(help).unwrap
output.write_string(help).get
}

fn pub run(
Expand All @@ -57,30 +53,29 @@ fn pub run(
}

if matches.contains?('version') {
output.print("clogs {VERSION}").unwrap
output.print('clogs ${VERSION}').get
return Result.Ok(nil)
}

let config_path = matches
.value('config')
.map fn (v) { v.to_path }
.unwrap_or_else fn { working_directory.join(CONFIG_FILE) }
.to_path
let config_path = matches.value('config').map(fn (v) { v.to_path }).or_else(
fn { working_directory.join(CONFIG_FILE) },
)

match matches.remaining.opt(0) {
case Some('init') if config_path.file? ->
Result.Error("the configuration file '{config_path}' already exists")
case Some('init') if config_path.file? -> {
Result.Error("the configuration file '${config_path}' already exists")
}
case Some('init') -> {
Config.default.save(config_path)
Result.Ok(nil)
}
case Some(val) -> match Version.parse(val) {
case Some(version) -> update(
config_path,
version,
matches.value('end').unwrap_or('HEAD')
)
case _ -> Result.Error('a version in the format X.Y.Z is required')
case Some(val) -> {
match Version.parse(val) {
case Some(version) -> {
update(config_path, version, matches.value('end').or('HEAD'))
}
case _ -> Result.Error('a version in the format X.Y.Z is required')
}
}
case _ -> {
show_help(opts, output)
Expand All @@ -96,50 +91,53 @@ fn update(
) -> Result[Nil, String] {
let config = match Config.load(config_path) {
case Ok(v) -> v
case Error(e) -> throw "failed to read {config_path}: {e}"
case Error(e) -> throw 'failed to read ${config_path}: ${e}'
}

let config_dir = config_path.directory
let repo = Repository.new(config_dir)
let versions = match repo.versions {
case Ok(iter) -> iter.to_array
case Error(e) -> throw "failed to get the Git tags: {e}"
case Error(e) -> throw 'failed to get the Git tags: ${e}'
}

if versions.contains?(version).false? { versions.push(version.clone) }

versions.sort

# At this point it's guaranteed our version is in the Array, so it's safe to
# unwrap the index.
let index = versions.index_of(version).unwrap
let prev_version = versions.opt(index - 1).map fn (v) { v.clone }
# get the index.
let index = versions.index_of(version).get
let prev_version = versions.opt(index - 1).map(fn (v) { v.clone })
let start = match ref prev_version {
case Some(ver) -> ver.tag_name
case _ -> match repo.first_commit {
case Ok(v) -> v
case Error(e) -> throw "failed to get the first commit: {e}"
case _ -> {
match repo.first_commit {
case Ok(v) -> v
case Error(e) -> throw 'failed to get the first commit: ${e}'
}
}
}

let commits = try repo
.changelog_commits(start, end)
.map_error fn (e) { "failed to get the changelog commits: {e}" }
let commits = try repo.changelog_commits(start, end).map_error(fn (e) {
'failed to get the changelog commits: ${e}'
})

let reverts = try repo
.reverted_commits(start, end)
.map_error fn (e) { "failed to get the list of reverted commits: {e}" }
let reverts = try repo.reverted_commits(start, end).map_error(fn (e) {
'failed to get the list of reverted commits: ${e}'
})

let release = Release.new(config, version, prev_version, date: DateTime.utc)

commits.select fn (c) { reverts.contains?(c.id).false? }.each fn (c) {
commits.select(fn (c) { reverts.contains?(c.id).false? }).each(fn (c) {
release.add(c)
}
})

let out_path = config_dir.join(config.changelog)
let changelog = try Changelog
.load(out_path.clone)
.map_error fn (e) { "failed to read {out_path}: {e}" }
let changelog = try Changelog.load(out_path.clone).map_error(fn (e) {
'failed to read ${out_path}: ${e}'
})

changelog.add(release)
changelog.save.map_error fn (e) { "failed to update {out_path}: {e}" }
changelog.save.map_error(fn (e) { 'failed to update ${out_path}: ${e}' })
}
Loading

0 comments on commit 2c3896e

Please sign in to comment.
0