Class: Autoproj::CLI::Watch

Inherits:
InspectionTool show all
Defined in:
lib/autoproj/cli/watch.rb

Instance Attribute Summary collapse

Attributes inherited from Base

#ws

Instance Method Summary collapse

Methods inherited from InspectionTool

#finalize_setup, #initialize_and_load

Methods inherited from Base

#export_env_sh, #normalize_command_line_package_selection, #notify_env_sh_updated, #resolve_selection, #resolve_user_selection, validate_options, #validate_user_selection

Methods included from Ops::Tools

#common_options, #create_autobuild_package, #load_autoprojrc, #load_main_initrb

Constructor Details

#initialize(*args) ⇒ Watch

Returns a new instance of Watch.



9
10
11
12
# File 'lib/autoproj/cli/watch.rb', line 9

def initialize(*args)
    super(*args)
    @show_events = false
end

Instance Attribute Details

#notifierObject (readonly)

Returns the value of attribute notifier.



7
8
9
# File 'lib/autoproj/cli/watch.rb', line 7

def notifier
  @notifier
end

Instance Method Details

#assert_watchers_availableObject



108
109
110
111
112
113
# File 'lib/autoproj/cli/watch.rb', line 108

def assert_watchers_available
    return if RbConfig::CONFIG["target_os"] =~ /linux/

    puts "error: Workspace watching not available on this platform"
    exit 1
end

#callbackObject



51
52
53
# File 'lib/autoproj/cli/watch.rb', line 51

def callback
    Thread.new { notifier.stop }
end

#cleanupObject



122
123
124
125
# File 'lib/autoproj/cli/watch.rb', line 122

def cleanup
    Ops.watch_cleanup_marker(@marker_io) if @marker_io
    cleanup_notifier if @notifier
end

#cleanup_notifierObject



103
104
105
106
# File 'lib/autoproj/cli/watch.rb', line 103

def cleanup_notifier
    notifier.watchers.dup.each_value(&:close)
    notifier.close
end

#create_dir_watcher(dir, included_paths: [], excluded_paths: [], inotify_flags: []) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/autoproj/cli/watch.rb', line 62

def create_dir_watcher(dir, included_paths: [], excluded_paths: [], inotify_flags: [])
    strip_dir_range = ((dir.size + 1)..-1)
    notifier.watch(dir, :move, :create, :delete, :modify, :dont_follow, *inotify_flags) do |e|
        file_name = e.absolute_name[strip_dir_range]
        included = included_paths.empty? ||
                   included_paths.any? { |rx| rx === file_name }
        included = !excluded_paths.any? { |rx| rx === file_name } if included
        next unless included

        Autobuild.message "#{e.absolute_name} changed" if show_events?
        callback
    end
end

#create_file_watcher(file) ⇒ Object



55
56
57
58
59
60
# File 'lib/autoproj/cli/watch.rb', line 55

def create_file_watcher(file)
    notifier.watch(file, :modify) do |e|
        Autobuild.message "#{e.absolute_name} modified" if show_events?
        callback
    end
end

#create_src_pkg_watchersObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/autoproj/cli/watch.rb', line 76

def create_src_pkg_watchers
    @source_packages_dirs.each do |pkg_srcdir|
        next unless File.exist? pkg_srcdir

        create_dir_watcher(pkg_srcdir, included_paths: ["manifest.xml", "package.xml"])

        manifest_file = File.join(pkg_srcdir, "manifest.xml")
        create_file_watcher(manifest_file) if File.exist? manifest_file
        ros_manifest_file = File.join(pkg_srcdir, "package.xml")
        if File.exist? ros_manifest_file
            create_file_watcher(ros_manifest_file)
        end
    end
end

#load_info_from_installation_manifestObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/autoproj/cli/watch.rb', line 35

def load_info_from_installation_manifest
    installation_manifest =
        begin
            Autoproj::InstallationManifest.from_workspace_root(ws.root_dir)
        rescue ConfigError
        end

    @source_packages_dirs = []
    @package_sets = []

    @source_packages_dirs = installation_manifest.each_package
                                                 .map(&:srcdir)
    @package_sets = installation_manifest.each_package_set
                                         .map(&:raw_local_dir)
end

#restartObject



127
128
129
130
131
132
# File 'lib/autoproj/cli/watch.rb', line 127

def restart
    cleanup
    args = []
    args << "--show-events" if show_events?
    exec($PROGRAM_NAME, "watch", *args)
end

#runObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/autoproj/cli/watch.rb', line 134

def run(**)
    @marker_io = Ops.watch_create_marker(ws.root_dir)
    begin
        update_workspace
    rescue Exception => e
        puts "ERROR: #{e.message}"
        load_info_from_installation_manifest
    end
    setup_notifier
    start_watchers

    puts "Watching workspace, press ^C to quit..."
    notifier.run

    puts "Workspace changed..."
    restart
rescue Interrupt
    puts "Exiting..."
ensure
    cleanup
end

#setup_notifierObject



115
116
117
118
119
120
# File 'lib/autoproj/cli/watch.rb', line 115

def setup_notifier
    assert_watchers_available

    require "rb-inotify"
    @notifier = INotify::Notifier.new
end

#show_events?Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/autoproj/cli/watch.rb', line 20

def show_events?
    @show_events
end

#start_watchersObject



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/autoproj/cli/watch.rb', line 91

def start_watchers
    create_file_watcher(ws.config.path)
    create_src_pkg_watchers
    create_dir_watcher(ws.config_dir,
                       excluded_paths: [/(^|#{File::SEPARATOR})\./],
                       inotify_flags: [:recursive])
    FileUtils.mkdir_p ws.remotes_dir
    create_dir_watcher(ws.remotes_dir,
                       excluded_paths: [/(^|#{File::SEPARATOR})\./],
                       inotify_flags: [:recursive])
end

#update_workspaceObject



24
25
26
27
28
29
30
31
32
33
# File 'lib/autoproj/cli/watch.rb', line 24

def update_workspace
    initialize_and_load

    source_packages, = finalize_setup([])
    @source_packages_dirs = source_packages.map do |pkg_name|
        ws.manifest.find_autobuild_package(pkg_name).srcdir
    end
    @pkg_sets_dirs = ws.manifest.each_package_set.map(&:raw_local_dir)
    export_env_sh(shell_helpers: ws.config.shell_helpers?)
end

#validate_options(unused, options = {}) ⇒ Object



14
15
16
17
18
# File 'lib/autoproj/cli/watch.rb', line 14

def validate_options(unused, options = {})
    _, options = super(unused, options)
    @show_events = options[:show_events]
    nil
end