diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..bb98fe1 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,44 @@ +# mas-cli Code of Conduct + +mas-cli strongly values contributors from anywhere, regardless of gender, sexual orientation, disability, physical appearance, body size, race, or religion. As a result, the mas-cli team has agreed to and enforces this code of conduct in order to provide a harassment-free experience for everyone who participates in the development of mas-cli. + +### Summary + +Harassment in code and discussion or violation of physical boundaries is completely unacceptable anywhere in mas-cli’s codebases, issue trackers, Slack, Campfire, mailing lists, meetups, and other events. Violators will be warned and then blocked or banned by the core team at or before the 3rd violation. + +### In detail + +Harassment includes offensive verbal comments related to gender, sexual orientation, disability, physical appearance, body size, race, ethnicity, religion, sexual images, deliberate intimidation, stalking, sustained disruption, and unwelcome sexual attention. + +Individuals asked to stop any harassing behavior are expected to comply immediately. + +Maintainers, including the core team, are also subject to the anti-harassment policy. + +If anyone engages in harassing behavior, including maintainers, we may take appropriate action, up to and including warning the offender, deletion of comments, removal from the project’s codebase and communication systems, and escalation to GitHub support. + +If you are being harassed, notice that someone else is being harassed, or have any other concerns, please contact a member of [@mas-cli/admins](https://github.com/orgs/mas-cli/teams/admins) immediately. + +We expect everyone to follow these rules anywhere in the mas-cli project’s codebases, issue trackers, IRC channel, group chat, and mailing lists. + +This code of conduct applies both within project spaces and in public spaces when an individual is actively representing the project or its community. Due to their strong association with the project, core contributors are always seen as actively representing it. + +Finally, don't forget that it is human to make mistakes! We all do. Let’s work together to help each other, resolve issues, and learn from the mistakes that we will all inevitably make from time to time. + +### Thanks + +Thanks to the [CocoaPods Code of Contact](https://github.com/CocoaPods/CocoaPods/blob/master/CODE_OF_CONDUCT.md), +[Bundler Code of Conduct](https://github.com/bundler/bundler/blob/e3ce14f5ecd9b729338435c8689553ef209d83aa/CODE_OF_CONDUCT.md), +[JSConf Code of Conduct](http://jsconf.com/codeofconduct.html), +[Fedora Code of Conduct](http://fedoraproject.org/code-of-conduct), and +[Contributor Covenant](http://contributor-covenant.org), version 1.2.0 for inspiration and ideas. + +### License + +

+ To the extent possible under law, The mas-cli Team has waived all copyright and related or neighboring rights to the mas-cli Code of Conduct. This work is published from the United States. +
+
+ + CC0 + +

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..b35dd41 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contributing + +We love pull requests from everyone. By participating in this project, you agree to abide by our [code of conduct](CODE_OF_CONDUCT.md). + +## Getting Started + +- Make sure you have a [GitHub account](https://github.com/join). +- [Open an issue](https://github.com/mas-cli/mas/issues/new) to simply ask a question or request a new feature. +- Search for similar issues with the [ERROR MESSAGE](https://github.com/mas-cli/mas/issues?utf8=%E2%9C%93&q=is%3Aopen+ERROR+MESSAGE) you are exeriencing. +- If one doesn't exist, [open a new issue](https://github.com/mas-cli/mas/issues/new) + - Clearly describe the issue including steps to reproduce when it is a bug. + - Include the earliest version of `mas` that you know has the issue. + - Include your macOS version. + +## Making Changes + +- [Fork the repository](https://github.com/mas-cli/mas#fork-destination-box) on GitHub. +- Cone your fork + `git clone git@github.com:your-username/mas.git` +- Create a topic branch from where you want to base your work. + - This is usually the `master` branch. + - To quickly create a topic branch based on `master`, run + `git checkout -b awesome-feature master` + - Please avoid working [directly on the master branch](https://softwareengineering.stackexchange.com/questions/223400/when-should-i-stop-committing-to-master-on-new-projects). + - Make commits of logical units. +- Check for unnecessary whitespace with `git diff --check` before committing. + - Note that [two trailing spaces](https://gist.github.com/shaunlebron/746476e6e7a4d698b373) is intentional + in markdown documents to create a line break like `
`, so these should _not_ be removed. +- Push your topic branch to your fork and [submit a pull request](https://github.com/mas-cli/mas/compare/master...your-username:topic-branch). + +Some things that will increase the chance that your pull request is accepted: + +- Write tests. (Tests target is still [in progress](https://github.com/mas-cli/mas/issues/123)) + - If you need help with tests, feel free to open a PR in the meantime and just ask for some help. + - Add "[WIP]" to the title of your PR to indicate that it's not ready to be merged. +- Follow our [style guide](docs/style.md). +- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). + - Including [appropriate emoji](https://gitmoji.carloscuesta.me/) in the first line of commit messages is fun :wink:. + +## Becoming a Contributor + +Once you have had a few PRs accepted, if you are interested in joining the +[@mas-cli/contributors](https://github.com/orgs/mas-cli/teams/contributors) +team to help with the issue/PR backlog and even release new versions of this project, +[open a new issue](https://github.com/mas-cli/mas/issues/new) +titled "Add Contributor: @YourGitHubUsername", with a brief message asking to join the team. + +This project was created by [@argon](https://github.com/argon), who is unable to continue contributing +to this project, but must remain an owner. By becoming a contributor, you agree to the terms in [#47](https://github.com/mas-cli/mas/issues/47). + +## Branching and Releases + +- This project follows [trunk-based development](https://trunkbaseddevelopment.com/), where `master` is our trunk. +- Release commits will be tagged in the format: `v1.2.3`. +- Once releases are tagged, high-level release notes are published on the [releases](https://github.com/mas-cli/mas/releases) page. + +See GitHub's post on creating [Contributing Guidelines](https://github.com/blog/1184-contributing-guidelines) +if you would like to set up something like this for your projects. diff --git a/README.md b/README.md index 99a6bbb..440688a 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ Build output can be found in the `build/` directory within the project. ## License +mas-cli was created by [@argon](https://github.com/argon). Code is under the [MIT license](LICENSE). [mas-cli]: https://github.com/mas-cli/mas diff --git a/docs/sample.swift b/docs/sample.swift new file mode 100644 index 0000000..0b398ec --- /dev/null +++ b/docs/sample.swift @@ -0,0 +1,102 @@ +// Don't include generated header comments + +// MARK: Types and naming + +// Types begin with a capital letter +struct User { + let name: String + + // if the first letter of an acronym is lowercase, the entire thing should + // be lowercase + let json: Any + + // if the first letter of an acronym is uppercase, the entire thing should + // be uppercase + static func decode(from json: JSON) -> User { + return User(json: json) + } +} + +// Use () for void arguments and Void for void return types +let f: () -> Void = {} + +// When using classes, default to marking them as final +final class MyViewController: UIViewController { + // Prefer strong IBOutlet references + @IBOutlet var button: UIButton! +} + +// Use typealias when closures are referenced in multiple places +typealias CoolClosure = (Int) -> Bool + +// Use aliased parameter names when function parameters are ambiguous +func yTown(some: Int, withCallback callback: CoolClosure) -> Bool { + return CoolClosure(some) +} + +// It's OK to use $ variable references if the closure is very short and +// readability is maintained +let cool = yTown(5) { $0 == 6 } + +// Use full variable names when closures are more complex +let cool = yTown(5) { foo in + if foo > 5 && foo < 0 { + return true + } else { + return false + } +} + +// Strongify weak references in async closures +APIClient.getAwesomeness { [weak self] result in + guard let `self` = self else { return } + self.stopLoadingSpinner() + self.show(result) +} + +// If the API you are using has implicit unwrapping you should still use if-let +func someUnauditedAPI(thing: String!) { + if let string = thing { + print(string) + } +} + +// When the type is known you can let the compiler infer +let response: Response = .success(NSData()) + +func doSomeWork() -> Response { + let data = ... + return .success(data) +} + +switch response { +case let .success(data): + print("The response returned successfully \(data)") + +case let .failure(error): + print("An error occured: \(error)") +} + +// MARK: Organization + +// Group methods into specific extensions for each level of access control +private extension MyClass { + func doSomethingPrivate() { } +} + +// MARK: Breaking up long lines + +// One expression to evaluate and short or no return +guard let singleTest = somethingFailable() else { return } +guard statementThatShouldBeTrue else { return } + +// If there is one long expression to guard or multiple expressions +// move else to next line +guard let oneItem = somethingFailable(), + let secondItem = somethingFailable2() + else { return } + +// If the return in else is long, move to next line +guard let something = somethingFailable() else { + return someFunctionThatDoesSomethingInManyWordsOrLines() +} diff --git a/docs/style.md b/docs/style.md new file mode 100644 index 0000000..c941617 --- /dev/null +++ b/docs/style.md @@ -0,0 +1,33 @@ +# All Files + +- Remove unnecessary whitespace from the end of lines. + - Use `git diff --check` to look for these before committing. + - Note that [two trailing spaces](https://gist.github.com/shaunlebron/746476e6e7a4d698b373) + is intentional in markdown documents to create a line break like `
`, so these should _not_ be removed. +- End each file with a [newline character](https://unix.stackexchange.com/questions/18743/whats-the-point-in-adding-a-new-line-to-the-end-of-a-file#18789). + +# Swift + +[Sample](sample.swift) + +- Avoid [force unwrapping optionals](https://blog.timac.org/2017/0628-swift-banning-force-unwrapping-optionals/) with `!` in production code + - Production code is what gets shipped with the app. Basically, everything under the [`mas-cli/`](https://github.com/mas-cli/mas/tree/master/mas-cli) folder. + - However, force unwrapping is **encouraged** in tests for less code and tests _should_ break when any expected conditions aren't met. +- Prefer `struct`s over `class`es wherever possible +- Default to marking classes as `final` +- Prefer protocol conformance to class inheritance +- Break long lines after 120 characters +- Use 4 spaces for indentation +- Use `let` whenever possible to make immutable variables +- Name all parameters in functions and enum cases +- Use trailing closures +- Let the compiler infer the type whenever possible +- Group computed properties below stored properties +- Use a blank line above and below computed properties +- Group methods into specific extensions for each level of access control +- When capitalizing acronyms or initialisms, follow the capitalization of the first letter. +- When using `Void` in function signatures, prefer `()` for arguments and `Void` for return types. +- Prefer strong `IBOutlet` references. +- Avoid evaluating a weak reference multiple times in the same scope. Strongify first, then use the strong reference. +- Prefer to name `IBAction` and target/action methods using a verb describing the action it will trigger, instead + of the user action (e.g., `edit:` instead of `editTapped:`)