summaryrefslogtreecommitdiff
path: root/third_party/waf/waflib/extras/unc.py
blob: e630c2a7d05483765d9d6bff394f712f0aaab742 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#! /usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2014 (ita)

"""
This module enables automatic handling of network paths of the form \\server\share for both input
and output files. While a typical script may require the following::

	import os
	def build(bld):

		node = bld.root.make_node('\\\\COMPUTER\\share\\test.txt')

		# mark the server/share levels as folders
		k = node.parent
		while k:
			k.cache_isdir = True
			k = k.parent

		# clear the file if removed
		if not os.path.isfile(node.abspath()):
			node.sig = None

		# create the folder structure
		if node.parent.height() > 2:
			node.parent.mkdir()

		# then the task generator
		def myfun(tsk):
			tsk.outputs[0].write("data")
		bld(rule=myfun, source='wscript', target=[nd])

this tool will make the process much easier, for example::

	def configure(conf):
		conf.load('unc') # do not import the module directly

	def build(bld):
		def myfun(tsk):
			tsk.outputs[0].write("data")
		bld(rule=myfun, update_outputs=True,
			source='wscript',
			target='\\\\COMPUTER\\share\\test.txt')
		bld(rule=myfun, update_outputs=True,
			source='\\\\COMPUTER\\share\\test.txt',
			target='\\\\COMPUTER\\share\\test2.txt')
"""

import os
from waflib import Node, Utils, Context

def find_resource(self, lst):
	if isinstance(lst, str):
		lst = [x for x in Node.split_path(lst) if x and x != '.']

	if lst[0].startswith('\\\\'):
		if len(lst) < 3:
			return None
		node = self.ctx.root.make_node(lst[0]).make_node(lst[1])
		node.cache_isdir = True
		node.parent.cache_isdir = True

		ret = node.search_node(lst[2:])
		if not ret:
			ret = node.find_node(lst[2:])
		if ret and os.path.isdir(ret.abspath()):
			return None
		return ret

	return self.find_resource_orig(lst)

def find_or_declare(self, lst):
	if isinstance(lst, str):
		lst = [x for x in Node.split_path(lst) if x and x != '.']

	if lst[0].startswith('\\\\'):
		if len(lst) < 3:
			return None
		node = self.ctx.root.make_node(lst[0]).make_node(lst[1])
		node.cache_isdir = True
		node.parent.cache_isdir = True
		ret = node.find_node(lst[2:])
		if not ret:
			ret = node.make_node(lst[2:])
		if not os.path.isfile(ret.abspath()):
			ret.sig = None
			ret.parent.mkdir()
		return ret

	return self.find_or_declare_orig(lst)

def abspath(self):
	"""For MAX_PATH limitations"""
	ret = self.abspath_orig()
	if not ret.startswith("\\"):
		return "\\\\?\\" + ret
	return ret

if Utils.is_win32:
	Node.Node.find_resource_orig = Node.Node.find_resource
	Node.Node.find_resource = find_resource

	Node.Node.find_or_declare_orig = Node.Node.find_or_declare
	Node.Node.find_or_declare = find_or_declare

	Node.Node.abspath_orig = Node.Node.abspath
	Node.Node.abspath = abspath

	for k in list(Context.cache_modules.keys()):
		Context.cache_modules["\\\\?\\" + k] = Context.cache_modules[k]