Skip to content
This repository has been archived by the owner on May 13, 2020. It is now read-only.

replace usage of options with cli #95

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ifdef config
endif

ifeq ($(config),release)
PONYC = ponyc
PONYC = ponyc
else
PONYC = ponyc --debug
endif
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Checking connectivity... done.
## Compile in a stable environment.

```bash
stable env ponyc --debug
stable env -- ponyc --debug
# The local paths to the dependencies listed in `bundle.json`
# will be included in the `PONYPATH` environment variable,
# available to `use` in the `ponyc` invocation.
Expand Down
7 changes: 5 additions & 2 deletions doc/cli/stable-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ stable-env(1) -- run a command in a stable environment

## SYNOPSIS

stable env <command>
stable env -- <command>

## DESCRIPTION

This command allows you to run another command with the environment
needed for `ponyc` to use your stable-managed dependencies. Use
this command with `ponyc` to build your project.

In order to separate options given to `command` from options for `stable`,
always separate the `command` with a double dash `--` from the `stable` parts of the command line.

## EXAMPLES

stable env ponyc
stable env -- ponyc --debug
34 changes: 31 additions & 3 deletions stable/_bundle_locator.pony
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
use "files"

primitive _BundleLocator
fun apply(env: Env, start_path: String): (String | None) =>
class _BundleLocator
let _auth: AmbientAuth
let _log: Log
new create(auth: AmbientAuth, log: Log) =>
_auth = auth
_log = log

fun locate(start_path: String): (String | None) =>
"""
find a path, starting from start_path, that contains a bundle.json,
ascend into parent directories if none is found locally.
"""
var path = start_path
while path.size() > 0 do
let candidate = try
FilePath(env.root as AmbientAuth, path)?.join("bundle.json")?
FilePath(_auth, path)?.join("bundle.json")?
else
return None
end
Expand All @@ -17,3 +27,21 @@ primitive _BundleLocator
end

None

fun load_from_cwd(create_on_missing: Bool = false): Bundle ? =>
"""
locate and load a bundle from the current working directory
"""
let cwd = Path.cwd()
match locate(cwd)
| let path: String =>
Bundle(FilePath(_auth, path)?, _log, false)?
| None =>
if create_on_missing then
Bundle(FilePath(_auth, cwd)?, _log, true)?
else
_log("No bundle.json in current working directory or ancestors.")
error
end
end

11 changes: 7 additions & 4 deletions stable/_test.pony
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ class _TestBundleLocator is UnitTest
Path.join("stable/test/testdata", subpath).string()

fun apply(h: TestHelper) ? =>
let locator = _BundleLocator(
h.env.root as AmbientAuth,
LogNone)
h.assert_eq[String]("stable/test/testdata/nested",
_BundleLocator(h.env, bundle("nested")) as String)
locator.locate(bundle("nested")) as String)

// nested has one, but so does nested/deeply
h.assert_eq[String]("stable/test/testdata/nested/deeply",
_BundleLocator(h.env, bundle("nested/deeply")) as String)
locator.locate(bundle("nested/deeply")) as String)

// nested/empty has no bundle.json
h.assert_eq[String]("stable/test/testdata/nested",
_BundleLocator(h.env, bundle("nested/empty")) as String)
locator.locate(bundle("nested/empty")) as String)

// stable itself has no bundle.json, so this ancestor-checking
// from stable/test/testdata/empty yields no bundle.json
h.assert_eq[None](None, _BundleLocator(h.env, bundle("empty")) as None)
h.assert_eq[None](None, locator.locate(bundle("empty")) as None)
78 changes: 50 additions & 28 deletions stable/add.pony
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
use "json"
use options = "options"
use "cli"

primitive Add
fun apply(args: Array[String] box, log: Log): JsonObject ? =>
let kind = args(0)?
let rest = args.slice(1)
primitive AddCmd
fun name(): String => "add"
fun command_spec(): CommandSpec ? =>
CommandSpec.leaf(
name(),
"Adds a new dependency to the local `bundle.json`.",
[ // options
OptionSpec.string(
"tag",
"Specifies a tag from the source repository",
't',
"")
OptionSpec.string(
"subdir",
"Fetch only a subdirectory of the repository",
'd',
"")
],
[ // args
ArgSpec.string(
"type",
"The type of the dependency to add. Possible values: github, gitlab, local-git, local")
ArgSpec.string(
"source",
"The path addressing the dependency to add. For github and gitlab: <ORGANIZATION>/<REPOSITORY>, for local-git and local: a path.")
]
)?

fun apply(cmd: Command, bundle: Bundle, log: Log) ? =>
let kind = cmd.arg("type").string()
let prim =
match kind
| "github" => AddGitHosted
Expand All @@ -18,35 +44,31 @@ primitive Add
end
let info: JsonObject ref = JsonObject
info.data("type") = kind.clone()
prim(rest, info)?

info
prim(cmd, info)
bundle.add_dep(info)?
bundle.fetch()

primitive AddGitHosted
fun apply(args: Array[String] box, info: JsonObject) ? =>
info.data("repo") = args(0)?

let opts = options.Options(args.slice(1))
opts.add("tag", "t", options.StringArgument)
opts.add("subdir", "d", options.StringArgument)
for opt in opts do
match opt
| (let name: String, let value: String) => info.data(name) = value
end
fun apply(cmd: Command, info: JsonObject) =>
info.data("repo") = cmd.arg("source").string()
let git_tag = cmd.option("tag").string()
if git_tag.size() > 0 then
info.data("tag") = git_tag
end
let subdir = cmd.option("subdir").string()
if subdir.size() > 0 then
info.data("subdir") = subdir
end

primitive AddLocalGit
fun apply(args: Array[String] box, info: JsonObject) ? =>
info.data("local-path") = args(0)?
fun apply(cmd: Command, info: JsonObject) =>
info.data("local-path") = cmd.arg("source").string()

let opts = options.Options(args.slice(1))
opts.add("tag", "t", options.StringArgument)
for opt in opts do
match opt
| (let name: String, let value: String) => info.data(name) = value
end
let git_tag = cmd.option("tag").string()
if git_tag.size() > 0 then
info.data("tag") = git_tag
end

primitive AddLocal
fun apply(args: Array[String] box, info: JsonObject) ? =>
info.data("local-path") = args(0)?
fun apply(cmd: Command, info: JsonObject) =>
info.data("local-path") = cmd.arg("source").string()
56 changes: 56 additions & 0 deletions stable/env.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use "cli"
use "files"

primitive EnvCmd
fun name(): String => "env"

fun command_spec(): CommandSpec ?=>
CommandSpec.leaf(
name(),
"Executes the given command within the environment defined by the local `bundle.json`.",
[], // options
[ // args
ArgSpec.string_seq(
"command",
"The command to execute.")
]
)?

fun apply(env: Env, cmd: Command, bundle: Bundle, log: Log) ? =>
let command = cmd.arg("command").string_seq()
if command.size() == 0 then
log("Please provide a command to execute.")
error
end
let ponypath =
try
let ponypath' = recover trn String end
let iter = bundle.paths().values()
let sep = Path.list_sep()(0)?
for path in iter do
ponypath'.append(path)
if iter.has_next() then ponypath'.push(sep) end
end

ponypath'
else
""
end
try
ifdef windows then
var exec: String trn = recover String end
exec.append("cmd /C \"set \"PONYPATH=")
exec.append(ponypath)
exec.append("\" &&")
for arg in command.values() do
exec.append(" ")
exec.append(arg)
end
exec.append("\"")
Shell(consume exec, env.exitcode)?
else
Shell.from_array(
["env"; "PONYPATH=" + ponypath] .> append(command), env.exitcode)?
end
end

14 changes: 14 additions & 0 deletions stable/fetch.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use "cli"

primitive FetchCmd
fun name(): String => "fetch"

fun command_spec(): CommandSpec ? =>
CommandSpec.leaf(
name(),
"Updates the local `.deps` directory with the most recent content from the source repositories."
)?

fun apply(cmd: Command, bundle: Bundle, log: Log) =>
bundle.fetch()

Loading