Please help me write a command line application for changing macOS system appearance (between light and dark mode) called 'appear'. Though it will be simple, I would like the application itself it to be as comprehensive as possible - so a help page and man page with automatic installation on macos should be included - along with anything else needed to make it ready for package managers. Ideally, I would like to publish it to Homebrew, but - as I think it should be based in Ruby - please hold off on that and instead help me publish it as a Ruby gem. ### For light mode To change the system appearance to light mode, the user runs the command `appear light` Our command line application uses this Applescript command to accomplish this: `osascript -e 'tell app "System Events" to tell appearance preferences to set dark mode to false'` ### For dark mode To change the system appearance to light mode, the user runs the command `appear dark` Our command line application uses this Applescript command to accomplish this: `osascript -e 'tell app "System Events" to tell appearance preferences to set dark mode to true'`
Here’s a comprehensive plan to develop the command line application appear
for switching macOS system appearance between light and dark mode. The plan covers writing the script, creating a help page and man page, and packaging the application as a Ruby gem for future distribution via Homebrew or RubyGems.
We'll begin by writing the Ruby script that toggles between light and dark mode using AppleScript.
#!/usr/bin/env ruby
require 'optparse'
class Appear
def self.change_mode(mode)
if mode == 'light'
system("osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to false'")
puts 'System appearance changed to light mode.'
elsif mode == 'dark'
system("osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to true'")
puts 'System appearance changed to dark mode.'
else
puts 'Invalid mode. Use `light` or `dark`.'
end
end
end
# Parse command-line arguments
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: appear [options]"
opts.on('-h', '--help', 'Display help') do
puts opts
exit
end
opts.on('light', 'Change system appearance to light mode') do
Appear.change_mode('light')
end
opts.on('dark', 'Change system appearance to dark mode') do
Appear.change_mode('dark')
end
end.parse!
if ARGV.empty?
puts 'No mode specified. Use `light` or `dark`.'
else
Appear.change_mode(ARGV[0])
end
The OptionParser
in Ruby handles help automatically when the user passes the --help
flag. However, we can improve the help output by adding descriptions and formatting.
opts.banner = "Usage: appear [light|dark] [options]"
opts.separator ""
opts.separator "Specific options:"
opts.separator " light Switch system appearance to light mode"
opts.separator " dark Switch system appearance to dark mode"
opts.separator ""
opts.separator "Common options:"
You can create a simple man page for appear
using the groff format. Here is a basic man page that can be installed on macOS:
Save the following content in a file called appear.1
.
.TH APPEAR 1 "2024" "appear 1.0" "User Commands"
.SH NAME
appear \- change macOS system appearance between light and dark mode
.SH SYNOPSIS
.B appear
[\fIlight|dark\fR]
.SH DESCRIPTION
The \fBappear\fR command changes the macOS system appearance between light and dark mode.
Use the command with one of the following arguments:
.TP
\fBlight\fR
Switch system appearance to light mode.
.TP
\fBdark\fR
Switch system appearance to dark mode.
.SH OPTIONS
.TP
\fB-h\fR, \fB--help\fR
Display this help message.
.SH AUTHOR
David Blue
Create a Rakefile
to handle installation steps. The following Rakefile
installs the appear
binary and the man page:
require 'rake/clean'
CLEAN.include('appear.o')
desc 'Install the appear script'
task :install do
sh 'cp appear /usr/local/bin/appear'
sh 'chmod +x /usr/local/bin/appear'
sh 'mkdir -p /usr/local/share/man/man1'
sh 'cp appear.1 /usr/local/share/man/man1/appear.1'
end
desc 'Uninstall appear'
task :uninstall do
sh 'rm /usr/local/bin/appear'
sh 'rm /usr/local/share/man/man1/appear.1'
end
To package appear
as a Ruby gem, you’ll need to create a gemspec
file that defines the gem’s metadata and dependencies.
Create a file called appear.gemspec
:
Gem::Specification.new do |spec|
spec.name = "appear"
spec.version = "1.0.0"
spec.authors = ["David Blue"]
spec.email = ["your-email@example.com"]
spec.summary = %q{A command line tool to change macOS system appearance between light and dark mode.}
spec.description = %q{A simple command line tool that allows users to switch between light and dark modes on macOS by running a command.}
spec.homepage = "https://example.com/appear"
spec.files = ["lib/appear.rb", "bin/appear", "appear.gemspec", "Rakefile", "LICENSE.txt", "README.md"]
spec.bindir = "bin"
spec.executables = ["appear"]
spec.required_ruby_version = '>= 2.3.0'
spec.metadata["allowed_push_host"] = "https://rubygems.org"
end
Ensure you have the necessary files like LICENSE.txt
and README.md
in the same directory as your gemspec.
Once the gemspec file is ready, build the gem:
gem build appear.gemspec
This will create a .gem
file. You can now push it to RubyGems:
gem push appear-1.0.0.gem
When you're ready to publish it on Homebrew, you can create a formula and submit it to the Homebrew repository. However, focusing on the Ruby gem allows you to package it for any Ruby-based environment first.
You now have a full-fledged macOS command-line application that:
Let me know if you need further assistance with any step!
Before I do anything, I think I'm going to go ahead and initialize a repository for all of this. Can you show me how these files should be organized in said repository?
Here’s how you should organize your repository for the appear
project. I'll structure it in a way that makes it easy to maintain and distribute as a Ruby gem:
appear/
├── bin/
│ └── appear # The main executable script
├── lib/
│ └── appear.rb # Ruby file with the core logic
├── man/
│ └── appear.1 # The man page
├── spec/ # (Optional) Tests, if you plan to add any
├── Rakefile # Rake tasks for installation/uninstallation
├── appear.gemspec # Gem specification file
├── LICENSE.txt # License information
├── README.md # Project documentation
└── .gitignore # Git ignore file for unnecessary files
bin/appear
:
This is the main executable for your command-line application. It will be a small Ruby script that invokes the code in lib/appear.rb
.
lib/appear.rb
:
The core logic of your application resides here. You want to separate your logic into the lib
folder to keep the binary (bin/appear
) lightweight and to follow common Ruby practices.
man/appear.1
:
The man page is stored in its own directory. This can be installed in /usr/local/share/man/man1
on the user’s system as part of your Rakefile or installation process.
spec/
:
This is optional, but if you want to write tests for your gem, they would go here. You can use RSpec or Minitest if you decide to implement unit tests later.
Rakefile
:
Handles installation and uninstallation tasks for the script and the man page.
appear.gemspec
:
The gemspec file contains metadata and other details for packaging and publishing the Ruby gem.
LICENSE.txt
:
Add a suitable license for your project here, such as MIT, GPL, etc.
README.md
:
Documentation about the project, including installation instructions, usage examples, and any other details.
.gitignore
:
Specify files and directories that Git should ignore, such as:
*.gem
*.log
.DS_Store
.bundle/
bin/appear
:
#!/usr/bin/env ruby
require_relative '../lib/appear'
Appear.run(ARGV)
lib/appear.rb
:
require 'optparse'
class Appear
def self.run(args)
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: appear [light|dark]"
opts.on('-h', '--help', 'Display this help') do
puts opts
exit
end
end.parse!(args)
mode = args[0]
case mode
when 'light'
system("osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to false'")
puts 'System appearance changed to light mode.'
when 'dark'
system("osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to true'")
puts 'System appearance changed to dark mode.'
else
puts 'Invalid mode. Use `light` or `dark`.'
end
end
end
Once you have these files in place, initialize a git repository:
git init
git add .
git commit -m "Initial commit"
You can also use Bundler to manage gem dependencies and versioning:
bundle init
This creates a Gemfile
in the project, where you can add any necessary gems.
Once the repository is initialized and files are in place, you’re ready to build, test, and later push your Ruby gem.
Let me know if you'd like to add anything else!
Would you go ahead and provide me with the exact contents of each file in the tree you provided above?
Certainly! Here’s the exact content for each file that you can use to initialize your appear
project.
appear/
├── bin/
│ └── appear
├── lib/
│ └── appear.rb
├── man/
│ └── appear.1
├── spec/
├── Rakefile
├── appear.gemspec
├── LICENSE.txt
├── README.md
└── .gitignore
bin/appear
#!/usr/bin/env ruby
require_relative '../lib/appear'
# Run the command with arguments
Appear.run(ARGV)
This file calls the main logic defined in lib/appear.rb
. It simply passes the command-line arguments to the Appear
class.
lib/appear.rb
require 'optparse'
class Appear
def self.run(args)
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: appear [light|dark]"
opts.on('-h', '--help', 'Display this help') do
puts opts
exit
end
end.parse!(args)
mode = args[0]
case mode
when 'light'
system("osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to false'")
puts 'System appearance changed to light mode.'
when 'dark'
system("osascript -e 'tell app \"System Events\" to tell appearance preferences to set dark mode to true'")
puts 'System appearance changed to dark mode.'
else
puts 'Invalid mode. Use `light` or `dark`.'
end
end
end
This file contains the main logic for the appear
application, parsing the mode (light
or dark
) and running the corresponding AppleScript command.
man/appear.1
.TH APPEAR 1 "2024" "appear 1.0" "User Commands"
.SH NAME
appear \- change macOS system appearance between light and dark mode
.SH SYNOPSIS
.B appear
[\fIlight|dark\fR]
.SH DESCRIPTION
The \fBappear\fR command changes the macOS system appearance between light and dark mode.
Use the command with one of the following arguments:
.TP
\fBlight\fR
Switch system appearance to light mode.
.TP
\fBdark\fR
Switch system appearance to dark mode.
.SH OPTIONS
.TP
\fB-h\fR, \fB--help\fR
Display this help message.
.SH AUTHOR
David Blue
This is the man page for the appear
application. It explains the usage, description, options, and author.
spec/
(Optional)If you plan to add tests in the future, you can use this directory to store them. You can add an empty file here for now:
touch spec/.keep
This is an empty placeholder to commit the directory structure.
Rakefile
require 'rake/clean'
CLEAN.include('appear.o')
desc 'Install the appear script and man page'
task :install do
sh 'cp bin/appear /usr/local/bin/appear'
sh 'chmod +x /usr/local/bin/appear'
sh 'mkdir -p /usr/local/share/man/man1'
sh 'cp man/appear.1 /usr/local/share/man/man1/appear.1'
end
desc 'Uninstall appear'
task :uninstall do
sh 'rm /usr/local/bin/appear'
sh 'rm /usr/local/share/man/man1/appear.1'
end
This Rakefile
includes tasks for installing and uninstalling the script and man page.
appear.gemspec
Gem::Specification.new do |spec|
spec.name = "appear"
spec.version = "1.0.0"
spec.authors = ["David Blue"]
spec.email = ["your-email@example.com"]
spec.summary = %q{A command line tool to change macOS system appearance between light and dark mode.}
spec.description = %q{A simple command line tool that allows users to switch between light and dark modes on macOS by running a command.}
spec.homepage = "https://example.com/appear"
spec.files = ["lib/appear.rb", "bin/appear", "man/appear.1", "Rakefile", "LICENSE.txt", "README.md"]
spec.bindir = "bin"
spec.executables = ["appear"]
spec.required_ruby_version = '>= 2.3.0'
spec.metadata["allowed_push_host"] = "https://rubygems.org"
end
This gemspec
file defines the gem's metadata and the files that should be included when packaging the gem.
LICENSE.txt
MIT License
Copyright (c) 2024 David Blue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This is the MIT License for your project. Replace it with a different license if needed.
README.md
# Appear
`appear` is a simple command line tool that allows you to change the macOS system appearance between light and dark modes.
## Installation
To install the `appear` script and man page:
```bash
rake install
To switch to light mode:
appear light
To switch to dark mode:
appear dark
To uninstall the script and man page:
rake uninstall
This project is licensed under the MIT License.
This `README.md` file provides a summary of the project, how to install, use, and uninstall it.
---
### 9. `.gitignore`
```txt
*.gem
*.log
.DS_Store
.bundle/
This .gitignore
file excludes unnecessary files like .gem
builds, logs, macOS .DS_Store
files, and the Bundler .bundle
directory.
With these files in place and structured as outlined, you’re ready to initialize the project and begin working with your command-line tool. You can follow these steps to set it up:
Initialize the repository:
git init
Add all files and commit:
git add .
git commit -m "Initial commit"
Build and install the gem when ready:
rake install
Let me know if you'd like to modify or add anything further!
Having followed said steps, I'm receiving the following on my mac when I just tried to run both `appear dark` and `appear light`: /usr/local/bin/appear:2:in `require_relative': cannot load such file -- /usr/local/lib/appear (LoadError) from /usr/local/bin/appear:2:in `<main>'
The error message you're receiving suggests that the require_relative
in your bin/appear
script is looking for the appear.rb
file in the wrong location after the install process. Specifically, it's looking for lib/appear.rb
in /usr/local/lib/
instead of in your project's lib/
directory.
To resolve this, you need to adjust the require_relative
path in the bin/appear
file so that it properly points to the lib
directory during execution.
bin/appear
script to handle the correct lib
path:
The bin/appear
script needs to dynamically figure out where the lib/appear.rb
file is located relative to its own location. Here's how you can update it:bin/appear
:#!/usr/bin/env ruby
# Determine the absolute path of the lib/appear.rb file
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
require 'appear'
# Run the command with arguments
Appear.run(ARGV)
File.expand_path('../../lib', __FILE__)
calculates the absolute path of the lib
folder relative to where the bin/appear
script is located.$LOAD_PATH.unshift(...)
adds the lib
directory to the Ruby load path, allowing require 'appear'
to find lib/appear.rb
.After making this change, you'll need to reinstall the appear
script:
rake uninstall # Uninstall the current version
rake install # Reinstall the script
Now, try running appear light
or appear dark
again, and the error should be resolved.
Let me know how it goes!
Why don't we go ahead and publish this as a ruby gem? It seems like installing via gem might fix some of these errors.
Publishing the appear
project as a Ruby gem is a great idea! It will make installation and usage more reliable, as RubyGems will handle the dependencies, installation paths, and executable generation for you. Let’s walk through the steps to publish it as a Ruby gem.
appear
as a Ruby Gemappear.gemspec
is CorrectThe gemspec
file contains all the metadata about your gem, including the files to package and publish.
Here’s the appear.gemspec
file again, with a few small improvements:
Gem::Specification.new do |spec|
spec.name = "appear"
spec.version = "1.0.0"
spec.authors = ["David Blue"]
spec.email = ["your-email@example.com"]
spec.summary = %q{A command line tool to change macOS system appearance between light and dark mode.}
spec.description = %q{A simple command line tool that allows users to switch between light and dark modes on macOS by running a command.}
spec.homepage = "https://github.com/username/appear"
spec.license = "MIT"
spec.files = Dir["lib/**/*.rb"] + ["bin/appear", "man/appear.1", "Rakefile", "LICENSE.txt", "README.md"]
spec.bindir = "bin"
spec.executables = ["appear"]
spec.require_paths = ["lib"]
spec.required_ruby_version = '>= 2.3.0'
spec.metadata["allowed_push_host"] = "https://rubygems.org"
end
Make sure to replace "your-email@example.com"
and "https://github.com/username/appear"
with your actual email and GitHub repository URL.
You can use Bundler to build the gem. First, ensure your environment is properly set up:
bundle install
Now, build the gem:
gem build appear.gemspec
This command will generate a .gem
file, such as appear-1.0.0.gem
, in the current directory.
If you don’t have a RubyGems.org account yet, create one by going to RubyGems.org.
First, you’ll need to authenticate your local system with RubyGems. Run the following command and enter your RubyGems credentials when prompted:
gem signin
Once signed in, push the gem:
gem push appear-1.0.0.gem
This will upload your gem to RubyGems.org and make it available for everyone to install.
After publishing the gem, you can test it locally to make sure everything works as expected:
gem install appear
Now, the appear
command should work properly without needing to manage installation paths manually.
Install the Gem:
gem install appear
Use the Commands:
appear light # Switches macOS to light mode
appear dark # Switches macOS to dark mode
Uninstall:
If you ever need to uninstall the gem, use:
gem uninstall appear
GitHub Repository: Consider creating a GitHub repository for your project (if you haven’t already). This will allow people to contribute, file issues, and review your code. Include the repository URL in the gemspec
file's homepage
field.
Continuous Integration (CI): You can set up CI tools like GitHub Actions or Travis CI to automatically run tests or build the gem when you push changes to GitHub.
Versioning: For future updates, remember to increment the version number in appear.gemspec
(e.g., "1.0.1"
).
Let me know if you run into any issues, and I can help you troubleshoot further!
I got a warning after building noting that bin/appear is not executable
The warning you received is related to file permissions for the bin/appear
script. Ruby expects the scripts in the bin/
directory to be executable, but in this case, the file likely doesn't have the correct permissions.
bin/appear
To resolve this, you need to make the bin/appear
file executable by setting the correct file permissions. Here’s how to do that:
Set the Executable Permission:
Run the following command in your project directory:
chmod +x bin/appear
This will set the executable flag on the bin/appear
script, allowing it to be run as an executable.
Rebuild the Gem:
After making the script executable, you should rebuild the gem:
gem build appear.gemspec
Check if the Warning Is Gone:
Now, the warning about the script not being executable should disappear. You can test this by installing the gem locally or pushing it to RubyGems.
You can confirm that the file is executable by running the following command:
ls -l bin/appear
The output should look something like this:
-rwxr-xr-x 1 user group 1234 Sep 17 15:00 bin/appear
The x
indicates that the file is executable.
If the permissions are now correct, you can follow the steps to push the updated gem to RubyGems:
gem push appear-1.0.0.gem
Let me know how it goes!