Skip to content

Commit

Permalink
Merge pull request #118 from jacebrowning/fix-version
Browse files Browse the repository at this point in the history
Fix version tracking
  • Loading branch information
jacebrowning committed Jul 20, 2023
2 parents 3a43621 + ca07a22 commit ef62039
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 71 deletions.
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ omit =
[report]

exclude_lines =
__main__
except PackageNotFoundError
pragma: no cover
raise NotImplementedError
except DistributionNotFound
TYPE_CHECKING
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Release Notes

## 4.0 (alpha)
## 4.0 (2023-07-20)

- Dropped support for Python 3.8 and 3.9.
- Improved computer identification using serial numbers.

## 3.1.1 (2023-07-15)

Expand Down
13 changes: 7 additions & 6 deletions mine/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
import sys
import time

import datafiles
import log
from datafiles import frozen
from datafiles.model import create_model
from startfile import startfile

from . import CLI, DESCRIPTION, VERSION, common, services
from .manager import BaseManager, get_manager
from .models import Application, Data, Versions

daemon = Application(CLI, versions=Versions(mac="mine", windows="mine", linux="mine"))
daemon = Application("Mine", versions=Versions(mac=CLI, windows=CLI, linux=CLI))


def main(args=None):
Expand Down Expand Up @@ -176,7 +176,8 @@ def run(
status = data.status

log.info("Identifying current computer...")
computer = config.get_current_computer()
with datafiles.frozen(data):
computer = config.get_current_computer()
log.info("Current computer: %s", computer)

if edit:
Expand All @@ -198,7 +199,7 @@ def run(

while True:
services.delete_conflicts(root, config_only=True, force=True)
with frozen(data):
with datafiles.frozen(data):
data.launch_queued_applications(config, status, computer, manager)
data.update_status(config, status, computer, manager)

Expand All @@ -221,7 +222,7 @@ def run(
time.sleep(short_delay)

if cleanup:
with frozen(data):
with datafiles.frozen(data):
data.prune_status(config, status)

if delay is None:
Expand All @@ -246,5 +247,5 @@ def _restart_daemon(manager: BaseManager):
return True


if __name__ == "__main__": # pragma: no cover (manual test)
if __name__ == "__main__":
main()
41 changes: 18 additions & 23 deletions mine/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,25 @@
import log
import psutil

# TODO: delete this after implementing `BaseManager`
# https://github.com/jacebrowning/mine/issues/8
# https://github.com/jacebrowning/mine/issues/9


# TODO: enable coverage when a Linux test is implemented
def log_running(func): # pragma: no cover (manual)
def log_running(func):
@functools.wraps(func)
def wrapped(self, application):
log.debug("Determining if %s is running...", application)
log.debug(f"Determining if {application} is running...")
running = func(self, application)
if running is None:
status = "Application untracked"
status = "Application is untracked"
elif running:
status = "Application running on current machine"
status = "Application running on this computer"
else:
status = "Application not running on current machine"
log.info("%s: %s", status, application)
status = "Application not running on this computer"
log.info(f"{status}: {application}")
return running

return wrapped


# TODO: enable coverage when a Linux test is implemented
def log_starting(func): # pragma: no cover (manual)
def log_starting(func):
@functools.wraps(func)
def wrapped(self, application):
log.info("Starting %s...", application)
Expand All @@ -45,8 +39,7 @@ def wrapped(self, application):
return wrapped


# TODO: enable coverage when a Linux test is implemented
def log_stopping(func): # pragma: no cover (manual)
def log_stopping(func):
@functools.wraps(func)
def wrapped(self, application):
log.info("Stopping %s...", application)
Expand Down Expand Up @@ -145,17 +138,19 @@ class MacManager(BaseManager): # pragma: no cover (manual)
"""Application manager for macOS."""

NAME = "Darwin"
FRIENDLY = "Mac"
FRIENDLY = "macOS"

IGNORED_APPLICATION_NAMES = [
"iTunesHelper.app",
"slack helper.app",
"com.apple.mail.spotlightindexextension",
"com.apple.notes.spotlightindexextension",
"com.apple.podcasts.spotlightindexextension",
"garcon.appex",
"musiccacheextension",
"podcastswidget",
"iTunesHelper.app",
"mailcachedelete",
"com.apple.mail.spotlightindexextension",
"mailshortcutsextension",
"musiccacheextension",
"podcastswidget",
"slack helper.app",
]

@log_running
Expand Down Expand Up @@ -222,12 +217,12 @@ def stop(self, application):

def get_manager(name=None) -> BaseManager:
"""Return an application manager for the current operating system."""
log.info("Detecting the current system...")
log.info("Detecting the operating system...")
name = name or platform.system()
manager = { # type: ignore
WindowsManager.NAME: WindowsManager,
MacManager.NAME: MacManager,
LinuxManager.NAME: LinuxManager,
}[name]()
log.info("Current system: %s", manager)
log.info("Identified operating system: %s", manager)
return manager
9 changes: 6 additions & 3 deletions mine/models/computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,24 @@
import uuid
from dataclasses import dataclass

from .. import __version__


@dataclass
class Computer:
"""A dictionary of identifying computer information."""

name: str
hostname: str = ""
address: str = ""
serial: str = ""
mine: str = ""
address: str = ""
hostname: str = ""
mine: str = "v" + __version__

def __post_init__(self):
self.address = self.address or self.get_address()
self.hostname = self.hostname or self.get_hostname()
self.serial = self.serial or self.get_serial()
assert ":" in self.address, f"Invalid address: {self.address!r}"

def __str__(self):
return self.name
Expand Down
25 changes: 12 additions & 13 deletions mine/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import log

from .. import __version__
from .application import Application
from .computer import Computer

Expand Down Expand Up @@ -48,24 +47,24 @@ def match_computer(self, partial: str):

def get_current_computer(self, default_name: str = ""):
"""Get the current computer's information."""
this = Computer("?", mine=__version__)
this = Computer("?")
log.debug(f"Comparing information with {this!r}...")

# Search for a matching hostname
# Search for a matching serial
for other in self.computers:
if this.serial and this.serial == other.serial:
log.debug(f"Matched via serial: {other!r}")
other.hostname = this.hostname
other.mine = this.mine
return other

# Else, search for a matching hostname
for other in self.computers:
if this.hostname == other.hostname:
log.debug(f"Matched via hostname: {other!r}")
other.address = this.address
other.serial = other.serial or this.serial
other.mine = __version__
return other

# Else, search for a matching serial
for other in self.computers:
if this.serial and this.serial == other.serial:
log.debug(f"Matched via serial: {other!r}")
other.hostname = this.hostname
other.mine = __version__
other.mine = this.mine
return other

# Else, search for a matching address
Expand All @@ -74,7 +73,7 @@ def get_current_computer(self, default_name: str = ""):
log.debug(f"Matched via address: {other!r}")
other.hostname = this.hostname
other.serial = other.serial or this.serial
other.mine = __version__
other.mine = this.mine
return other

# Else, this is a new computer
Expand Down
2 changes: 1 addition & 1 deletion mine/models/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def get_latest(self, application):
application,
", ".join(str(s) for s in states),
)
# TODO: consider returning the computer instance?
# TODO: consider returning the computer instance
return states[0].computer

log.debug(f"{application} marked as started on: nothing")
Expand Down
9 changes: 5 additions & 4 deletions mine/tests/test_models_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ def test_init(self):

def test_init_defaults(self):
"""Verify the correct computer information can be overridden."""
computer = Computer("name", "hostname", "address")
computer = Computer("name", "serial", "address:", "hostname")
assert "name" == computer.name
assert "address" == computer.address
assert "address:" == computer.address
assert "hostname" == computer.hostname
assert "serial" == computer.serial

def test_eq(self):
"""Verify computers and strings can be equated."""
Expand All @@ -38,7 +39,7 @@ def test_lt(self):

def test_get_match_none(self):
"""Verify a computer is added when missing."""
other = Computer("name", "hostname", "address", "serial")
other = Computer("name", "serial", "address:", "hostname")
config = ProgramConfig(computers=[other])
this = config.get_current_computer()
assert "sample" == this.name
Expand All @@ -48,7 +49,7 @@ def test_get_match_none(self):

def test_get_match_all(self):
"""Verify a computer can be matched exactly."""
other = Computer("all", "Sample.local", "00:00:00:00:00:00")
other = Computer("all", "serial", "00:00:00:00:00:00", "Sample.local")
config = ProgramConfig(computers=[other])
this = config.get_current_computer()
assert "all" == this.name
Expand Down
14 changes: 7 additions & 7 deletions mine/tests/test_models_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ class TestProgramConfig:
config = ProgramConfig(
applications=[Application("iTunes"), Application("HipChat")],
computers=[
Computer("abc", "abc.local", "1"),
Computer("def", "def.local", "2"),
Computer("My iMac", "imac.local", "3"),
Computer("My Mac", "mac.local", "4"),
Computer("abc", "s1", "1:1", "abc.local"),
Computer("def", "s2", "2:2", "def.local"),
Computer("My iMac", "s3", "3:3", "imac.local"),
Computer("My Mac", "s4", "4:4", "mac.local"),
],
)

Expand Down Expand Up @@ -66,18 +66,18 @@ def test_generate_name(self):
def test_generate_name_duplicates(self):
"""Verify a computer name is generated correctly with duplicates."""
config = ProgramConfig(computers=[Computer("jaces-imac")])
computer = Computer("", hostname="Jaces-iMac.local")
computer = Computer("", "s", hostname="Jaces-iMac.local")
name = config.generate_computer_name(computer)
assert "jaces-imac-2" == name

def test_get_current_computer_by_matching_address(self):
config = ProgramConfig(
computers=[Computer("abc", "foobar", "00:00:00:00:00:00")]
computers=[Computer("abc", "s", "00:00:00:00:00:00", "foobar")]
)
computer = config.get_current_computer()
assert "abc" == computer.name

def test_get_current_computer_by_matching_hostname(self):
config = ProgramConfig(computers=[Computer("abc", "Sample.local", "foobar")])
config = ProgramConfig(computers=[Computer("abc", "s", "a:", "Sample.local")])
computer = config.get_current_computer()
assert "abc" == computer.name
3 changes: 1 addition & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]

name = "mine"
version = "4.0"
version = "4.0.1"
description = "Share application state across computers using Dropbox."

license = "MIT"
Expand Down
12 changes: 6 additions & 6 deletions tests/files/mine-out.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
config:
computers:
- name: macbook
hostname: Jaces-MacBook
address: AA:BB:CC:DD:EE:FF
serial: abc123
mine: ''
address: AA:BB:CC:DD:EE:FF
hostname: Jaces-MacBook
mine: v4.0.1
- name: macbook-pro
hostname: Jaces-MacBook-2
address: 11:22:33:44:55:66
serial: def456
mine: ''
address: 11:22:33:44:55:66
hostname: Jaces-MacBook-2
mine: v4.0.1
applications:
- name: itunes
properties:
Expand Down
6 changes: 3 additions & 3 deletions tests/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_data(self):
iphoto = Application("iphoto")
iphoto.versions.mac = "iPhoto"

mac = Computer("macbook", "Other.local")
mac = Computer("macbook", "serial", "address:", "Other.local")
mac2 = Computer("macbook-pro")

configuration = ProgramConfig()
Expand Down Expand Up @@ -77,8 +77,8 @@ def test_data_out(self):
iphoto = Application("iphoto")
iphoto.versions.mac = "iPhoto"

mac = Computer("macbook", "Jaces-MacBook", "AA:BB:CC:DD:EE:FF", "abc123")
mac2 = Computer("macbook-pro", "Jaces-MacBook-2", "11:22:33:44:55:66", "def456")
mac = Computer("macbook", "abc123", "AA:BB:CC:DD:EE:FF", "Jaces-MacBook")
mac2 = Computer("macbook-pro", "def456", "11:22:33:44:55:66", "Jaces-MacBook-2")

configuration = ProgramConfig()
configuration.applications = [itunes, iphoto]
Expand Down

0 comments on commit ef62039

Please sign in to comment.